zoukankan      html  css  js  c++  java
  • 计算几何基本模板

    待更新。。。

    #include<iostream>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const double PI = acos(-1);
    const double EPS = 1e-8;//实数精度
    //点结构类型
    struct Point{
    	double x, y;
    	Point(double a = 0, double b = 0){ x = a; y = b; }
    };
    //线段结构类型
    struct LineSeg{
    	Point s, e;
    	LineSeg();
    	LineSeg(Point a, Point b): s(a), e(b){}
    };
    struct Line{//直线结构类型
    	//直线a*x+b*y+c=0 (a>=0)
    	double a, b, c;
    };
    
    Point operator-(Point a, Point b){
    	return Point(a.x - b.x, a.y - b.y);
    }
    //重载==,判断点a,b是否相等
    bool operator==(Point a, Point b){
    	return abs(a.x - b.x) < EPS&&abs(a.y - b.y) < EPS;
    }
    //比较实数r1与r2的大小关系
    int RlCmp(double r1, double r2 = 0){
    	if (abs(r1 - r2) < EPS)
    		return 0;
    	return r1>r2 ? 1 : -1;
    }
    
    //先比较横坐标再比较纵坐标,确定顺序,一般用在sort中
    bool Cmp(Point a, Point b){
    	if (abs(a.x - b.x)<EPS)
    		return a.y < b.y;
    	else
    		return a.x < b.x;
    }
    //返回两点间的距离
    double Distance(Point a, Point b){
    	return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
    }
    //返回向量p1-p0和p2-p0的点积
    double Dot(Point p0, Point p1, Point p2){
    	Point a = p1 - p0;
    	Point b = p2 - p0;
    	return a.x*b.x + a.y*b.y;
    }
    //返回向量p1-p0和p2-p0的叉积
    double Cross(Point p0, Point p1, Point p2){
    	Point a = p1 - p0;
    	Point b = p2 - p0;
    	return a.x*b.y - b.x*a.y;
    }
    //判断点p是否规范在线段L上(不包括端点)
    bool Standard_Online(LineSeg L, Point p){
    	return RlCmp(Cross(L.s, L.e, p)) == 0 &&
    		RlCmp(Dot(p, L.s, L.e))< 0;
    }
    //判断点p是在线段L上(包括端点)
    bool Standard_Online(LineSeg L, Point p){
    	return RlCmp(Cross(L.s, L.e, p)) == 0 &&
    		RlCmp(Dot(p, L.s, L.e))<=0;
    }
    //返回将点p沿着原点逆时针旋转alpha(弧度制)角度得到的点
    Point Rotate(Point p,double alpha=PI/2){
    	return Point(p.x*cos(alpha) - p.y*sin(alpha), p.x*sin(alpha) + p.y*cos(alpha));
    }
    //判断线段L1与线段L2是否相交(包括交点在线段上)
    bool Intersect(LineSeg L1, LineSeg L2){
    	//排斥实验和跨立实验
    	return max(L1.s.x, L1.e.x) >= min(L2.s.x, L2.e.x)
    		&& min(L1.s.x, L1.e.x) <= max(L2.s.x, L2.e.x)
    		&& max(L1.s.y, L1.e.y) >= min(L2.s.y, L2.e.y)
    		&& min(L1.s.y, L1.e.y) <= max(L2.s.y, L2.e.y)
    		&& Cross(L1.s, L1.e, L2.s)*Cross(L1.s, L1.e, L2.e) <= 0
    		&& Cross(L2.s, L2.e, L1.s)*Cross(L2.s, L2.e, L1.e) <= 0;
    }
    //判断线段L1与L2是否规范相交
    bool Standard_Intersect(LineSeg L1, LineSeg L2){
    	return RlCmp((Cross(L1.s, L1.e, L2.s)*Cross(L1.s, L1.e, L2.e))) < 0
    		&& RlCmp((Cross(L2.s, L2.e, L1.s)*Cross(L2.s, L2.e, L1.e)))< 0;
    }
    //两不同点a,b来构造直线
    Line MakeLine(Point a, Point b){ 
    	Line L;
    	L.a = (b.y -a.y);
    	L.b = (a.x - b.x);
    	L.c = (b.x*a.y - a.x*b.y);
    	if (L.a < 0){  //保准x系数大于等于0
    		L.a = -L.a;
    		L.b = -L.b;
    		L.c = -L.c;
    	}
    	return L;
    }
    //判直线X,Y是否相交,相交返回true和交点
    bool LineIntersect(Line X, Line Y, Point&P){
    	double d = X.a*Y.b - Y.a*X.b;
    	if (d == 0) //直线平行或者重合
    		return false;
    	P.x = (X.b*Y.c - Y.b*X.c) / d;
    	P.y = (X.c*Y.a - Y.c*X.a) / d;
    	return true;
    }
    

      

  • 相关阅读:
    JAVA 主函数(主方法)
    JAVA 什么时候使用静态
    JAVA 静态成员 static
    JAVA 构造方法之间的调用
    JAVA 构造代码块
    JAVA 构造方法
    JAVA 方法重载
    JAVA 理解封装的概念,private私有的,public公有的
    JAVA this关键字
    JAVA toString方法
  • 原文地址:https://www.cnblogs.com/td15980891505/p/5727921.html
Copyright © 2011-2022 走看看