http://hi.baidu.com/billdu/item/703ad4e15d819db52f140b0b
POJ 2986
Point Zero=Point(0,0);
d_ common_area(Circle C,Point A,Point B)
{
// if(A==B) return 0;
if(A==C.c||B==C.c) return 0;
d_ OA=length(A-C.c),OB=length(B-C.c);
d_ d=distance_to_Line(Zero, A, B);
int sg=dcmp(cross(A,B));
if(sg==0) return 0;
d_ ang=angle(A,B);
if(dcmp(OA-C.r)<=0&&dcmp(OB-C.r)<=0)
{
return cross(A,B)/2;
}
else if(dcmp(OA-C.r)>=0&&dcmp(OB-C.r)>=0&&dcmp(d-C.r)>=0)
{
return sg*C.r*C.r*ang/2;
}
else if (dcmp(OA-C.r)>=0&&dcmp(OB-C.r)>=0&&dcmp(d-C.r)<0)
{
Point prj=get_Line_projection(Zero, A, B);
if(on_segment(prj, A, B))
{
vector<Point> p;
Line L=Line(A,B-A);
d_ t1,t2;
get_Line_Circle_intersection(L,C, t1, t2, p);
d_ s1=0;
s1=C.r*C.r*ang/2;
d_ s2=0;
s2=C.r*C.r*angle(p[0],p[1])/2;
s2-=fabs(cross(p[0],p[1])/2);
s1=s1-s2;
return sg*s1;
}
else
{
return sg*C.r*C.r*ang/2;
}
}
else
{ if(dcmp(OB-C.r)<0){Point temp=A;A=B;B=temp;}
Point prj=get_Line_projection(Zero, A, B),inter_point;
Vector v=B-A;
v=v/length(v);
d_ mov=sqrt(C.r*C.r-d*d);
if(on_segment(prj+v*mov, A, B))
{
inter_point=prj+v*mov;
}
else
{
inter_point=prj+Vector(-v.x,-v.y)*mov;
}
d_ s=fabs(cross(inter_point, A)/2);
s+=C.r*C.r*angle(inter_point,B)/2;
return s*sg;
}
}