您的位置:首页 > 其它

计算几何 || 圆 二维模板

2015-04-14 20:06 302 查看
</pre><pre name="code" class="cpp">#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#define FIR first
#define SEC second
using namespace std;
const double eps = 1e-8;
const double PI = acos(-1.0);
int dcmp(double x)
{
if(fabs(x)<eps)
return 0;
return x < 0? -1: 1;
}
struct pnode
{
double x,y;
pnode(double x=0.0,double y=0.0):x(x),y(y){}
pnode operator - (const pnode &b)const{ return pnode(x-b.x,y-b.y);}
pnode operator + (const pnode &b)const{ return pnode(x+b.x,y+b.y);}
bool operator < (const pnode &b)const
{
return dcmp(x - b.x)<0 || ( dcmp(x-b.x)==0 && dcmp(y-b.y)<0);
}
};
struct circle
{
double x,y,r;
circle(double x=0.0,double y=0.0,double r=0.0):x(x),y(y),r(r){}
pnode point(double a)//圆心角求唯一点坐标
{
return pnode( x+r*cos(a),y+r*sin(a));
}
int pscanf()
{
return scanf("%lf %lf %lf",&x,&y,&r);
}
}A,B;
// 两圆面积交
double cir_area_inst(circle A, double r1, circle B, double r2) {

double a1, a2, d, ans;
pnode c (A.x-B.x,A.y-B.y);
d = sqrt(c.x*c.x + c.y*c.y);

if ( d > r1 + r2 - eps )//外离或者外切
return 0;
if ( d < r2 - r1 + eps )//
return PI*r1*r1;
if ( d < r1 - r2 + eps )
return PI*r2*r2;
a1 = acos((r1*r1+d*d-r2*r2)/2/r1/d);
a2 = acos((r2*r2+d*d-r1*r1)/2/r2/d);
ans = (a1-0.5*sin(2*a1))*r1*r1 + (a2-0.5*sin(2*a2))*r2*r2;
return ans;

}
//两圆求公切线
//a[i] 为第i条切线与圆A的交点
int get_tangents(circle A, circle B, pnode *a, pnode *b){
int cnt = 0;        //存切点用
if(dcmp(A.r - B.r) < 0)
{
swap(A, B);
swap(a, b);
}
double d = sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));     //圆心距
double rdiff = A.r - B.r;      //两圆半径差
double rsum  = A.r + B.r;       //两圆半径和
if(dcmp(d - rdiff) < 0)
return 0;        //1.内含
double base = atan2(B.y - A.y, B.x - A.x);      //向量AB的极角
if(dcmp(d) == 0) return -1;        //2.重合
if(dcmp(d - rdiff) == 0)
{       //3.内切
a[cnt] = b[cnt] = A.point(base);
cnt++;
return 1;
}
double ang = acos((A.r - B.r) / d);
a[cnt] = A.point(base + ang); b[cnt] = B.point(base + ang); cnt++;      //4.相交(外切、外离的外公切线也在此求出)
a[cnt] = A.point(base - ang); b[cnt] = B.point(base - ang); cnt++;      //两条外公切线的切点
if(dcmp(d - rsum) == 0)
{        //5.外切
a[cnt] = b[cnt] = A.point(base);
cnt++;
}
else if(dcmp(d - rsum) > 0)
{      //6.外离
double ang = acos((A.r + B.r) / d);
a[cnt] = A.point(base + ang); b[cnt] = B.point(PI + base + ang); cnt++;
a[cnt] = A.point(base - ang); b[cnt] = B.point(PI + base - ang); cnt++;
}
return cnt;
}

int main()
{
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: