• 计算几何模版(点,线)


      1 #include<math.h>
      2 #define MAXN 1000
      3 #define offset 10000
      4 #define eps 1e-8
      5 #define PI acos(-1.0)//3.14159265358979323846
      6 //判断一个数是否为0,是则返回true,否则返回false
      7 #define zero(x)(((x)>0?(x):-(x))<eps)
      8 //返回一个数的符号,正数返回1,负数返回2,否则返回0
      9 #define _sign(x)((x)>eps?1:((x)<-eps?2:0))
     10 struct point 
     11 {
     12     double x,y;
     13 };
     14 struct line
     15 {
     16     point a,b;
     17 };//直线通过的两个点,而不是一般式的三个系数
     18 //求矢量[p0,p1],[p0,p2]的叉积
     19 //p0是顶点
     20 //若结果等于0,则这三点共线
     21 //若结果大于0,则p0p2在p0p1的逆时针方向
     22 //若结果小于0,则p0p2在p0p1的顺时针方向
     23 double xmult(point p1,point p2,point p0)
     24 {
     25     return(p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
     26 }
     27 //计算dotproduct(P1-P0).(P2-P0)
     28 double dmult(point p1,point p2,point p0)
     29 {
     30     return(p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
     31 }
     32 //两点距离
     33 double distance(point p1,point p2)
     34 {
     35     return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
     36 }
     37 //判三点共线
     38 int dots_inline(point p1,point p2,point p3)
     39 {
     40     return zero(xmult(p1,p2,p3));
     41 }
     42 //判点是否在线段上,包括端点
     43 int dot_online_in(point p,line l)
     44 {
     45     return zero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&&(l.a.y-p.y)*(l.b.y-p.y)<eps;
     46 }
     47 //判点是否在线段上,不包括端点
     48 int dot_online_ex(point p,line l)
     49 {
     50     return dot_online_in(p,l)&&(!zero(p.x-l.a.x)||!zero(p.y-l.a.y))&&(!zero(p.x-l.b.x)||!zero(p.y-l.b.y));
     51 }
     52 //判两点在线段同侧,点在线段上返回0
     53 int same_side(point p1,point p2,line l)
     54 {
     55     return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps;
     56 }
     57 //判两点在线段异侧,点在线段上返回0
     58 int opposite_side(point p1,point p2,line l)
     59 {
     60     return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)<-eps;
     61 }
     62 //判两直线平行
     63 int parallel(line u,line v)
     64 {
     65     return zero((u.a.x-u.b.x)*(v.a.y-v.b.y)-(v.a.x-v.b.x)*(u.a.y-u.b.y));
     66 }
     67 //判两直线垂直
     68 int perpendicular(line u,line v)
     69 {
     70     return zero((u.a.x-u.b.x)*(v.a.x-v.b.x)+(u.a.y-u.b.y)*(v.a.y-v.b.y));
     71 }
     72 //判两线段相交,包括端点和部分重合
     73 int intersect_in(line u,line v)
     74 {
     75     if(!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))
     76         return!same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);
     77     return dot_online_in(u.a,v)||dot_online_in(u.b,v)||dot_online_in(v.a,u)||dot_online_in(v.b,u);
     78 }
     79 //判两线段相交,不包括端点和部分重合
     80 int intersect_ex(line u,line v)
     81 {
     82     return opposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u);
     83 }
     84 //计算两直线交点,注意事先判断直线是否平行!
     85 //线段交点请另外判线段相交(同时还是要判断是否平行!)
     86 point intersection(line u,line v)
     87 {
     88     point ret=u.a;
     89     double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))/((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));
     90     ret.x+=(u.b.x-u.a.x)*t;
     91     ret.y+=(u.b.y-u.a.y)*t;
     92     return ret;
     93 }
     94 //点到直线上的最近点
     95 point ptoline(point p,line l)
     96 {
     97     point t=p;
     98     t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;
     99     return intersection(p,t,l.a,l.b);
    100 }
    101 //点到直线距离
    102 double disptoline(point p,line l)
    103 {
    104     return fabs(xmult(p,l.a,l.b))/distance(l.a,l.b);
    105 }
    106 //点到线段上的最近点
    107 point ptoseg(point p,line l)
    108 {
    109     point t=p;
    110     t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;
    111     if(xmult(l.a,t,p)*xmult(l.b,t,p)>eps)
    112         return distance(p,l.a)<distance(p,l.b)?l.a:l.b;
    113     return intersection(p,t,l.a,l.b);
    114 }
    115 //点到线段距离
    116 double disptoseg(point p,line l)
    117 {
    118     point t=p;
    119     t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;
    120     if(xmult(l.a,t,p)*xmult(l.b,t,p)>eps)
    121         return distance(p,l.a)<distance(p,l.b)?distance(p,l.a):distance(p,l.b);
    122     return fabs(xmult(p,l.a,l.b))/distance(l.a,l.b);
    123 }
    124 struct TPoint
    125 {
    126     double x,y;
    127     TPoint operator-(TPoint&a)
    128     {
    129         TPoint p1;
    130         p1.x=x-a.x;
    131         p1.y=y-a.y;
    132         return p1;
    133     }
    134 };
    135 
    136 struct TLine
    137 {
    138     double a,b,c;
    139 };
    140 
    141 //求p1关于p2的对称点
    142 TPoint symmetricalPoint(TPoint p1,TPoint p2)
    143 {
    144     TPoint p3;
    145     p3.x=2*p2.x-p1.x;
    146     p3.y=2*p2.y-p1.y;
    147     return p3;
    148 }
    149 //p点关于直线L的对称点
    150 TPoint symmetricalPointofLine(TPoint p,TLine L)
    151 {
    152     TPoint p2;
    153     double d;
    154     d=L.a*L.a+L.b*L.b;
    155     p2.x=(L.b*L.b*p.x-L.a*L.a*p.x-2*L.a*L.b*p.y-2*L.a*L.c)/d;
    156     p2.y=(L.a*L.a*p.y-L.b*L.b*p.y-2*L.a*L.b*p.x-2*L.b*L.c)/d;
    157     return p2;
    158 }
    159 //求线段所在直线,返回直线方程的三个系数
    160 //两点式化为一般式
    161 TLine lineFromSegment(TPoint p1,TPoint p2)
    162 {
    163     TLine tmp;
    164     tmp.a=p2.y-p1.y;
    165     tmp.b=p1.x-p2.x;
    166     tmp.c=p2.x*p1.y-p1.x*p2.y;
    167     return tmp;
    168 }
    169 //求直线的交点
    170 //求直线的交点,注意平行的情况无解,避免RE
    171 TPoint LineInter(TLine l1,TLine l2)
    172 {
    173     //求两直线得交点坐标
    174     TPoint tmp;
    175     double a1=l1.a;
    176     double b1=l1.b;
    177     double c1=l1.c;
    178     double a2=l2.a;
    179     double b2=l2.b;
    180     double c2=l2.c;
    181     //注意这里b1=0
    182     if(fabs(b1)<eps){
    183         tmp.x=-c1/a1;
    184         tmp.y=(-c2-a2*tmp.x)/b2;
    185     }
    186     else{
    187         tmp.x=(c1*b2-b1*c2)/(b1*a2-b2*a1);
    188         tmp.y=(-c1-a1*tmp.x)/b1;
    189     }
    190     //cout<<"交点坐标"<<endl;
    191     //cout<<a1*tmp.x+b1*tmp.y+c1<<endl;
    192     //cout<<a2*tmp.x+b2*tmp.y+c2<<endl;
    193     return tmp;
    194 }
    195 //矢量(点)V以P为顶点逆时针旋转angle(弧度)并放大scale倍
    196 point rotate(point v,point p,double angle,double scale){
    197     point ret=p;
    198     v.x-=p.x,v.y-=p.y;
    199     p.x=scale*cos(angle);
    200     p.y=scale*sin(angle);
    201     ret.x+=v.x*p.x-v.y*p.y;
    202     ret.y+=v.x*p.y+v.y*p.x;
    203     return ret;
    204 }
    205 //矢量(点)V以P为顶点逆时针旋转angle(弧度)
    206 point rotate(point v,point p,double angle){
    207     double cs=cos(angle),sn=sin(angle);
    208     v.x-=p.x,v.y-=p.y;
    209     p.x+=v.x*cs-v.y*sn;
    210     p.y+=v.x*sn+v.y*cs;
    211     return p;
    212 }
  • 相关阅读:
    C语言文件
    java课程设计-彩票购买抽奖程序
    面向对象设计大作业——图书馆
    有理数类设计
    图总结
    编译器、编辑器、文件、IDE等常见概念辨析
    树、二叉树、查找算法总结
    互评:数据结构、算法及线性表总结
    c语言文件
    第二次博客园作业
  • 原文地址:https://www.cnblogs.com/Missa/p/2790906.html
Copyright © 2020-2023  润新知