圆有关的计算

#include<bits/stdc++.h>
using namespace std;
struct Circle//圆的结构体
{
Point c;
double r;
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);
}
};
struct Line
{
Point v,Point p
};
int getLineCircleIntersection(Line L,Circle C,double &t1,double &t2,vector<Point>&sol)//直线和圆的交点
{
double a=L.v.x,b=L.p.x-C.c.x,c=L.v.y,d=L.p.y-C.c.y;
double e=a*a+c*c,f=2*(a*b+c*d),g=b*b-d*d-C.r*C.r;
double delta=f*f-4*e*g;//判别式
if(dcmp(delta)<0) return 0;//相离
if(dcmp(delta)==0) //相切
{
t1=t2=-f/(2*e);sol.push_back(L.point(t1));
return 1;
}
t1=(-f-sqrt(delta))/(2*e);sol.push_back(L.point(t1));
t2=(-f+sqrt(delta))/(2*e);sol.push_back(L.point(t2));
return 2;
}
double angle(Vector v)
{
return atan2(v.y,v.x);
}
int getCircleCircleIntersection(Circle c1,Circle c2,vector<Point> &sol)
{
double d=Length(C1.c-C2.c);
if(dcmp(d)==0)
{
if(dcmp(C1.r-C2.r)==0) return -1;//两圆重合 
return 0;//包含关系 
}
if(dcmp(C1.r+C2.r-d)<0) return 0;//相离 
if(dcmp(fabs(C1.r-C2.r)-d)>0) return 0;//内含 
double a= angle(C2.c-C1.c);
double da=acos(C1.r*C1.r+d*d-C2.r*C2.r)/(2*C1.r*d);
Point p1=C1.Point(a-da),p2=C1.point(a+da);//两条切线的极角 
sol.push_back(p1);
if(p1==p2) return 1;
sol.push_back(p2);
return 2;
}
int getTangents(Point p,Circle C,Vector *v)//过定点作圆的切线 
{
Vector u=C.c-p;
double dist = Length(u);
if(dist<C.r) return 0;
else if(dcmp(dist-C.r)==0)?
{
v[0]=Rotate(u,PI/2);
return 1;
}
else
{
double ang=asin(C.r/dist);
v[0]=Rotate(u,-ang);
v[1]=Rotate(u,ang);
return 2;
}
}
int getTangents(Circle A,Circle B,Point *a,Point *b)//公切线 
{
int cnt=0;
if(A.r<B.r) {
swap(A,B);
swap(a,b);
}
int d2=(A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
int rdiff=A.r-B.r;
int rsum=A.r+B.r;
if(d2<rdiff*rdiff) return 0;//内含 
double base=atan2(B.y-A.y,B.x-A.x);
if(d2==0&&A.r==B.r) return -1;//重合 
if(d2==rdiff*rdiff)//内切 
{
a[cnt]=A.getPoint(base);
b[cnt]=B.getPoint(base);
cnt++;
return 1;
}
double ang=acos(A.r-B.r)/sqrt(d2);
a[cnt]=A.getPoint(base+ang);
b[cnt]=B.getPoint(base+ang);
cnt++;
a[cnt]=A.getPoint(base-ang);
b[cnt]=B.getPoint(base+ang);
cnt++;
if(d2==rsum*rsum)//外切 
{
a[cnt]=A.getPoint(base);
b[cnt]=B.getPoint(PI+base);
cnt++;
}
else if(d2>rsum*rsum)//相离 
{
double ang=acos((A.r+B.r)/sqrt(d2));
a[cnt]=A.getPoint(base+ang);b[cnt]=B.getPoint(PI+base+ang);cnt++;
a[cnt]=A.getPoint(base-ang);b[cnt]=B.getPoint(PI+base-ang);cnt++;
}
return cnt;
}
int main()
{
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值