码迷,mamicode.com
首页 > 其他好文 > 详细

计算几何模板

时间:2015-08-30 00:54:07      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:

既然咱负责计算几何,就多刷一些题吧ww

 

模板改编自刘汝佳

 

点,线基础部分:

struct Point{double x, y;Point(double x=0, double y=0) :x(x),y(y) {}};
typedef Point Vector;
Point Read(){double x, y;scanf("%lf%lf", &x, &y);return Point(x, y);}
Vector    operator + (Vector A, Vector B){ return Vector(A.x + B.x, A.y + B.y); }
Vector    operator - (Vector A, Vector B){ return Vector(A.x - B.x, A.y - B.y); }
Vector    operator * (Vector A, double p){ return Vector(A.x*p, A.y*p); }
Vector    operator / (Vector A, double p){ return Vector(A.x/p, A.y/p); }
double    operator * (Vector A, Vector B){ return A.x*B.x + A.y*B.y;}//点积
double    operator ^ (Vector A, Vector B){ return A.x*B.y - A.y*B.x;}//叉积
bool    operator < (const Point& a, const Point& b){ return a.x < b.x || (a.x == b.x && a.y < b.y); }
int    dcmp(double x){if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; }
bool    operator ==(const Point& a, const Point& b){ return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0; }
double     Length(Vector A){ return sqrt(A*A); }//向量的模
double     Angle(Vector A, Vector B){return acos(A*B / Length(A) / Length(B)); }//向量的夹角,返回值为弧度
double     Area2(Point A, Point B, Point C){ return (B-A)^(C-A); }//向量AB叉乘AC的有向面积
Vector     VRotate(Vector A, double rad){return Vector(A.x*cos(rad) - A.y*sin(rad), A.x*sin(rad) + A.y*cos(rad));}//向量A旋转rad弧度
Point     PRotate(Point A, Point B, double rad){return A + VRotate(B-A, rad);}//将B点绕A点旋转rad弧度
Vector     Normal(Vector A){double l = Length(A);return Vector(-A.y/l, A.x/l);}//求向量A向左旋转90°的单位法向量,调用前确保A不是零向量

Point GetLineIntersection/*求直线交点,调用前要确保两条直线有唯一交点*/(Point P, Vector v, Point Q, Vector w){double t = (w^(P - Q)) / (v^w);return P + v*t;}//在精度要求极高的情况下,可以自定义分数类
double DistanceToLine/*P点到直线AB的距离*/(Point P, Point A, Point B){Vector v1 = B - A, v2 = P - A;return fabs(v1^v2) / Length(v1);}//不加绝对值是有向距离
double DistanceToSegment/*点到线段的距离*/(Point P, Point A, Point B)
{
    if (A==B) return Length(P-A);
    Vector v1=B-A,v2=P-A,v3=P-B;
    if (dcmp(v1*v2)<0) return Length(v2);else
    if (dcmp(v1*v3)>0) return Length(v3);else
    return fabs(v1*v2)/Length(v1);
}

Point GetLineProjection/*点在直线上的射影*/(Point P, Point A, Point B)
{
    Vector v=B-A;
    return A+v*((v*(P-A))/(v*v));
}

bool SS_IS/*线段“规范”相交判定*/(Point a1, Point a2, Point b1, Point b2)
{
    double c1=(a2-a1)^(b1-a1),c2=(a2-a1)^(b2-a1);
    double c3=(b2-b1)^(a1-b1),c4=(b2-b1)^(a2-b1);
    return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}
bool OnSegment/*判断点是否在线段上(含端点)*/(Point P,Point a1,Point a2)
{
    Vector v1=a1-P,v2=a2-P;
    if (dcmp(v1^v2)==0 && min(a1.x,a2.x)<=P.x  && P.x<=max(a1.x,a2.x)  && min(a1.y,a2.y)<=P.y && P.y<=max(a1.y,a2.y)) return true;
    return false;
}

bool InTri/*判断点是否在三角形内*/(Point P, Point a,Point b,Point c)
{
    if (dcmp(fabs((c-a)^(c-b))-fabs((p-a)^(p-b))-fabs((p-b)^(p-c))-fabs((p-a)^(p-c)))==0) return true;
    return false;
}

double PolygonArea/*求多边形面积,注意凸包P序号从0开始*/(Point *P ,int n)
{
    double ans = 0.0;
    for(int i=1;i<n-1;i++)
        ans+=(P[i]-P[0])^(P[i+1]-P[0]);
    return ans/2;
}
bool CrossOfSegAndLine/*判断线段是否与直线相交*/(Point a1,Point a2,Point b1,Vector b2)
{
    if (OnSegment(b1,a1,a2) || OnSegment(b1+b2,a1,a2)) return true;
    return dcmp(b2^(a1-b1))*dcmp(b2^(a2-b1))<0;
}

 

计算几何模板

标签:

原文地址:http://www.cnblogs.com/zhyfzy/p/4770173.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!