hdu 5130(2014广州 圆与多边形相交模板)
2015-10-06 17:21
387 查看
题意:一个很多个点p构成的多边形,pb <= pa * k时p所占区域与多边形相交面积
设p(x,y), (x - xb)^2+(y - yb)^2 / (x - xa)^2+(y - ya)^2 = k^2
所以可以化成圆的一般式x^2 + y^2 + dx + ey + f = 0;
推公式:
圆心:(-d/2,-e/2) 半径:(sqrt(d*d + e*e - 4*f)) / 2
得出圆后,套模板求圆与多边形的相交
设p(x,y), (x - xb)^2+(y - yb)^2 / (x - xa)^2+(y - ya)^2 = k^2
所以可以化成圆的一般式x^2 + y^2 + dx + ey + f = 0;
推公式:
圆心:(-d/2,-e/2) 半径:(sqrt(d*d + e*e - 4*f)) / 2
得出圆后,套模板求圆与多边形的相交
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; typedef long long ll; #define eps 1e-8 #define N 100017 struct Point { double x,y; Point(double x=0, double y=0):x(x),y(y) {} void get(int x1,int y1) { x = x1; y = y1; } }; typedef Point Vector; struct Circle { Point c; double r; Circle() {} Circle(Point c,double r):c(c),r(r) {} Point point(double a) { return Point(c.x + cos(a)*r, c.y + sin(a)*r); } void input() { scanf("%lf%lf%lf",&c.x,&c.y,&r); } }; int dcmp(double x) { if(x < -eps) return -1; if(x > eps) return 1; return 0; } template <class T> T sqr(T x) { return x * x; } Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); } Vector operator - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); } Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); } Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); } bool operator < (const Point& a, const Point& b) { return a.x < b.x || (a.x == b.x && a.y < b.y); } bool operator >= (const Point& a, const Point& b) { return a.x >= b.x && a.y >= b.y; } bool operator <= (const Point& a, const Point& b) { return a.x <= b.x && a.y <= b.y; } bool operator == (const Point& a, const Point& b) { return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0; } double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; } double Length(Vector A) { return sqrt(Dot(A, A)); } double Angle(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); } double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; } Vector VectorUnit(Vector x) { return x / Length(x); } Vector Normal(Vector x) { return Point(-x.y, x.x) / Length(x); } double angle(Vector v) { return atan2(v.y, v.x); } bool OnSegment(Point P, Point A, Point B) { return dcmp(Cross(A-P,B-P)) == 0 && dcmp(Dot(A-P,B-P)) < 0; } double DistanceToSeg(Point P, Point A, Point B) { if(A == B) return Length(P-A); Vector v1 = B-A, v2 = P-A, v3 = P-B; if(dcmp(Dot(v1, v2)) < 0) return Length(v2); if(dcmp(Dot(v1, v3)) > 0) return Length(v3); return fabs(Cross(v1, v2)) / Length(v1); } double DistanceToLine(Point P, Point A, Point B) { Vector v1 = B-A, v2 = P-A; return fabs(Cross(v1,v2)) / Length(v1); } Point DisP(Point A, Point B) { return Length(B-A); } bool SegmentIntersection(Point A,Point B,Point C,Point D) { return max(A.x,B.x) >= min(C.x,D.x) && max(C.x,D.x) >= min(A.x,B.x) && max(A.y,B.y) >= min(C.y,D.y) && max(C.y,D.y) >= min(A.y,B.y) && dcmp(Cross(C-A,B-A)*Cross(D-A,B-A)) <= 0 && dcmp(Cross(A-C,D-C)*Cross(B-C,D-C)) <= 0; } Point Zero = Point(0,0); double TriAngleCircleInsection(Circle C, Point A, Point B) { Vector OA = A-C.c, OB = B-C.c; Vector BA = A-B, BC = C.c-B; Vector AB = B-A, AC = C.c-A; double DOA = Length(OA), DOB = Length(OB),DAB = Length(AB), r = C.r; if(dcmp(Cross(OA,OB)) == 0) return 0; if(dcmp(DOA-C.r) < 0 && dcmp(DOB-C.r) < 0) return Cross(OA,OB)*0.5; else if(DOB < r && DOA >= r) { double x = (Dot(BA,BC) + sqrt(r*r*DAB*DAB-Cross(BA,BC)*Cross(BA,BC)))/DAB; double TS = Cross(OA,OB)*0.5; return asin(TS*(1-x/DAB)*2/r/DOA)*r*r*0.5+TS*x/DAB; } else if(DOB >= r && DOA < r) { double y = (Dot(AB,AC)+sqrt(r*r*DAB*DAB-Cross(AB,AC)*Cross(AB,AC)))/DAB; double TS = Cross(OA,OB)*0.5; return asin(TS*(1-y/DAB)*2/r/DOB)*r*r*0.5+TS*y/DAB; } else if(fabs(Cross(OA,OB)) >= r*DAB || Dot(AB,AC) <= 0 || Dot(BA,BC) <= 0) { if(Dot(OA,OB) < 0) { if(Cross(OA,OB) < 0) return (-acos(-1.0)-asin(Cross(OA,OB)/DOA/DOB))*r*r*0.5; else return ( acos(-1.0)-asin(Cross(OA,OB)/DOA/DOB))*r*r*0.5; } else return asin(Cross(OA,OB)/DOA/DOB)*r*r*0.5; } else { double x = (Dot(BA,BC)+sqrt(r*r*DAB*DAB-Cross(BA,BC)*Cross(BA,BC)))/DAB; double y = (Dot(AB,AC)+sqrt(r*r*DAB*DAB-Cross(AB,AC)*Cross(AB,AC)))/DAB; double TS = Cross(OA,OB)*0.5; return (asin(TS*(1-x/DAB)*2/r/DOA)+asin(TS*(1-y/DAB)*2/r/DOB))*r*r*0.5 + TS*((x+y)/DAB-1); } } Point p[2000]; int main() { int n; double k; int cas = 1; while(scanf("%d%lf",&n,&k) != EOF) { for(int i = 1; i <= n; i++) { double x,y; scanf("%lf%lf",&x,&y); p[i].get(x,y); } p[n+1] = p[1]; double x1,x2,y1,y2; scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); double d = (2.0*k*k*x1-2.0*x2)/(1.0-k*k); double e = (2.0*k*k*y1-2.0*y2)/(1.0-k*k); double f = (x2*x2+y2*y2-k*k*(x1*x1+y1*y1))/(1.0-k*k); Point O = Point(-d*0.5,-e*0.5); double R= sqrt(d*d+e*e-4.0*f)*0.5; Circle C = Circle(O,R); double ans = 0.0; for(int i=1; i<=n; i++) ans += TriAngleCircleInsection(C, p[i], p[i+1]); printf("Case %d: %.10f\n",cas++,fabs(ans)); } return 0; }
相关文章推荐
- 微信企业号开发CreateTime的C#解析
- 缺陷报告
- 系统主要配置文件
- HDU5416(树DP)
- C++初始化变量
- jQuery源码分析之$.grep()函数四问
- opencv环境的搭建,并打开一个本地PC摄像头。
- Socket所有的网络通信模型详解共享
- div、p等标签不自动折行
- Log Malicious Discovery tool (Log-MD)
- RenderScript的基础使用
- 黑马程序员----Objective-C学习笔记之@property参数
- 让 Putty 保存密码,自动登陆的四种方法
- matlab边缘检测算法汇总2
- 第三周Linux编程实例练习
- [wordpress使用]002_主题
- public static void main(String[] args){}函数
- 一元多项式的乘法与加法运算【Java实现--通过单项链表实现队列】
- eclipse下建立 android 项目,相关文件夹介绍
- Mac下如何安装调试apk