模板 点或向量
计算几何基础
const double eps=1e-6;
const double inf=1e20;
const double pi=acos(-1.0);
//符号函数
int sgn(double x){
if(fabs(x)<eps) return 0;
if(x>0) return 1;
return -1;
}
//平方
double squ(double x){
return x*x;
}
点或向量
struct Point{
double x,y;
Point(){}
Point(double _x,double _y){
x=_x;
y=_y;
}
void input(){
scanf("%lf%lf",&x,&y);
}
void output(){
printf("%.2f %.2f\n",x,y);
}
bool operator == (Point b)const{
return sgn(x-b.x)==0 && sgn(y-b.y)==0;
}
//按照横坐标为第一优先级,纵坐标为第二优先级排序
bool operator < (Point b)const{
return sgn(x-b.x)==0?sgn(y-b.y)<0:x<b.x;
}
Point operator - (const Point &b)const{
return Point(x-b.x,y-b.y);
}
//叉积
double operator ^ (const Point &b)const{
return x*b.y-y*b.x;
}
//点积
double operator * (const Point &b)const{
return x*b.x+y*b.y;
}
//返回长度
double len(){
return hypot(x,y);//库函数
}
//返回长度的平方
double len_squ(){
return x*x+y*y;
}
//返回两点的距离
double distance(Point p){
return hypot(x-p.x,y-p.y);
}
Point operator + (const Point &b)const{
return Point(x+b.x,y+b.y);
}
Point operator * (const double &k)const{
return Point(x*k,y*k);
}
Point operator / (const double &k)const{
return Point(x/k,y/k);
}
//计算pa和pb的夹角
double rad(Point a,Point b){
Point p=*this;
return fabs(atan2(fabs((a-p)^(b-p)),(a-p)*(b-p)));
}
//化为长度为r的向量
Point trunc(double r){
double l=len();
if(!sgn(l)) return *this;
r/= l;
return Point(x*r,y*r);
}
//逆时针旋转90度
Point rotleft(){
return Point(-y,x);
}
//顺时针旋转90度
Point rotright(){
return Point(y,-x);
}
//绕着p点逆时针旋转angle角度
Point rotate(Point p,double angle){
Point v=(*this)-p;
double c=cos(angle),s=sin(angle);
return Point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
}
};
具有公共起点向量的点积和叉积
//AB X AC
double cross(Point A,Point B,Point C){
return (B-A)^(C-A);
}
//AB*AC
double dot(Point A,Point B,Point C){
return (B-A)*(C-A);
}