计算几何模板大选

来源:互联网 发布:淘宝卖家会员关系管理 编辑:程序博客网 时间:2024/04/30 08:49
1.两点之间距离
2.判断两点是否重合
3.叉积//可判断点在线段或直线的哪一侧
4.点积
5.判断点p是否在线段l上
6.返回点p以点o为圆心逆时针旋转alpha(单位:弧度)后所在的位置
7.返回顶角在o点,起始边为os,终止边为oe的夹角
8.判断点与线段的关系
9.求点C到线段AB所在直线的垂足 P
10.求点p到线段l的最短距离,并返回线段上距该点最近的点np
11.求点p到线段l所在直线的距离
12.计算点到折线集的最近距离,并返回最近点
13.判断圆是否在多边形内
14.返回两个 矢量 l1和l2的夹角的余弦
15.返回线段l1与l2之间的夹角
16.如果线段u和v相交(包括相交在端点处)时,返回true
17.(线段u和v相交)&&(交点不是端点)时返回true
18.线段v所在直线与线段u相交时返回true
19.根据已知两点坐标,求过这两点的直线解析方程
20.根据直线解析方程返回直线的斜率k,  水平线返回 0, 竖直线返回 1e200
21.返回直线的倾斜角
22.求点p关于直线l的对称点
23.两直线相交返回true并返回交点p,不相交则返回false
24.如果线段l1和l2相交,返回true且交点由(inter)返回,否则返回false
25.返回值:点p在圆内(包括边界)时,返回true
26.三点确定一个圆,不能构成圆返回false
27.两圆位置关系
28.空间 点到平面距离
29.点在直线同侧返回true
30.两个圆(已判断为相交或相切)的交点rp1,rp2
31.两相交圆公共面积
32.圆和直线(ax+by+c=0,a>=0)关系

33.三角形内切圆

