首页 > 代码库 > hdu 2892 多边形与园面积相交
hdu 2892 多边形与园面积相交
area
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 623 Accepted Submission(s): 233
Problem Description
小白最近被空军特招为飞行员,参与一项实战演习。演习的内容是轰炸某个岛屿。。。
作为一名优秀的飞行员,任务是必须要完成的,当然,凭借小白出色的操作,顺利地将炸弹投到了岛上某个位置,可是长官更关心的是,小白投掷的炸弹到底摧毁了岛上多大的区域?
岛是一个不规则的多边形,而炸弹的爆炸半径为R。
小白只知道自己在(x,y,h)的空间坐标处以(x1,y1,0)的速度水平飞行时投下的炸弹,请你计算出小白所摧毁的岛屿的面积有多大. 重力加速度G = 10.
作为一名优秀的飞行员,任务是必须要完成的,当然,凭借小白出色的操作,顺利地将炸弹投到了岛上某个位置,可是长官更关心的是,小白投掷的炸弹到底摧毁了岛上多大的区域?
岛是一个不规则的多边形,而炸弹的爆炸半径为R。
小白只知道自己在(x,y,h)的空间坐标处以(x1,y1,0)的速度水平飞行时投下的炸弹,请你计算出小白所摧毁的岛屿的面积有多大. 重力加速度G = 10.
Input
首先输入三个数代表小白投弹的坐标(x,y,h);
然后输入两个数代表飞机当前的速度(x1, y1);
接着输入炸弹的爆炸半径R;
再输入一个数n,代表岛屿由n个点组成;
最后输入n行,每行输入一个(x‘,y‘)坐标,代表岛屿的顶点(按顺势针或者逆时针给出)。(3<= n < 100000)
然后输入两个数代表飞机当前的速度(x1, y1);
接着输入炸弹的爆炸半径R;
再输入一个数n,代表岛屿由n个点组成;
最后输入n行,每行输入一个(x‘,y‘)坐标,代表岛屿的顶点(按顺势针或者逆时针给出)。(3<= n < 100000)
Output
输出一个两位小数,表示实际轰炸到的岛屿的面积。
Sample Input
0 0 2000 100 0 100 4 1900 100 2000 100 2000 -100 1900 -100
Sample Output
15707.96
多边形与园面积相交主要思想就是把多边形拆成一个一个三角形,计算三角形与园面积相交的结果,然后累加。
三角形与圆面积的计算分了四种情况,具体看这里:http://www.cnblogs.com/lxglbk/archive/2012/08/12/2634192.html
具体代码:
/* *********************************************** Author :_rabbit Created Time :2014/5/7 10:36:31 File Name :F.cpp ************************************************ */ #pragma comment(linker, "/STACK:102400000,102400000") #include <stdio.h> #include <iostream> #include <algorithm> #include <sstream> #include <stdlib.h> #include <string.h> #include <limits.h> #include <string> #include <time.h> #include <math.h> #include <queue> #include <stack> #include <set> #include <map> using namespace std; #define INF 0x3f3f3f3f #define eps 1e-8 #define pi acos(-1.0) typedef long long ll; int dcmp(double x){ if(fabs(x)<eps)return 0; return x>0?1:-1; } struct Point{ double x,y; Point(double _x=0,double _y=0){ x=_x;y=_y; } }; Point operator + (Point a,Point b){ return Point(a.x+b.x,a.y+b.y); } Point operator - (Point a,Point &b){ return Point(a.x-b.x,a.y-b.y); } Point operator * (Point a,double p){ return Point(a.x*p,a.y*p); } Point operator / (Point a,double p){ return Point(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 dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; } double Dot(Point a,Point b){ return a.x*b.x+a.y*b.y; } double Length(Point a){ return sqrt(Dot(a,a)); } double Angle(Point a,Point b){ return acos(Dot(a,b)/Length(a)/Length(b)); } double angle(Point a){ return atan2(a.y,a.x); } double Cross(Point a,Point b){ return a.x*b.y-a.y*b.x; } Point vecunit(Point a){ return a/Length(a); } Point Normal(Point a){ return Point(-a.y,a.x)/Length(a); } Point Rotate(Point a,double rad){ return Point(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad)); } bool OnSegment(Point p,Point a1,Point a2){ return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dot(a1-p,a2-p))<=0; } Point GetLineIntersection(Point p,Point v,Point q,Point w){ Point u=p-q; double t=Cross(w,u)/Cross(v,w); return p+v*t; } struct Line{ Point p,v; double ang; Line(){} Line(Point _p,Point _v){ p=_p;v=_v;ang=atan2(v.y,v.x); } bool operator < (const Line &L) const { return ang<L.ang; } Point point(double a){ return p+(v*a); } }; Point GetLineIntersection(Line a,Line b){ return GetLineIntersection(a.p,a.v,b.p,b.v); } 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); } }; bool InCircle(Point x,Circle c){ return dcmp(c.r-Length(c.c-x))>=0; } bool OnCircle(Point x,Circle c){ return dcmp(c.r-Length(c.c-x))==0; } int getSegCircleIntersection(Line L,Circle C,Point *sol){ Point nor=Normal(L.v); Line p1=Line(C.c,nor); Point ip=GetLineIntersection(p1,L); double dis=Length(ip-C.c); if(dcmp(dis-C.r)>0)return 0; Point dxy=vecunit(L.v)*sqrt(C.r*C.r-dis*dis); int ret=0; sol[ret]=ip+dxy; if(OnSegment(sol[ret],L.p,L.point(1)))ret++; sol[ret]=ip-dxy; if(OnSegment(sol[ret],L.p,L.point(1)))ret++; return ret; } double SegCircleArea(Circle C,Point a,Point b){ double a1=angle(a-C.c); double a2=angle(b-C.c); double da=fabs(a1-a2); if(da>pi)da=pi*2-da; return dcmp(Cross(b-C.c,a-C.c))*da*C.r*C.r/2.0; } double PolyCircleArea(Circle C,Point *p,int n){ double ret=0; Point sol[2]; p[n]=p[0]; for(int i=0;i<n;i++){ double t1,t2; int cnt=getSegCircleIntersection(Line(p[i],p[i+1]-p[i]),C,sol); if(cnt==0){ if(!InCircle(p[i],C)||!InCircle(p[i+1],C))ret+=SegCircleArea(C,p[i],p[i+1]); else ret+=Cross(p[i+1]-C.c,p[i]-C.c)/2; } if(cnt==1){ if(InCircle(p[i],C)&&!InCircle(p[i+1],C))ret+=Cross(sol[0]-C.c,p[i]-C.c)/2,ret+=SegCircleArea(C,sol[0],p[i+1]); else ret+=SegCircleArea(C,p[i],sol[0]),ret+=Cross(p[i+1]-C.c,sol[0]-C.c)/2; } if(cnt==2){ if((p[i]<p[i+1])^(sol[0]<sol[1]))swap(sol[0],sol[1]); ret+=SegCircleArea(C,p[i],sol[0]); ret+=Cross(sol[1]-C.c,sol[0]-C.c)/2; ret+=SegCircleArea(C,sol[1],p[i+1]); } } return fabs(ret); } Point p[200000]; int main() { //freopen("data.in","r",stdin); //freopen("data.out","w",stdout); Point a,b; double h,R; int n; while(~scanf("%lf%lf%lf",&a.x,&a.y,&h)){ scanf("%lf%lf%lf%d",&b.x,&b.y,&R,&n); for(int i=0;i<n;i++)scanf("%lf%lf",&p[i].x,&p[i].y); double t=sqrt(h/5); Point g=Point(a.x+b.x*t,a.y+b.y*t); Circle h=Circle(g,R); double ans=PolyCircleArea(h,p,n); printf("%.2lf\n",ans); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。