计算几何模板 ①

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

#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;
}
posted @ 2018-11-21 22:58  Harry_bh  阅读(215)  评论(0编辑  收藏  举报