计算几何 || 圆 二维模板
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; }