这些代码未经过题目测试,存在安全隐患。。。。
struct circle
{
Point p;
double r;
circle(){}
circle(Point pp,double rr)
{
p=pp,r=rr;
}
circle(double xx,double yy,double rr)
{
p=Point(xx,yy);
r=rr;
}
//三角形外接圆
//利用两条边的中垂线得到圆心
circle(Point a,Point b,Point c)
{
Line u=Line((a+b)/2,((a+b)/2)+((b-a).turn_left()));
Line v=Line((b+c)/2,((b+c)/2)+((c-b).turn_left()));
p=u.cross_point(v);
r=p.dis(a);
}
//三角形内切圆,bool t只是为了重载
circle(Point a,Point b,Point c,bool t)
{
Line u,v;
double m=atan2(b.y-a.y,b.x-a.x),n=atan2(c.y-a.y,c.x-a.x);
u.s=a;
u.e=u.s+Point(cos((n+m)/2),sin((n+m)/2));
m=atan2(a.y-b.y,a.x-b.x),n=atan2(c.y-b.y,c.x-b.x);
v.s=b;
v.e=v.s+Point(cos((n+m)/2),sin((n+m)/2));
p=u.cross_point(v);
r=Line(a,b).dis_point_to_seg(p);
}
void input(void)
{
p.input();
scanf("%lf",&r);
}
void output(void)
{
printf("%.2f %.2f %.2f\n",p.x,p.y,r);
}
bool operator == (const circle &v)
{
return (p==v.p)&&sgn(r-v.r)==0;
}
bool operator <(const circle &v) const
{
return ((p<v.p)||((p==v.p)&&sgn(r-v.r)<0));
}
double area(void)
{
return pi*r*r;
}
double cir(void)
{
return 2*pi*r;
}
//点和圆的关系,
//0 圆外
//1 圆上
//2 圆内
int rel_of_point(const Point &b)
{
double dist=b.dis(p);
if(sgn(dist-r)<0) return 2;
if(sgn(dist-r)==0) return 1;
return 0;
}
//线段和圆的关系
//比较的是圆心到线段的距离和半径的关
int rel_of_seg(Line &v)
{
double dist=v.dis_point_to_seg(p);
if(sgn(dist-r)<0) return 2;
if(sgn(dist-r)==0) return 1;
return 0;
}
//直线和圆的关系
//比较的是圆心到直线的距离和半径的关系
int rel_of_line(Line &v)
{
double dist=v.dis_point_to_line(p);
if(sgn(dist-r)<0) return 2;
if(sgn(dist-r)==0) return 1;
return 0;
}
//两圆的关系
//5 相离
//4 外切
//3 相交
//2 内切
//1 内含
int rel_of_circle(const circle &v)
{
double d=p.dis(v.p);
if(sgn(d-r-v.r)>0) return 5;
if(sgn(d-r-v.r)==0) return 4;
double l=abs(r-v.r);
if(sgn(d-r-v.r)<0&&sgn(d-l)>0) return 3;
if(sgn(d-l)==0) return 2;
if(sgn(d-l)<0) return 1;
}
//求两个圆的交点,
//0 表示没有交点,
//1 是一个交点,
//2 是两个交点
int point_two_circle(const circle &v,Point &p1,Point &p2)
{
int rel=rel_of_circle(v);
if(rel==1||rel==5) return 0;
double d=p.dis(v.p);
double l=(d*d+r*r-v.r*v.r)/(2*d);
double h=sqrt(r*r-l*l);
Point tmp=p+(v.p-p).turn_to_r(l);
p1=tmp+((v.p-p).turn_left().turn_to_r(h));
p2=tmp+((v.p-p).turn_right().turn_to_r(h));
if(rel==2||rel==4) return 1;
return 2;
}
//求直线和圆的交点,返回交点个数
int point_line_circle(Line &v,Point &p1,Point &p2)
{
if(!(*this).rel_of_line(v)) return 0;
Point a=v.point_proj_line(p);
double d=v.dis_point_to_line(p);
d=sqrt(r*r-d*d);
if(sgn(d)==0)
{
p1=a;
p2=a;
return 1;
}
p1=a+(v.e-v.s).turn_to_r(d);
p2=a-(v.e-v.s).turn_to_r(d);
return 2;
}
//得到过 a,b 两点,半径为 r1 的两个圆
int circle_by_point_point_r(Point a,Point b,double r1,circle &c1,circle &c2)
{
circle x(a,r1),y(b,r1);
int t=x.point_two_circle(y,c1.p,c2.p);
if(!t) return 0;
c1.r=c2.r=r;
return t;
}
//得到与直线 u 相切,过点 q, 半径为 r1 的圆
int circle_by_line_point_r(Line u,Point q,double r1,circle &c1,circle &c2)
{
double dis=u.dis_point_to_line(q);
if(sgn(dis-r1*2)>0) return 0;
if(sgn(dis)==0)
{
c1.p=q+((u.e-u.s).turn_left().turn_to_r(r1));
c2.p=q+((u.e-u.s).turn_right().turn_to_r(r1));
c1.r=c2.r=r1;
return 2;
}
Line u1=Line((u.s+(u.e-u.s).turn_left().turn_to_r(r1)),(u.e+(u.e-u.s).turn_left().turn_to_r(r1)));
Line u2=Line((u.s+(u.e-u.s).turn_right().turn_to_r(r1)),(u.e+(u.e-u.s).turn_right().turn_to_r(r1)));
circle cc=circle(q,r1);
Point p1,p2;
if(!cc.point_line_circle(u1,p1,p2)) cc.point_line_circle(u2,p1,p2);
c1=circle(p1,r1);
if(p1==p2)
{
c2=c1;
return 1;
}
c2=circle(p2,r1);
return 2;
}
//同时与直线 u,v 相切,半径为 r1 的圆
int circle_by_line_line_r(Line u,Line v,double r1,circle &c1,circle &c2,circle &c3,circle &c4)
{
if(u.parallel(v)) return 0;
Line u1=Line(u.s+(u.e-u.s).turn_left().turn_to_r(r1),u.e+(u.e-u.s).turn_left().turn_to_r(r1));
Line u2=Line(u.s+(u.e-u.s).turn_right().turn_to_r(r1),u.e+(u.e-u.s).turn_right().turn_to_r(r1));
Line v1=Line(v.s+(v.e-v.s).turn_left().turn_to_r(r1),v.e+(v.e-v.s).turn_left().turn_to_r(r1));
Line v2=Line(v.s+(v.e-v.s).turn_right().turn_to_r(r1),v.e+(v.e-v.s).turn_right().turn_to_r(r1));
c1.r=c2.r=c3.r=c4.r=r1;
c1.p=u1.cross_point(v1);
c2.p=u1.cross_point(v2);
c3.p=u2.cross_point(v1);
c4.p=u2.cross_point(v2);
return 4;
}
//同时与不相交圆 cx,cy 相切,半径为 r1 的圆
int circle_by_circle_circle_r(circle cx,circle cy,double r1,circle &c1,circle &c2)
{
circle x(cx.p,r1+cx.r),y(cy.p,r1+cy.r);
int t=x.point_two_circle(y,c1.p,c2.p);
if(!t) return 0;
c1.r=c2.r=r1;
return t;
}
//过一点作圆的切线 (先判断点和圆的关系)
int tangentline(Point q,Line &u,Line &v)
{
int x=rel_of_point(q);
if(x==2) return 0;
if(x==1)
{
u=Line(q,q+(q-p).turn_left());
v=u;
return 1;
}
double d=p.dis(q);
double l=r*r/d;
double h=sqrt(r*r-l*l);
u=Line(q,p+((q-p).turn_to_r(l)+(q-p).turn_left().turn_to_r(h)));
v=Line(q,p+((q-p).turn_to_r(l)+(q-p).turn_right().turn_to_r(h)));
return 2;
}
//求两圆相交的面积
double area_circle(circle v)
{
int rel=rel_of_circle(v);
if(rel>=4) return 0.0;
if(rel<=2) return min(area(),v.area());
double d=p.dis(v.p);
double hf=(r+v.r+d)/2.0;
double ss=2*sqrt(hf*(hf-r)*(hf-v.r)*(hf-d));
double a1=acos((r*r+d*d-v.r*v.r)/(2.0*r*d));
a1=a1*r*r;
double a2=acos((v.r*v.r+d*d-r*r)/(2.0*v.r*d));
a2=a2*v.r*v.r;
return a1+a2-ss;
}
//求圆和三角形 pab 的相交面积
double area_triangle(Point a,Point b)
{
if(sgn((p-a)^(p-b))==0) return 0.0;
Point q[10];
int len=0;
q[len++]=a;
Line l(a,b);
if(point_line_circle(l,q[1],q[2])==2)
{
if(sgn((a-q[1])*(b-q[1]))<0) q[len++]=q[1];
if(sgn((a-q[2])*(b-q[2]))<0) q[len++]=q[2];
}
q[len++]=b;
if(len==4&&sgn((q[0]-q[1])*(q[2]-q[1]))>0) swap(q[1],q[2]);
double res=0;
for(int i=0;i<len-1;i++)
{
if(rel_of_point(q[i])==0||rel_of_point(q[i+1])==0)
{
double arg=p.rad(q[i],q[i+1]);
res+=r*r*arg/2.0;
}
else res+=abs((q[i]-p)^(q[i+1]-p))/2.0;
}
return res;
}
};