34.过圆外一点的直线与圆的两个切点

  1. <span style="font-size:14px;">#include<iostream>  
  2. #include<cmath>  
  3. #include<cstdio>  
  4. #define INF 1E200  
  5. using namespace std;  
  6. const double PI  = 3.14159265;  
  7. const double eps=0.0000000001;  
  8. struct Point //点  
  9. {  
  10.     double x,y;  
  11.     Point (double a=0,double b=0):x(a),y(b) {}  
  12. };  
  13.   
  14. struct Line_segment //线段  
  15. {  
  16.     Point s,e;  
  17.     Line_segment() {}  
  18.     Line_segment(Point a,Point b):s(a),e(b) {}  
  19. };  
  20.   
  21. struct Line //直线  
  22. {  
  23.     double A,B,C;  
  24.     Line(double A=1,double B=-1,double C=0):A(A),B(B),C(C) {}  
  25. };  
  26.   
  27. inline double Max(double a,double b)  
  28. {  
  29.     return a>b?a:b;  
  30. }  
  31.   
  32. inline double Min(double a,double b)  
  33. {  
  34.     return a<b?a:b;  
  35. }  
  36.   
  37. //计算几何 开始!  
  38. double Dist(Point a,Point b) //1.两点之间距离  
  39. {  
  40.     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));  
  41. }  
  42.   
  43. bool equal_Point(Point a,Point b) //2.判断两点是否重合  
  44. {  
  45.     return fabs(a.x-b.x)<eps&&fabs(a.y-b.y)<eps;  
  46. }  
  47.   
  48. double multiply(Point sp,Point  ep,Point op) //3.叉积//要判断点在直线哪一侧时,sp,ep为线段或者直线上两点,op为判断的点  
  49. {  
  50.     /****************************************************************************** 
  51.     r=multiply(sp,ep,op),得到(sp-op) 和 ( ep-op)的叉积 
  52.     r>0; ep在矢量op sp的逆时针方向//点在直线右边 
  53.     r=0;op sp ep 三点共线; 
  54.     r<0;ep在矢量op sp的顺时针方向//点在直线左边 
  55.     *******************************************************************************/  
  56.     return((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y));  
  57. }  
  58.   
  59. double dotmultiply(Point p1,Point p2,Point p0) //4.点积  
  60. {  
  61.     /****************************************************************************** 
  62.     r=dotmultiply(p1,p2,op),得到矢量(p1-op)和(p2-op)的点积,如果两个矢量都非零矢量 
  63.     r<0:两矢量夹角为钝角; 
  64.     r=0:两矢量夹角为直角; 
  65.     r>0:两矢量夹角为锐角; 
  66.     *******************************************************************************/  
  67.     return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);  
  68. }  
  69.   
  70. bool online(Line_segment l,Point p)//5.判断点p是否在线段l上 +3  
  71. {  
  72.     /****************************************************************************** 
  73.     判断点p是否在线段l上 
  74.     条件:(p在线段l所在的直线上) && (点p在以线段l为对角线的矩形内) 
  75.     *******************************************************************************/  
  76.     return( (multiply(l.e,p,l.s)==0) &&( ( (p.x-l.s.x)*(p.x-l.e.x)<=0 )&&( (p.y-l.s.y)*(p.y-l.e.y)<=0 ) ) );  
  77. }  
  78.   
  79. Point Rotate(Point o,double alpha,Point p) // 6.返回点p以点o为圆心逆时针旋转alpha(单位:弧度)后所在的位置  
  80. {  
  81.     Point tp;  
  82.     p.x-=o.x;  
  83.     p.y-=o.y;  
  84.     tp.x=p.x*cos(alpha)-p.y*sin(alpha)+o.x;  
  85.     tp.y=p.y*cos(alpha)+p.x*sin(alpha)+o.y;  
  86.     return tp;  
  87. }  
  88.   
  89. double angle(Point o,Point s,Point e) //7.返回顶角在o点,起始边为os,终止边为oe的夹角(单位:弧度)  
  90. {  
  91.     /****************************************************************************** 
  92.        返回顶角在o点,起始边为os,终止边为oe的夹角(单位:弧度) 
  93.     角度小于pi,返回正值 
  94.     角度大于pi,返回负值 
  95.     可以用于求线段之间的夹角 
  96.  
  97.     原理: 
  98.     r = dotmultiply(s,e,o) / (dist(o,s)*dist(o,e)) 
  99.     r'= multiply(s,e,o) 
  100.     r >= 1 angle = 0; 
  101.     r <= -1 angle = -PI 
  102.     -1<r<1 && r'>0 angle = arccos(r) 
  103.     -1<r<1 && r'<=0 angle = -arccos(r) 
  104.     ********************************************************************************/  
  105.     double cosfi,fi,norm;  
  106.     double dsx = s.x - o.x;  
  107.     double dsy = s.y - o.y;  
  108.     double dex = e.x - o.x;  
  109.     double dey = e.y - o.y;  
  110.   
  111.     cosfi=dsx*dex+dsy*dey;  
  112.     norm=(dsx*dsx+dsy*dsy)*(dex*dex+dey*dey);  
  113.     cosfi /= sqrt( norm );  
  114.   
  115.     if (cosfi >=  1.0 ) return 0;  
  116.     if (cosfi <= -1.0 ) return -3.1415926;  
  117.   
  118.     fi=acos(cosfi);  
  119.     if (dsx*dey-dsy*dex>0) return fi;      // 说明矢量os 在矢量 oe的顺时针方向  
  120.     return -fi;  
  121. }  
  122.   
  123.   
  124. double relation(Point p,Line_segment l) //8.判断点与线段的关系  
  125. {  
  126.     /****************************************************************************** 
  127.     判断点与线段的关系,用途很广泛 
  128.     本函数是根据下面的公式写的,P是点C到线段AB所在直线的垂足 
  129.  
  130.             AC dot AB 
  131.     r =     --------- 
  132.              ||AB||^2 
  133.          (Cx-Ax)(Bx-Ax) + (Cy-Ay)(By-Ay) 
  134.       = ------------------------------- 
  135.                       L^2 
  136.  
  137.     r has the following meaning: 
  138.  
  139.     r=0      P = A 
  140.     r=1      P = B 
  141.     r<0   P is on the backward extension of AB 
  142.     r>1      P is on the forward extension of AB 
  143.     0<r<1  P is interior to AB 
  144.     ********************************************************************************/  
  145.     Line_segment tl;  
  146.     tl.s=l.s;  
  147.     tl.e=p;  
  148.     return dotmultiply(tl.e,l.e,l.s)/(Dist(l.s,l.e)*Dist(l.s,l.e));  
  149. }  
  150.   
  151.   
  152.   
  153.   
  154. Point perpendicular(Point p,Line_segment l) //9.求点C到线段AB所在直线的垂足 P  
  155. {  
  156.     /****************************************************************************** 
  157.        求点C到线段AB所在直线的垂足 P 
  158.        *******************************************************************************/  
  159.     double r=relation(p,l);  
  160.     Point tp;  
  161.     tp.x=l.s.x+r*(l.e.x-l.s.x);  
  162.     tp.y=l.s.y+r*(l.e.y-l.s.y);  
  163.     return tp;  
  164. }  
  165.   
  166. double ptolinesegdist(Point p,Line_segment l,Point &np) //10.求点p到线段l的最短距离,并返回线段上距该点最近的点np  
  167. {  
  168.     /****************************************************************************** 
  169.        求点p到线段l的最短距离,并返回线段上距该点最近的点np 
  170.     注意:np是线段l上到点p最近的点,不一定是垂足 
  171.  
  172.     *******************************************************************************/  
  173.     double r=relation(p,l);  
  174.     if(r<0)  
  175.     {  
  176.         np=l.s;  
  177.         return Dist(p,l.s);  
  178.     }  
  179.     if(r>1)  
  180.     {  
  181.         np=l.e;  
  182.         return Dist(p,l.e);  
  183.     }  
  184.     np=perpendicular(p,l);  
  185.     return Dist(p,np);  
  186. }  
  187.   
  188. double ptoldist(Point p,Line_segment l) // 11.求点p到线段l所在直线的距离,请注意本函数与上个函数的区别  
  189. {  
  190.     return abs(multiply(p,l.e,l.s))/Dist(l.s,l.e);  
  191. }  
  192.   
  193.   
  194. double ptopointset(int vcount,Point pointset[],Point p,Point &q) //12.计算点到折线集的最近距离,并返回最近点.  
  195. {  
  196.     /****************************************************************************** 
  197.      计算点到折线集的最近距离,并返回最近点. 
  198.     注意:调用的是ptolineseg()函数 
  199.     *******************************************************************************/  
  200.     int i;  
  201.     double cd=double(INF),td;  
  202.     Line_segment l;  
  203.     Point tq,cq;  
  204.   
  205.     for(i=0; i<vcount-1; i++)  
  206.     {  
  207.         l.s=pointset[i];  
  208.   
  209.         l.e=pointset[i+1];  
  210.         td=ptolinesegdist(p,l,tq);  
  211.         if(td<cd)  
  212.         {  
  213.             cd=td;  
  214.             cq=tq;  
  215.         }  
  216.     }  
  217.     q=cq;  
  218.     return cd;  
  219. }  
  220.   
  221. bool CircleInsidePolygon(int vcount,Point center,double radius,Point polygon[]) //13.判断圆是否在多边形内.ptolineseg()函数的应用  
  222. {  
  223.     Point q;  
  224.     double d;  
  225.     q.x=0;  
  226.     q.y=0;  
  227.     d=ptopointset(vcount,polygon,center,q);  
  228.     if(d<radius||fabs(d-radius)<eps)  
  229.         return true;  
  230.     else  
  231.         return false;  
  232. }  
  233.   
  234. double cosine(Line_segment l1,Line_segment l2)   //14.返回两个 矢量 l1和l2的夹角的余弦  
  235. {  
  236.     /****************************************************************************** 
  237.     返回两个矢量l1和l2的夹角的余弦(-1 --- 1)注意:如果想从余弦求夹角的话,注意反余弦函数的定义域是从 0到pi 
  238.     *******************************************************************************/  
  239.     return (((l1.e.x-l1.s.x)*(l2.e.x-l2.s.x) +(l1.e.y-l1.s.y)*(l2.e.y-l2.s.y))/(Dist(l1.e,l1.s)*Dist(l2.e,l2.s)));  
  240. }  
  241.   
  242. double lsangle(Line_segment l1,Line_segment l2)  // 15.返回线段l1与l2之间的夹角 单位:弧度 范围(-pi,pi)  
  243. {  
  244.     Point o,s,e;  
  245.     o.x=o.y=0;  
  246.     s.x=l1.e.x-l1.s.x;  
  247.     s.y=l1.e.y-l1.s.y;  
  248.     e.x=l2.e.x-l2.s.x;  
  249.     e.y=l2.e.y-l2.s.y;  
  250.     return angle(o,s,e);  
  251. }  
  252.   
  253.   
  254. bool intersect(Line_segment u,Line_segment v) // 16.如果线段u和v相交(包括相交在端点处)时,返回true  
  255. {  
  256.     /****************************************************************************** 
  257.     如果线段u和v相交(包括相交在端点处)时,返回true 
  258.     判断P1P2跨立Q1Q2的依据是: ( P1 - Q1 ) x ( Q2 - Q1 ) x ( Q2 - Q1 ) x ( P2 - Q1 ) >= 0 
  259.     判断Q1Q2跨立P1P2的依据是: ( Q1 - P1 ) x ( P2 -  P1 ) x ( P2 - P1 ) x ( Q2 - P1 ) >= 0 
  260.     *******************************************************************************/  
  261.     return((Max(u.s.x,u.e.x)>=Min(v.s.x,v.e.x))&&                     //排斥实验  
  262.            (Max(v.s.x,v.e.x)>=Min(u.s.x,u.e.x))&&  
  263.            (Max(u.s.y,u.e.y)>=Min(v.s.y,v.e.y))&&  
  264.            (Max(v.s.y,v.e.y)>=Min(u.s.y,u.e.y))&&  
  265.            (multiply(v.s,u.e,u.s)*multiply(u.e,v.e,u.s)>=0)&&         //跨立实验  
  266.            (multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=0));  
  267. }  
  268.   
  269.   
  270. bool intersect_A(Line_segment u,Line_segment v) // 17.(线段u和v相交)&&(交点不是端点)时返回true  
  271. {  
  272.     return ((intersect(u,v))&&  
  273.             (!online(u,v.s))&&  
  274.             (!online(u,v.e))&&  
  275.             (!online(v,u.e))&&  
  276.             (!online(v,u.s)));  
  277. }  
  278.   
  279. bool intersect_l(Line_segment u,Line_segment v)// 18.线段v所在直线与线段u相交时返回true  
  280. {  
  281.     /****************************************************************************** 
  282.     线段v所在直线与线段u相交时返回true;方法;判断线段u是否跨立线段v 
  283.     *******************************************************************************/  
  284.     return multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=0;  
  285. }  
  286.   
  287.   
  288. Line makeline(Point p1,Point p2)   // 19.根据已知两点坐标,求过这两点的直线解析方程  
  289. {  
  290.     /****************************************************************************** 
  291.     根据已知两点坐标,求过这两点的直线解析方程Ax+By+C=0 (A>=0) 
  292.     *******************************************************************************/  
  293.     Line tl;  
  294.     int sign = 1;  
  295.     tl.A=p2.y-p1.y;  
  296.     if(tl.A<0)  
  297.     {  
  298.         sign = -1;  
  299.         tl.A=sign*tl.A;  
  300.     }  
  301.     tl.B=sign*(p1.x-p2.x);  
  302.     tl.C=sign*(p1.y*p2.x-p1.x*p2.y);  
  303.     return tl;  
  304. }  
  305.   
  306.   
  307. double slope(Line l)   // 20.根据直线解析方程返回直线的斜率k,  水平线返回 0, 竖直线返回 1e200  
  308. {  
  309.     if(abs(l.A) < 1e-20)  
  310.         return 0;  
  311.     if(abs(l.B) < 1e-20)  
  312.         return INF;  
  313.     return -(l.A/l.B);  
  314. }  
  315.   
  316.   
  317. double alpha(Line l)   //21. 返回直线的倾斜角 alpha ( 0 - pi)  
  318. {  
  319.     if(abs(l.A)< eps)  
  320.         return 0;  
  321.     if(abs(l.B)< eps)  
  322.         return PI/2;  
  323.     double k=slope(l);  
  324.     if(k>0)  
  325.         return atan(k);  
  326.     else  
  327.         return PI+atan(k);  
  328. }  
  329.   
  330.   
  331. Point symmetry(Line l,Point p) //22. 求点p关于直线l的对称点  
  332. {  
  333.     Point tp;  
  334.     tp.x=((l.B*l.B-l.A*l.A)*p.x-2*l.A*l.B*p.y-2*l.A*l.C)/(l.A*l.A+l.B*l.B);  
  335.     tp.y=((l.A*l.A-l.B*l.B)*p.y-2*l.A*l.B*p.x-2*l.B*l.C)/(l.A*l.A+l.B*l.B);  
  336.     return tp;  
  337. }  
  338.   
  339.   
  340. bool lineintersect(Line l1,Line l2,Point &p) // 23.两直线相交返回true并返回交点p,不相交则返回false  
  341. {  
  342.     double d=l1.A*l2.B-l2.A*l1.B;  
  343.     if(abs(d)<eps) // 不相交  
  344.         return false;  
  345.     p.x = (l2.C*l1.B-l1.C*l2.B)/d;  
  346.     p.y = (l2.A*l1.C-l1.A*l2.C)/d;  
  347.     return true;  
  348. }  
  349.   
  350.   
  351. bool intersection(Line_segment l1,Line_segment l2,Point &inter)   // 24.如果线段l1和l2相交,返回true且交点由(inter)返回,否则返回false  
  352. {  
  353.     Line ll1,ll2;  
  354.     ll1=makeline(l1.s,l1.e);  
  355.     ll2=makeline(l2.s,l2.e);  
  356.     if(lineintersect(ll1,ll2,inter))  
  357.         return online(l1,inter) && online(l2,inter);  
  358.     else  
  359.         return false;  
  360. }  
  361.   
  362. /*******************************************************************************/  
  363. bool point_in_circle(Point o,double r,Point p)   //25. 返回值:点p在圆内(包括边界)时,返回true  
  364. {  
  365.     /****************************************************************************** 
  366.     参数o为圆心,r为半径,p为判断的点 
  367.     返回值:点p在圆内(包括边界)时,返回true 
  368.     *******************************************************************************/  
  369.     double d2=(p.x-o.x)*(p.x-o.x)+(p.y-o.y)*(p.y-o.y);  
  370.     double r2=r*r;  
  371.     return d2<r2||abs(d2-r2)<eps;  
  372. }  
  373.   
  374.   
  375.   
  376. bool cocircle(Point p1,Point p2,Point p3,Point &q,double &r) //26.三点确定一个圆,不能构成圆返回false  
  377. {  
  378.     /****************************************************************************** 
  379.     用 途 :求不共线的三点确定一个圆 
  380.     输 入 :三个点p1,p2,p3 
  381.     返回值 :如果三点共线,返回false;反之,返回true。圆心由q返回,半径由r返回 
  382.     *******************************************************************************/  
  383.     double x12=p2.x-p1.x;  
  384.     double y12=p2.y-p1.y;  
  385.     double x13=p3.x-p1.x;  
  386.     double y13=p3.y-p1.y;  
  387.     double z2=x12*(p1.x+p2.x)+y12*(p1.y+p2.y);  
  388.     double z3=x13*(p1.x+p3.x)+y13*(p1.y+p3.y);  
  389.     double d=2.0*(x12*(p3.y-p2.y)-y12*(p3.x-p2.x));  
  390.     if(abs(d)<eps) //共线,圆不存在  
  391.         return false;  
  392.     q.x=(y13*z2-y12*z3)/d;  
  393.     q.y=(x12*z3-x13*z2)/d;  
  394.     r=Dist(p1,q);  
  395.     return true;  
  396. }  
  397.   
  398. int CircleRelation(Point p1, double r1, Point p2, double r2) //27.两圆位置关系  
  399. {  
  400.     /****************************************************************************** 
  401.     相离:return 1 
  402.     外切:return 2 
  403.     相交:return 3 
  404.     内切:return 4 
  405.     内含:return 5 
  406.     *******************************************************************************/  
  407.     double d = sqrt( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) );  
  408.   
  409.     if( fabs(d-r1-r2) < eps ) // 必须保证前两个if先被判定!  
  410.         return 2;  
  411.     if( fabs(d-fabs(r1-r2)) < eps )  
  412.         return 4;  
  413.     if( d > r1+r2 )  
  414.         return 1;  
  415.     if( d < fabs(r1-r2) )  
  416.         return 5;  
  417.     if( fabs(r1-r2) < d && d < r1+r2 )  
  418.         return 3;  
  419.     return 0; // indicate an error!未知错误  
  420. }  
  421.   
  422. double P2planeDist(double x, double y, double z, double a, double b, double c, double d) //28.空间 点到平面距离  
  423. {  
  424.     /****************************************************************************** 
  425.     空间点到平面的距离,平面用一般式表示ax+by+cz+d=0 
  426.     *******************************************************************************/  
  427.     return fabs(a*x+b*y+c*z+d) / sqrt(a*a+b*b+c*c);  
  428. }  
  429.   
  430. bool SameSide(Point p1, Point p2, Line line) //29.点在直线同侧返回true  
  431. {  
  432.     return (line.A * p1.x + line.B * p1.y + line.C) *  
  433.            (line.A * p2.x + line.B * p2.y + line.C) > 0;  
  434. }  
  435.   
  436. void  c2point(Point p1,double r1,Point p2,double r2,Point &rp1,Point &rp2) //30.两个圆(已判断为相交或相切)的交点rp1,rp2  
  437. {  
  438.     double a,b,r;  
  439.     a=p2.x-p1.x;  
  440.     b=p2.y-p1.y;  
  441.     r=(a*a+b*b+r1*r1-r2*r2)/2;  
  442.     if(a==0&&b!=0)  
  443.     {  
  444.         rp1.y=rp2.y=r/b;  
  445.         rp1.x=sqrt(r1*r1-rp1.y*rp1.y);  
  446.         rp2.x=-rp1.x;  
  447.     }  
  448.     else if(a!=0&&b==0)  
  449.     {  
  450.         rp1.x=rp2.x=r/a;  
  451.         rp1.y=sqrt(r1*r1-rp1.x*rp2.x);  
  452.         rp2.y=-rp1.y;  
  453.     }  
  454.     else if(a!=0&&b!=0)  
  455.     {  
  456.         double delta;  
  457.         delta=b*b*r*r-(a*a+b*b)*(r*r-r1*r1*a*a);  
  458.         rp1.y=(b*r+sqrt(delta))/(a*a+b*b);  
  459.         rp2.y=(b*r-sqrt(delta))/(a*a+b*b);  
  460.         rp1.x=(r-b*rp1.y)/a;  
  461.         rp2.x=(r-b*rp2.y)/a;  
  462.     }  
  463.   
  464.     rp1.x+=p1.x;  
  465.     rp1.y+=p1.y;  
  466.     rp2.x+=p1.x;  
  467.     rp2.y+=p1.y;  
  468. }  
  469.   
  470. double c2area(Point p1,double r1,Point p2,double r2) //31.两相交圆公共面积 +30  
  471. {  
  472.     double TEMP;  
  473.     Point rp1,rp2,rp;  
  474.     c2point(p1,r1,p2,r2,rp1,rp2);  
  475.     if(r1>r2) //保证r2>r1  
  476.     {  
  477.         rp=p1;  
  478.         p1=p2;  
  479.         p2=rp;  
  480.         TEMP=r1;  
  481.         r1=r2;  
  482.         r2=TEMP;  
  483.     }  
  484.     double a,b,rr;  
  485.     a=p1.x-p2.x;  
  486.     b=p1.y-p2.y;  
  487.     rr=sqrt(a*a+b*b);  
  488.   
  489.     double dx1,dy1,dx2,dy2;  
  490.     double sita1,sita2;  
  491.     dx1=rp1.x-p1.x;  
  492.     dy1=rp1.y-p1.y;  
  493.     dx2=rp2.x-p1.x;  
  494.     dy2=rp2.y-p1.y;  
  495.     sita1=acos((dx1*dx2+dy1*dy2)/r1/r1);  
  496.   
  497.     dx1=rp1.x-p2.x;  
  498.     dy1=rp1.y-p2.y;  
  499.     dx2=rp2.x-p2.x;  
  500.     dy2=rp2.y-p2.y;  
  501.     sita2=acos((dx1*dx2+dy1*dy2)/r2/r2);  
  502.     double s=0;  
  503.     if(rr<r2)//相交弧为优弧  
  504.         s=r1*r1*(PI-sita1/2+sin(sita1)/2)+r2*r2*(sita2-sin(sita2))/2;  
  505.     else//相交弧为劣弧  
  506.         s=(r1*r1*(sita1-sin(sita1))+r2*r2*(sita2-sin(sita2)))/2;  
  507.   
  508.     return s;  
  509. }  
  510.   
  511. \  
  512. int clpoint(Point p,double r,double a,double b,double c,Point &rp1,Point &rp2) //32.圆和直线(ax+by+c=0,a>=0)关系  
  513. {  
  514.     /****************************************************************************** 
  515.     相离 return 0 
  516.     相切 return 1 
  517.     相交 return 2 
  518.     *******************************************************************************/  
  519.     int res=0;  
  520.     c=c+a*p.x+b*p.y;  
  521.     double tmp;  
  522.     if(a==0&&b!=0)  
  523.     {  
  524.         tmp=-c/b;  
  525.         if(r*r<tmp*tmp)  
  526.             res=0;  
  527.         else if(r*r==tmp*tmp)  
  528.         {  
  529.             res=1;  
  530.             rp1.y=tmp;  
  531.             rp1.x=0;  
  532.         }  
  533.         else  
  534.         {  
  535.             res=2;  
  536.             rp1.y=rp2.y=tmp;  
  537.             rp1.x=sqrt(r*r-tmp*tmp);  
  538.             rp2.x=-rp1.x;  
  539.         }  
  540.     }  
  541.     else if(a!=0&&b==0)  
  542.     {  
  543.         tmp=-c/a;  
  544.         if(r*r<tmp*tmp)  
  545.             res=0;  
  546.         else if(r*r==tmp*tmp)  
  547.         {  
  548.             res=1;  
  549.             rp1.x=tmp;  
  550.             rp1.y=0;  
  551.         }  
  552.         else  
  553.         {  
  554.             res=2;  
  555.             rp1.x=rp2.x=tmp;  
  556.             rp1.y=sqrt(r*r-tmp*tmp);  
  557.             rp2.y=-rp1.y;  
  558.         }  
  559.     }  
  560.     else if(a!=0&&b!=0)  
  561.     {  
  562.         double delta;  
  563.         delta=b*b*c*c-(a*a+b*b)*(c*c-a*a*r*r);  
  564.         if(delta<0)  
  565.             res=0;  
  566.         else if(delta==0)  
  567.         {  
  568.             res=1;  
  569.             rp1.y=-b*c/(a*a+b*b);  
  570.             rp1.x=(-c-b*rp1.y)/a;  
  571.         }  
  572.         else  
  573.         {  
  574.             res=2;  
  575.             rp1.y=(-b*c+sqrt(delta))/(a*a+b*b);  
  576.             rp2.y=(-b*c-sqrt(delta))/(a*a+b*b);  
  577.             rp1.x=(-c-b*rp1.y)/a;  
  578.             rp2.x=(-c-b*rp2.y)/a;  
  579.         }  
  580.     }  
  581.     rp1.x+=p.x;  
  582.     rp1.y+=p.y;  
  583.     rp2.x+=p.x;  
  584.     rp2.y+=p.y;  
  585.     return res;  
  586. }  
  587.   
  588. void incircle(Point p1,Point p2,Point p3,Point &rp,double &r) // 33.三角形内切圆  
  589. {  
  590.     double dx31,dy31,dx21,dy21,d31,d21,a1,b1,c1;  
  591.     dx31=p3.x-p1.x;  
  592.     dy31=p3.y-p1.y;  
  593.     dx21=p2.x-p1.x;  
  594.     dy21=p2.y-p1.y;  
  595.   
  596.     d31=sqrt(dx31*dx31+dy31*dy31);  
  597.     d21=sqrt(dx21*dx21+dy21*dy21);  
  598.     a1=dx31*d21-dx21*d31;  
  599.     b1=dy31*d21-dy21*d31;  
  600.     c1=a1*p1.x+b1*p1.y;  
  601.   
  602.     double dx32,dy32,dx12,dy12,d32,d12,a2,b2,c2;  
  603.     dx32=p3.x-p2.x;  
  604.     dy32=p3.y-p2.y;  
  605.     dx12=-dx21;  
  606.     dy12=-dy21;  
  607.   
  608.     d32=sqrt(dx32*dx32+dy32*dy32);  
  609.     d12=d21;  
  610.     a2=dx12*d32-dx32*d12;  
  611.     b2=dy12*d32-dy32*d12;  
  612.     c2=a2*p2.x+b2*p2.y;  
  613.   
  614.     rp.x=(c1*b2-c2*b1)/(a1*b2-a2*b1);  
  615.     rp.y=(c2*a1-c1*a2)/(a1*b2-a2*b1);  
  616.     r=fabs(dy21*rp.x-dx21*rp.y+dx21*p1.y-dy21*p1.x)/d21;  
  617. }  
  618.   
  619. void cutpoint(Point p,double r,Point sp,Point &rp1,Point &rp2) //34.过圆外一点的直线与圆的两个切点(p为圆心,r为圆半径,点sp为圆外一点)  
  620. {  
  621.     Point p2;  
  622.     p2.x=(p.x+sp.x)/2;  
  623.     p2.y=(p.y+sp.y)/2;  
  624.     double dx2,dy2,r2;  
  625.     dx2=p2.x-p.x;  
  626.     dy2=p2.y-p.y;  
  627.     r2=sqrt(dx2*dx2+dy2*dy2);  
  628.     c2point(p,r,p2,r2,rp1,rp2);  
  629. }  
  630.   
  631. int main()  
  632. {  
  633.     double a,b,c,d;  
  634.     Point m(1,1),n(2,2);  
  635.     Line_segment w(m,n);  
  636.     while(~scanf("%lf %lf",&a,&b))  
  637.     {  
  638.         Point A(a,b);  
  639.         if(online(w,A)) printf("yes\n");  
  640.         else printf("n0\n");  
  641.     }  
  642.     return 0;  
  643. }</span>  

0 0
原创粉丝点击