#include
#include
#include
#include
#include
#include
#include
#include
#include
#define CL(arr, val) memset(arr, val, sizeof(arr))
#define REP(i, n) for((i) = 0; (i) < (n); ++(i))
#define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i))
#define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i))
#define L(x) (x) << 1
#define R(x) (x) << 1 | 1
#define MID(l, r) (l + r) >> 1
#define Min(x, y) x < y ? x : y
#define Max(x, y) x < y ? y : x
#define E(x) (1 << (x))
const double eps = 1e-8;
typedef long long LL;
using namespace std;
const int maxn = 110;
struct Point {
double x;
double y;
Point(double a = 0, double b = 0): x(a), y(b) {}
void input() {
scanf("%lf%lf", &x, &y);
}
};
Point point[maxn], p[maxn], q[maxn]; //读入的多边形的顶点(顺时针)、p为存放最终切割得到的多边形顶点的数组、暂存核的顶点
int cCnt, n; //此时cCnt为最终切割得到的多边形的顶点数、暂存顶点个数
inline int dbcmp(double x) { //精度问题
if(x > eps) return 1;
else if(x < -eps) return -1;
return 0;
}
inline void getline(Point x, Point y, double& a, double& b, double& c) { //点X,Y确定一条直线
a = y.y - x.y;
b = x.x - y.x;
c = y.x*x.y - x.x*y.y;
}
inline Point intersect(Point x, Point y, double a, double b, double c) { 求x、y形成的直线与已知直线a、b、c、的交点
double u = fabs(a*x.x + b*x.y + c);
double v = fabs(a*y.x + b*y.y + c);
return Point((x.x*v + y.x*u)/(u + v), (x.y*v + y.y*u)/(u + v));
}
inline void cut(double a, double b, double c) { //如上图所示,切割
int cur = 0, i;
for(i = 1; i <= cCnt; ++i) {
if(dbcmp(a*p[i].x + b*p[i].y + c) >= 0) q[++cur] = p[i]; // c由于精度问题,可能会偏小,所以有些点本应在右侧而没在
else {
if(dbcmp(a*p[i-1].x + b*p[i-1].y + c) > 0) //如果p[i-1]在直线的右侧的话,
//则将p[i],p[i-1]形成的直线与已知直线的交点作为核的一个顶点(这样的话,由于精度的问题,核的面积可能会有所减少)
q[++cur] = intersect(p[i], p[i-1], a, b, c);
if(dbcmp(a*p[i+1].x + b*p[i+1].y + c) > 0)
q[++cur] = intersect(p[i], p[i+1], a, b, c);
}
}
for(i = 1; i <= cur; ++i) p[i] = q[i];
p[cur+1] = q[1]; p[0] = p[cur];
cCnt = cur;
}
void solve() { //注意:默认点是顺时针,如果题目不是顺时针,规整化方向
int i;
for(i = 1; i <= n; ++i) {
double a, b, c;
getline(point[i], point[i+1], a, b, c);
cut(a, b, c);
}
if(cCnt == 0) puts("NO");
else puts("YES");
}
void init() {
int i;
FOR(i, 1, n) point[i].input();
point[n+1] = point[1];
//初始化p[], cCnt
FOR(i, 1, n) p[i] = point[i];
p[n+1] = p[1]; p[0] = p[n];
cCnt = n;
}
int main() {
//freopen("data.in", "r", stdin);
int t;
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
init();
solve();
}
return 0;
}
*************************************************************************************
HDU1474
#include
#include
#include
using namespace std;
struct Point
{
double x, y;
} point[105]; //原始节点
Point p[105];//保存新切割出的多边形
Point q[105];//临时保存新切割的多边形
int n, m;
double a, b, c;//直线 ax + by + c == 0
void lineFromSegment(Point p1, Point p2)
{
//线段所在直线,返回直线方程的三个系数
a = p2.y - p1.y;
b = p1.x - p2.x;
c = p2.x * p1.y - p1.x * p2.y;
}
Point intersect(Point x, Point y)
{
double u = fabs(a * x.x + b * x.y + c);
double v = fabs(a * y.x + b * y.y + c);
Point ans;
ans.x = (x.x * v + y.x * u) / (u + v);
ans.y = (x.y * v + y.y * u) / (u + v);
return ans;
}//获取直线ax+by+c==0 和点x和y所连直线的交点
int cut()
{
int np = 0, i;
for( i = 0 ; i < m ; i++)
{
if( p[i].x *a + p[i].y *b + c >= 0) //题目输入是顺时针方向故大于号
{
q[np++] = p[i];
}//某点在该直线割后的多边形内,则保存该点
else
{
if( p[(i + m - 1) % m].x * a + p[(i + m - 1) % m].y * b + c > 0 )//
{
q[np++] = intersect(p[i], p[(i + m - 1) % m]);
}
if( p[(i + 1) % m].x * a + p[(i + 1) % m].y * b + c > 0 )
{
q[np++] = intersect(p[i], p[(i + 1) % m]);
}
}//如果该点在外,看是该点的相邻两边是否存在与割线的交点,有交点保存割边上的交点
}
for( i = 0 ; i < np ; i++)
p[i] = q[i];//更新切割后的多边形顶点
m = np;
return 0;
}
int find_nucleus()
{
int i, j;
for( i = 0; i < n; i++)
p[i] = point[i];
m = n;
for( i = 0 ; i < n ; i++)
{
lineFromSegment(point[i], point[(i + 1) % n]);
cut();
}
return 0;
}
int main()
{
int i, k;
k = 1;
while(scanf("%d", &n), n)
{
for( i = 0 ; i < n ; i++)
scanf("%lf%lf", &point[i].x, &point[i].y);
find_nucleus();
printf("Floor #%d\n", k++);
printf("%s\n\n", m == 0 ? "Surveillance is impossible." : "Surveillance is possible.");
}
return 0;
}
多边形的核
最新推荐文章于 2021-04-28 12:57:02 发布