计算几何 || 圆 二维模板

来源:互联网 发布:淘宝网ued官方博客 编辑:程序博客网 时间:2024/05/16 08:35
</pre><pre name="code" class="cpp">#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<vector>#define FIR first#define SEC secondusing 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;}


0 0
原创粉丝点击