二维几何基础(模板)

#include<bits/stdc++.h>
using namespace std;
const double eps=1e-10;

struct Point{
	double x,y;
	Point(double xx=0,double yy=0):x(xx),y(yy){}
};
typedef Point Vector;

Vector operator+(Vector A,Vector B){ return Vector(A.x+B.x,A.y+B.y); }
Vector operator-(Point A,Point 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); }
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 Dot(Vector A,Vector B){ return A.x*B.x+A.y*B.y; }//向量点积 
double Length(Vector A){ return sqrt(Dot(A,A)); }//向量长度 
double Angle(Vector A,Vector B){ return acos(Dot(A,B)/Length(A)/Length(B)); }//两向量夹角 
double Cross(Vector A,Vector B){ return A.x*B.y-A.y*B.x; }//向量叉积
double Area2(Point A,Point B,Point C){ return Cross(B-A,C-A); }//三角形ABC有向面积的两倍 

Vector Rotate(Vector A,double rad){//向量逆时针旋转rad弧度 
	return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
Vector Normal(Vector A){//向量的单位法线,逆时针转90度后长度单位化 
	double L=Length(A);
	return Vector(-A.y/L,A.x/L);
}

//求直线P+tv和Q+tw的交点,调用前确保有唯一交点即Cross(v,w)非0(参数式) 
Point GetLineIntersection(Point P,Vector v,Point Q,Vector w){ 
	Vector u=P-Q;
	double t=Cross(w,u)/Cross(v,w);
	return P+v*t;
}
//求直线A1,A2和直线B1,B2的交点,调用前确保有唯一交点(两点式) 
Point GetLineIntersectionB(Point A1,Point A2,Point B1,Point B2){
	return GetLineIntersection(A1,A2-A1,B1,B2-B1);
}

//点P到直线AB距离 
double DistanceToLine(Point P,Point A,Point B){
	Vector v1=B-A,v2=P-A;
	return fabs(Cross(v1,v2))/Length(v1);
}
//点P到线段AB距离
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(Dot(v1,v2))<0) return Length(v2);
	else if(dcmp(Dot(v1,v3))>0) return Length(v3);
	else return fabs(Cross(v1,v2)/Length(v1));
}
//点P到直线AB的投影 
Point GetLineProjection(Point P,Point A,Point B){
	Vector v=B-A;
	return A+v*(Dot(v,P-A)/Dot(v,v));
}

//线段a1,a2和b1,b2的"规范相交"判定 
bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2){
	double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1),
	       c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1);
	return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}
//点p是否在线段a1,a2上
bool OnSegment(Point p,Point a1,Point a2){
	return dcmp(Cross(a1-p,a2-p))==0 && dcmp(Dot(a1-p,a2-p))<0;
}

//多边形有向面积
double PolygonArea(Point* p,int n){
	double area=0;
	for(int i=1;i<n-1;++i)
		area+=Cross(p[i]-p[0],p[i+1]-p[0]);	
	return area/2;
}

int main(){
	
	return 0;
}
posted @ 2019-02-13 18:27  不想吃WA的咸鱼  阅读(137)  评论(0编辑  收藏  举报