博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1279 Art Gallery 半平面交求多边形核
阅读量:5323 次
发布时间:2019-06-14

本文共 2864 字,大约阅读时间需要 9 分钟。

第一道半平面交,只会写N^2。

将每条边化作一个不等式,ax+by+c>0,所以要固定顺序,方便求解。

半平面交其实就是对一系列的不等式组进行求解可行解。

如果某点在直线右侧,说明那个点在区域内,否则出现在左边,就可能会有交点,将交点求出加入。

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler#include 
#include
#include
#include
#include
#include
#include
#include
#define ll long long#define Max(a,b) (((a) > (b)) ? (a) : (b))#define Min(a,b) (((a) < (b)) ? (a) : (b))#define Abs(x) (((x) > 0) ? (x) : (-(x)))using namespace std;const int MAXN = 1555;const double eps = 1e-8;struct POINT{ double x; double y; POINT() : x(0), y(0) {}; POINT(double _x_, double _y_) : x(_x_), y(_y_) {};};struct LINE{ POINT a; POINT b; LINE() {}; LINE(POINT _a_, POINT _b_) : a(_a_), b(_b_) {};};POINT point[MAXN];//记录最开始的多边形POINT temp[MAXN]; //临时保存新切割的多边形POINT ans[MAXN]; //保存新切割出的多边形LINE lline;int n,m;//n的原先的点数,m是新切割出的多边形的点数void Coefficient(const LINE & L, double & A, double & B, double & C){ A = L.b.y - L.a.y; B = L.a.x - L.b.x; C = L.b.x * L.a.y - L.a.x * L.b.y;}double Cross(const POINT & a, const POINT & b, const POINT &o){ return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);}POINT Intersection(const LINE & A, const LINE & B){ double A1, B1, C1; double A2, B2, C2; Coefficient(A, A1, B1, C1); Coefficient(B, A2, B2, C2); POINT temp_point(0, 0); temp_point.x = -(B2 * C1 - B1 * C2) / (A1 * B2 - A2 * B1); temp_point.y = (A2 * C1 - A1 * C2) / (A1 * B2 - A2 * B1); return temp_point;}//求面积,正为顺时针,和叉积写法有关double PointArea(POINT p[],int n){ double area = 0; for(int i = 2; i < n; ++i) area += Cross(p[1], p[i], p[i+1]); return -area / 2.0;}void Cut(){ //用直线ax+by+c==0切割多边形 int cut_m = 0, i; double a, b, c; Coefficient(lline, a, b, c); for(i = 1; i <= m; ++i){ if(a * ans[i].x + b*ans[i].y + c >= 0) //题目是顺时钟给出点的,所以一个点在直线右边的话,那么带入值就会大于等于0 temp[++cut_m] = ans[i]; //说明这个点还在切割后的多边形内,将其保留 else{ if(a * ans[i - 1].x + b * ans[i - 1].y + c > 0){ //该点不在多边形内,但是它和它相邻的点构成直线与 LINE line1(ans[i - 1], ans[i]); //ax+by+c==0所构成的交点可能在新切割出的多边形内, temp[++cut_m] = Intersection(lline, line1); //所以保留交点 } if(a * ans[i + 1].x + b * ans[i + 1].y + c > 0){ LINE line1(ans[i + 1], ans[i]); temp[++cut_m] = Intersection(lline, line1); //所以保留交点 } } } for(i = 1; i <= cut_m; ++i) ans[i] = temp[i]; ans[cut_m + 1] = temp[1]; ans[0] = temp[cut_m]; m = cut_m;}void solve(){ int i; point[0] = point[n]; point[n+1] = point[1]; for(i = 0; i <= n + 1; ++i){ ans[i] = point[i]; } m = n; for(i = 1;i <= n; ++i){ lline.a = point[i]; lline.b = point[i + 1]; //根据point[i]和point[i+1]确定直线ax+by+c==0 Cut(); //用直线ax+by+c==0切割多边形 } printf("%.2f\n",Abs(PointArea(ans,m)));}int main(){ int caseNum,i; scanf("%d",&caseNum); while(caseNum--){ scanf("%d",&n); for(i = 1; i <= n; ++i){ scanf("%lf%lf",&point[i].x,&point[i].y); } solve(); } return 0;}

 

转载于:https://www.cnblogs.com/wushuaiyi/p/3919779.html

你可能感兴趣的文章
Java的位运算符具体解释实例——与(&amp;)、非(~)、或(|)、异或(^)
查看>>
java 注解 学习
查看>>
[leetcode]403. Frog Jump青蛙过河
查看>>
匿名内部类--细节
查看>>
但我现在要将其中的“pageEncoding="ISO-8859-1"”默认为“pageEncoding="GBK"”,请问怎么修改MyEclipse?...
查看>>
英语音节知识
查看>>
IEEE 802.15.4协议学习之MAC层
查看>>
AngularJS学习篇(十三)
查看>>
JavaScript Function.apply() 函数详解
查看>>
Tableau 学习资料
查看>>
中断和异常
查看>>
lucene 全文检索工具的介绍
查看>>
C# MD5-16位加密实例,32位加密实例
查看>>
无线点餐系统初步构思
查看>>
AJAX
查看>>
前端之CSS
查看>>
List注意点【修改】
查看>>
sqoop导入导出对mysql再带数据库test能跑通用户自己建立的数据库则不行
查看>>
拓扑排序的原理及其实现
查看>>
对StageWebView捕获位图时空白
查看>>