zoukankan      html  css  js  c++  java
  • 计算几何模板专页

    2018-2-23改

      1 #include<cstdio>
      2 #include<cmath>
      3 using namespace std;
      4 namespace X
      5 {
      6     const double eps=1e-10;
      7     struct Point
      8     {
      9         double x,y;
     10         Point(double x=0,double y=0):x(x),y(y){}
     11     };
     12     typedef Point Vec;
     13     Vec operator+(const Vec& a,const Vec& b)
     14     {
     15         return Vec(a.x+b.x,a.y+b.y);
     16     }
     17     Vec operator-(const Vec& a,const Vec& b)
     18     {
     19         return Vec(a.x-b.x,a.y-b.y);
     20     }
     21     Vec operator*(const double& a,const Vec& b)
     22     {
     23         return Vec(a*b.x,a*b.y);
     24     }
     25     Vec operator*(const Vec& a,const double& b)
     26     {
     27         return Vec(b*a.x,b*a.y);
     28     }
     29     Vec operator/(const Vec& a,const double& b)
     30     {
     31         return Vec(a.x/b,a.y/b);
     32     }
     33     int dcmp(double x)
     34     //正为1,负为-1,0为0
     35     {
     36         if(fabs(x)<eps)    return 0;
     37         return x<0?-1:1;
     38     }
     39     bool operator==(const Vec& a,const Vec& b)
     40     //判向量相等
     41     {
     42         return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
     43     }
     44     double dot(const Vec& a,const Vec& b)
     45     //点积
     46     {
     47         return a.x*b.x+a.y*b.y;
     48     }
     49     double cross(const Vec& a,const Vec& b)
     50     //叉积
     51     {
     52         return a.x*b.y-a.y*b.x;
     53     }
     54     double len(const Vec& x)
     55     //向量长度
     56     {
     57         return sqrt(dot(x,x));
     58     }
     59     double angle(const Vec& a,const Vec& b)
     60     //夹角,0~180°
     61     {
     62         return acos(dot(a,b)/len(a)/len(b));
     63     }
     64     double angle1(const Vec& a,const Vec& b)
     65     //夹角,带方向,a到b逆时针为正,顺时针为负,共线为0
     66     {
     67         return acos(dot(a,b)/len(a)/len(b))*(dcmp(cross(a,b)));
     68     }
     69     Vec rotate(const Vec& a,const double& rad)
     70     //旋转,正为逆时针,负为顺时针
     71     {
     72         return Vec(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
     73     }
     74     Vec normal(const Vec& x)
     75     //单位法线,左转90°后除以自身长度
     76     {
     77         double l=len(x);
     78         return Vec(-x.y/l,x.x/l);
     79     }
     80     Vec normal1(const Vec& x)
     81     //法线,不归一化
     82     {
     83         return Vec(-x.y,x.x);
     84     }
     85     Point lineline(const Point& p,const Vec& v,const Point& q,const Vec& w)
     86     //直线交点,GetLineIntersection
     87     {
     88         return p+v*cross(w,p-q)/cross(v,w);
     89     }
     90     double ptline(const Point& p,const Point& a,const Point& b)
     91     //point_to_line,点到直线距离,DistanceToLine
     92     {
     93         Vec v1=b-a,v2=p-a;
     94         return fabs(cross(v1,v2)/len(v1));
     95     }
     96     double ptseg(const Point& p,const Point& a,const Point& b)
     97     //point_to_segment,点到线段距离,DistanceToSegment
     98     {
     99         if(a==b)    return len(p-a);
    100         //Vec v1=b-a,v2=a-p,v3=p-b;
    101         Vec v1=b-a,v2=p-a,v3=p-b;
    102         if(dcmp(dot(v1,v2))<0)    return len(v2);
    103         else if(dcmp(dot(v1,v3))>0)    return len(v3);
    104         else return fabs(cross(v1,v2)/len(v1));
    105     }
    106     double area2(const Point& a,const Point& b,const Point& c)
    107     //叉积对应平行四边形的面积
    108     {
    109         return cross(b-a,c-a);
    110     }
    111     double thrarea(const Point& a,const Point& b,const Point& c)
    112     //三角形面积,绝对值
    113     {
    114         return fabs(cross(b-a,c-a)/2);
    115     }
    116     bool ifpar(const Vec& a,const Vec& b)
    117     //ifParallel
    118     //是否共线/平行
    119     {
    120         return dcmp(cross(a,b))==0;
    121     }
    122     Point pointline(const Point& p,const Point& a,const Vec& v)
    123     //点在直线上投影,GetLineProjection
    124     {
    125         return a+v*(dot(p-a,v)/dot(v,v));
    126     }
    127     bool ifsegseg(const Point& a1,const Point& a2,const Point& b1,const Point& b2)
    128     //SegmentProperIntersection,线段相交判定,不包含端点,不允许共线。有交点时求交点直接用直线交点即可
    129     //此处就是求两条线段的两个端点是否都分别在另一条线段的两侧
    130     {
    131         double c1=cross(a2-a1,b1-a1),c2=cross(a2-a1,b2-a1),
    132             c3=cross(b2-b1,a1-b1),c4=cross(b2-b1,a2-b1);
    133         return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;
    134     }
    135     bool ifonseg(const Point& p,const Point& a1,const Point& a2)
    136     //OnSegment,点是否在线段上,不含端点
    137     //这样就能判定向量p a1与p a2共线,且方向相反
    138     {
    139         return dcmp(cross(a1-p,a2-p))==0&&dcmp(dot(a1-p,a2-p))<0;
    140     }
    141     bool ifonseg1(const Point& p,const Point& a1,const Point& a2)
    142     //点是否在线段上,含端点
    143     {
    144         return (dcmp(cross(a1-p,a2-p))==0&&dcmp(dot(a1-p,a2-p))<0)||p==a1||p==a2;
    145     }
    146     bool ifsegseg1(const Point& a1,const Point& a2,const Point& b1,const Point& b2)
    147     //线段相交判定,包含端点,允许共线
    148     {
    149         double c1=cross(a2-a1,b1-a1),c2=cross(a2-a1,b2-a1),
    150             c3=cross(b2-b1,a1-b1),c4=cross(b2-b1,a2-b1);
    151         return (dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0)
    152         ||ifonseg(a1,b1,b2)//(dcmp(c1)==0&&dcmp(c2)==0)||
    153         ||ifonseg(a2,b1,b2)||ifonseg(b1,a1,a2)||ifonseg(b2,a1,a2)
    154         ||a1==b1||a1==b2||a2==b1||a2==b2;
    155     }
    156     double polyarea(Point p[],int n)
    157     //PolygonArea,有向面积,要求点按顺序能组成多边形(不会边相交,可以凹),如果顺时针转就是负,逆时针就是正(未验证)
    158     {
    159         double ans=0;
    160         for(int i=1;i<n-1;i++)
    161             ans+=cross(p[i]-p[0],p[i+1]-p[0]);
    162         return ans/2;
    163     }
    164 };
    165 using namespace X;
    166 int main()
    167 {
    168 
    169     return 0;
    170 }
    View Code
  • 相关阅读:
    day10 Python 形参顺序
    为oracle中的表格增加列和删除列
    为mapcontrol中的图层设置透明度
    最大的愿望 2007-05-10
    动心 2004年后半年
    写在十年 2007-09-15 (写给L之三)
    致vi老大 2011.1
    如潮 2011.2
    自然人——女孩思绪 (2006-09-14 08:21:51)
    朋友(2003年)
  • 原文地址:https://www.cnblogs.com/hehe54321/p/8462602.html
Copyright © 2011-2022 走看看