【问题描述】
作为水污染管理部门的一名雇员,你需要监控那些被有意无倒入河流、湖 作为水污染管理部门的一名雇员,你需要监控那些被有意无倒入河流、湖 作为水污染管理部门的一名雇员,你需要监控那些被有意无倒入河流、湖 泊和海洋的污染物。你其中一项工作就是估计对不 泊和海洋的污染物。你其中一项工作就是估计对不 同的水生态系统(珊 同的水生态系统(珊 瑚礁、产卵地等)造成的影响。
你计算所使用的模型已经在图 1中被说明。海岸线(图 中被说明。海岸线(图 中被说明。海岸线(图 1中的水平直线)为 中的水平直线)为 x轴,污染源位于原点 轴,污染源位于原点 (0, 0)(0, 0) 。污染的蔓延呈半圆形,多边代表了被波及生态 。污染的蔓延呈半圆形,多边代表了被波及生态 。污染的蔓延呈半圆形,多边代表了被波及生态 系统。
你需要计算出生态被污染的面积,也就是图中深蓝色部分
【输入格式】
第一行为两个整数 ��,��,��表示了多边形的顶点个数, ��表示了污染区域的半径;
接下来 ��行,每包含两个整数 行,每包含两个整数 ����,����,表示每个顶点的坐标以逆时针顺序 ,表示每个顶点的坐标以逆时针顺序 ,表示每个顶点的坐标以逆时针顺序 给出; 数据保证多边形不自交或触及身,没有顶点会位于圆弧上。
【输出格式】
输出多边形被圆心位于原点、半径为 ��的半圆覆盖面积。 答案的绝对误差不得超过 10−3。
【样例输入】
6 10
-8 2
8 2
8 14
0 14
0 6
-8 14
【样例输出】
101.576437872
【数据规模与约定】
对于100%的数据 ,1≤n≤100,1≤r≤10^3,−1500≤xi≤1500,0≤yi≤1500。
三角形剖分,计算多边形面积的变式,最后把叉积的和加起来之后要去绝对值! 因为方向是随便定的!!
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
const int INF=0x3f3f3f3f;
struct Point
{
double x,y;
Point(double x=0,double y=0):x(x),y(y){ }
};
typedef Point Vector;
Vector operator + (Vector A,Vector B){ return Vector(A.x+B.x,A.y+B.y);}
Vector operator - (Point A,Point 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);}
const double eps=1e-10;
int dcmp(double x)
{
if(fabs(x)return 0;
else return x>0?1:-1;
}
bool operator == (const Vector &v1,const Vector &v2)
{
return dcmp(v1.x-v2.x)==0 && dcmp(v1.y-v2.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 Cross(Vector A,Vector B){ return A.x*B.y-A.y*B.x; }
double Angle(Vector A,Vector B){ return acos(Dot(A,B)/Length(A)/Length(B));}
int R,n;
Point O=Point(0,0);
Vector v0=Vector(0,0);
bool on_line(Point P1,Point P2,Point P3)
{
return Cross(P1-P2,P2-P3)==v0?true:false;
}
double get_sector_area(Vector v1,Vector v2,double R)
{
double alpha=Angle(v1,v2);
return R*R*alpha/2;
}
Point get_circle_intersection(Point A,Point B)//ANS.x is between A and B
{
if(A.x==B.x) return Point(A.x,sqrt(R*R-A.x*A.x));//important ! special judge!
double k=(A.y-B.y)/(A.x-B.x);
double b=A.y-k*A.x;
double a1=k*k+1.0,a2=2.0*k*b,a3=b*b-R*R;
double delta=a2*a2-4.0*a1*a3;
delta=sqrt(delta);
double x1=(-a2+delta)/2/a1;
double x2=(-a2-delta)/2/a1;
if(dcmp(A.x-x1)*dcmp(B.x-x1)<0) return Point(x1,k*x1+b);
if(dcmp(A.x-x2)*dcmp(B.x-x2)<0) return Point(x2,k*x2+b);
if(dcmp(A.x-x1)*dcmp(B.x-x1)==0) return Point(x1,k*x1+b);// = needed! the case of segistration!!
else return Point(x2,k*x2+b);
}
void get_line_intersection(Point A,Point B,Point &C,Point &D)
{
double k=(A.y-B.y)/(A.x-B.x);
double b=A.y-k*A.x;
double a1=k*k+1.0,a2=2.0*k*b,a3=b*b-R*R;
double delta=a2*a2-4.0*a1*a3;
delta=sqrt(delta);
double x1=(-a2+delta)/2/a1;
double x2=(-a2-delta)/2/a1;
C=Point(x1,k*x1+b);
D=Point(x2,k*x2+b);
if((A.x<=B.x&&C.x>D.x)||(A.x>B.x&&C.x<=D.x)) swap(C,D);
}
double get_in_tri(Point A,Point B)//A is in, B is out
{
Vector v1=A-O,v2=B-O;
Point C=get_circle_intersection(A,B);
Point D=get_circle_intersection(B,O);
Vector v3=C-O;
Vector v4=D-O;
double s1=Cross(v1,v3)/2;
double sign=Cross(v3,v4);
double s2=get_sector_area(v3,v4,R);
if(sign*s2<0) s2*=-1;//important!! each time need to make sure the same operator!!
return s1+s2;
}
double get_out_tri(Point A,Point B)
{
Vector v1=A-O,v2=B-O;
Point C=get_circle_intersection(A,O);
Point D=get_circle_intersection(A,B);
Vector v3=C-O;
Vector v4=D-O;
double s1=Cross(v4,v2)/2;
double sign=Cross(v3,v4);
double s2=get_sector_area(v3,v4,R);
if(sign*s2<0) s2*=-1;//important!! each time need to make sure the same operator!!
return s1+s2;
}
double get_in_out_tri(Point A,Point B)
{
Vector v1=A-O,v2=B-O;
double len1=Length(v1),len2=Length(v2);
if(len1<=len2) return get_in_tri(A,B);
else return get_out_tri(A,B);
}
double get_area(Point A,Point B)
{
if(on_line(A,B,O)) return 0;
Vector v1=A-O,v2=B-O;
double len11=Length(v1),len22=Length(v2);
int len1=dcmp(len11-R);
int len2=dcmp(len22-R);
if(len1<=0&&len2<=0)
{
double ret=Cross(v1,v2)/2;
return ret;
}
if((len1<=0&&len2>0)||(len1>0&&len2<=0)) return get_in_out_tri(A,B);
if(len1>0&&len2>0)
{
Vector vab=B-A,vao=v1*-1;
double d=fabs(Cross(vao,vab)/Length(vab));
if(dcmp(d-R)>=0)
{
double tmp=get_sector_area(v1,v2,R);
double cross=Cross(v1,v2);
if(cross*tmp<0) tmp*=-1.0;
return tmp;
}
else
{
Point C,D;
get_line_intersection(A,B,C,D);
if(((C.xB.x&&C.x>A.x)))
{
double cross=Cross(v1,v2);
double tmp=get_sector_area(v1,v2,R);
if(tmp*cross<0) tmp*=-1.0;
return tmp;
}
double sum=get_in_out_tri(A,C)+get_in_out_tri(D,B);
sum+=Cross(C-O,D-O)/2;
return sum;
}
}
cout<<"Error!"<// default
return INT_MIN/2;
}
int main()
{
freopen("kao.in","r",stdin);
freopen("kao.out","w",stdout);
cin>>n>>R;
double area=0.0;
Point org;
scanf("%lf%lf",&org.x,&org.y);
Point last=org;
for(int i=1;iscanf("%lf%lf",&now.x,&now.y);
area+=get_area(last,now);
last=now;
}
area+=get_area(last,org);
if(dcmp(area)==0) area=0.0;
printf("%.7lf\n",area);
return 0;
}