• 计算几何模板 ①


    包含一些点与直线,线段的操作
    凸包的构建与判断之类的操作

    #include<cmath>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const double eps=1e-6;
    const double Pi=acos(-1.00);
    inline int dcmp(double x)
    {
    	if(x>eps)return 1;
    	return x<-eps?-1:0;
    }
    struct Vector
    {
    	double x,y;
    	Vector(double X=0,double Y=0)
    	{
    		x=X,y=Y;
    	}
    	bool operator < (const Vector &b)const 
    	{
    		return dcmp(x-b.x)==0?y<b.y:x<b.x;
    	}
    	bool operator == (const Vector &b)const 
    	{
    		return dcmp(x-b.x)==0&&dcmp(y-b.y)==0;
    	}
    }p[5];
    double dabs(Vector a)
    {
        return sqrt(a.x*a.x+a.y*a.y);
    }
    typedef Vector Point;
    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 b){return Vector(a.x*b,a.y*b);}
    Vector operator / (Vector a,double b){return Vector(a.x/b,a.y/b);}
    struct Line
    {
    	Point s,e;
    	Line(Point X=Vector(),Point Y=Vector())
    	{
    		s=X,e=Y;
    	}
    };
    typedef Line Segment;
    double dot(Vector a,Vector b)
    {
    	return a.x*b.x+a.y*b.y;
    }
    double cross(Vector a,Vector b)
    {
    	return a.x*b.y-a.y*b.x;
    }
    double dist(Point a,Point b)
    {
    	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    
    bool on_seg(Point a,Segment a1)
    {
    	Point b=a1.s,c=a1.e;
        return dcmp(cross(b-a,c-a))==0&&min(b.x,c.x)<=a.x&&a.x<=max(b.x,c.x)&&min(b.y,c.y)<=a.y&&a.y<=max(b.y,c.y);
    }
    Point get_cross(Point a,Point b,Point c,Point d)
    {
    	double t=cross(b-a,c-a)/(cross(b-a,c-a)+cross(d-a,b-a));
    	return Point(c.x+(d.x-c.x)*t,c.y+(d.y-c.y)*t);
    }
    bool is_cross(Line a1,Line a2)
    {
    	Point a=a1.s,b=a1.e,c=a2.s,d=a2.e;
    	int c1=dcmp(cross(b-a,c-a));
    	int c2=dcmp(cross(b-a,d-a));
    	int o1=dcmp(cross(d-c,b-c));
    	int o2=dcmp(cross(d-c,a-c));
    	if(c1*c2<=0&&o1*o2<=0)return true;
    	if(c1==0&&on_seg(c,a1))return true;
    	if(c2==0&&on_seg(d,a1))return true;
    	if(o1==0&&on_seg(b,a2))return true;
    	if(o2==0&&on_seg(a,a2))return true;
    	return false;
    }
    Point get_nearest_point_on_segment(Point a,Line a1)
    {
    	Point b=a1.s,c=a1.e;
    	double t=dot(a-b,c-b)/dot(c-b,c-b);
    	if(dcmp(t)!=-1&&dcmp(1-t)!=-1)return Vector(b.x+(c.x-b.x)*t,b.y+(c.y-b.y)*t);
    	if(dist(a,b)<dist(a,c))return b;
    	return c;
    }
    bool is_cross_line(Line a1,Segment a2)
    {
    	Point a=a1.s,b=a1.e,c=a2.s,d=a2.e;
    	int c1=dcmp(cross(b-a,c-a));
    	int c2=dcmp(cross(b-a,d-a));
    	if(c1*c2<=0)return true;
    	return false;
    }
    struct Circle
    {
    	Point O;
    	double R;
    	Circle(Point o=Vector(),double r=0)
    	{
    		O=o,R=r;
    	}
    };
    Point Base;
    bool cmp_ang(const Point &a,const Point &b)
    {
    	int tmp=dcmp(cross(a-Base,b-Base));
        if(tmp==0)return dist(Base,a)<dist(Base,b);
        else return tmp>0;
    }
    void sort_point(Point *s,int L,int R,Point base)
    {
    	Base=base;
    	sort(s+L,s+1+R,cmp_ang);
    	return;
    }
    struct Polygon
    {
    	Point node[10025];
    	Line edge[10025];
    	int cnt;
    	double C;
    	double A;
    	void build_edge()
    	{
    		for(int i=1;i<cnt;i++)edge[i]=Line(node[i],node[i+1]);
    		edge[cnt]=Line(node[cnt],node[1]);
    		return;
    	}
    	bool is_convex_hull()
    	{
    		bool s[3];
    		memset(s,0,sizeof(s));
    		for(int i=1;i<cnt-1;i++)
    		{
    			s[dcmp(cross(node[i+1]-node[i],node[i+2]-node[i]))+1]=true;
    			if(s[0]&&s[2])return false;
    		}
    		s[dcmp(cross(node[cnt-1]-node[cnt-2],node[cnt]-node[cnt-2]))+1]=true;
    		s[dcmp(cross(node[cnt]-node[cnt-1],node[1]-node[cnt-1]))+1]=true;
    		s[dcmp(cross(node[1]-node[cnt],node[2]-node[cnt]))+1]=true;
    		if(s[0]&&s[2])return false;
    		return true;
    	}
    	int is_in_polygon(Point a)
    	{
    		Line ray;
    		ray.s=a;
    		ray.e=Vector(-100000000.0,a.y);
    		int ans=0;
    		for(int i=1;i<=cnt;i++)
    		{
    			Point s1=edge[i].s,s2=edge[i].e;
    			if(on_seg(a,edge[i]))return 0;
    			if(dcmp(s1.y-s2.y)==0)continue;
    			if(on_seg(s1,ray))
    			{
    				if(dcmp(s1.y-s2.y)>0)ans++;
    			}
    			else if(on_seg(s2,ray))
    			{
    				if(dcmp(s2.y-s1.y)>0)ans++;
    			}
    			else if(is_cross(ray,edge[i]))ans++;
    		}
    		if(ans%2==1)return 1;
    		return -1;
    	}
    	bool circle_is_in_polygon(Circle a)
    	{
    		if(is_in_polygon(a.O)<0)return false;
            for(int i=1;i<=cnt;i++)
            if(dcmp(dist(a.O,get_nearest_point_on_segment(a.O,edge[i]))+eps-a.R)<0)return false;
            return true;
    	}
    	void get_convex_hull(Point *s,int num)
    	{
    		if(num==0)
    		{
    			cnt=0;
    			return;
    		}
    		if(num==1)
    		{
    			cnt=1;
    			node[1]=s[1];
    			return;
    		}
    		if(num==2)
    		{
    			cnt=2;
    			node[2]=s[2];
    			node[1]=s[1];
    			return ;
    		}
    		for(int i=1;i<=num;i++) 
    		if(s[i]<s[1])swap(s[1],s[i]);
    		sort_point(s,2,num,s[1]);
    		cnt=2;
    		node[1]=s[1],node[2]=s[2];
    		for(int i=3;i<=num;i++)
    		{
    			while(cnt>=2&&dcmp(cross(node[cnt]-node[cnt-1],s[i]-node[cnt-1]))<=0)cnt--;
    			node[++cnt]=s[i];
    		}
    		return;
    	}
    	double get_Circumference()
    	{
    		C=0;
    		for(int i=1;i<=cnt;i++)
    		C+=dist(edge[i].s,edge[i].e);
    		return C;
    	}
    	double get_Area()
    	{
    		A=0;
    		for(int i=1;i<cnt;i++)A+=cross(node[i],node[i+1])/2;
    		A+=cross(node[cnt],node[1])/2;
    		return A;
    	} 	
    };
    bool is_cross_polygon(Polygon a,Polygon b)
    {
    	for(int i=1;i<=a.cnt;i++)
    	for(int j=1;j<=b.cnt;j++)
    	if(is_cross(a.edge[i],b.edge[j]))return true;
    	return false;
    }
    int main()
    {
    	return 0;
    }
    
  • 相关阅读:
    oracle 函数
    Oracle 语句
    递归算法算出某个目录下所有目录和文件
    static
    递归算法
    JVM/JDK/JRE
    java跨平台原理
    .NET 未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”
    JS 判断对象是否为空
    html网页打印A4样式
  • 原文地址:https://www.cnblogs.com/Harry-bh/p/9998491.html
Copyright © 2020-2023  润新知