ACM-----计算几何

一.矢量
矢量表示
1.矢量的基本运算
矢量的加法减法
矢量的数乘
矢量的点积
矢量的求模
矢量单位化(将矢量除以自身的长度得到同方向上的单位矢量)
矢量投影长(矢量与该方向上的单位矢量的点积)
矢量的叉积


class Cvector{
    public:
    double x,y;
    Cvector(double a,double b){
        x=a;y=b;
    }
};
class Cpoint{
    public:
    double x,y;
    Cpoint(double a,double b){
        x=a;
        y=b;
    }
};
class Cline{
    public: 
    Cpoint a,b;
};
Cvector operator +(Cvector p,Cvector q){
    return Cvector(p.x+q.x,p.y+q.y);
}
Cvector operator -(Cvector p,Cvector q){
    return Cvector(p.x-q.x,p.y-q.y);
}
Cvector operator *(double k,Cvector p){
    return Cvector(k*p.x,k*p.y);
}
double operator *(Cvector p,Cvector q){
    return p.x*q.x+p.y*q.y; 
}
double length(Cvector p){
    //向量求模
    return sqrt(p*p); 
}
Cvector unit(Cvector p){
    //求向量的模 
    return 1/length(p)*p;
}
double operator ^(Cvector p,Cvector q){
    //求向量的叉乘 
    return p.x*q.y-p.y*q.x;
}
Cvector operator - (Cpoint a,Cpoint b){
    //由两个点求向量
    return Cvector(b.x-a.x,b.y-a.y);
    //c=a-b 
}
Cpoint operator +(Cpoint a,Cvector b){
    return Cpoint(a.x+b.x,a.y+b.y);
}
double dist(Cpoint a,Cpoint b){
    //求两点之间的模长 
    return length(b-a);
}
double dist2(Cpoint n,Cline l){
    //求点到直线的距离 
    return fabs((l.a-n)^(l.b-n))/length(l.a-l.b);
}
Cpoint rotate(Cpoint a,Cpoint b, double alph){
    //要求AB旋转alph(弧度)转到AC
     Cvector p=b-a;
     return Cpoint(a.x+(b.x*cos(alph)-b.y*sin(alph)),
     a.y+(b.y*sin(alph))+b.x*cos(alph));
}
int sideofline(Cpoint a,Cpoint b,Cpoint p){
    //根据叉乘的方向性判断方向 
    double result=(p-a)^(b-a);
    if(result==0)return 0;//平行或在一条直线上
    else if(result>0)return 1;//在右侧
    else return -1;//在左侧 
}
/*Cline verical(Cpoint p,Cline l){
    //过点做线的垂线 
    return Cline(p,p+(rotate(l.b,l.a,pi/2)-l.a));
}*/
//矢量的投影长度---矢量与该方向单位矢量的点积
double dot(Cvector p,Cvector q){
    return p.x*q.x+p.y*q.y; 
} 
double project(Cvector p,Cvector n){
    return dot(p,unit(n));  
}
//求点到直线的垂足
Cpoint foot(Cpoint p,Cline l){
    return l.a+project(p-l.a,l.b-l.a)*unit(l.b-l.a);
} 
//求两直线的夹角
double angle(Cline p,Cline m){
    return acos(fabs(project(p.a-p.b,m.a-m.b)
    /length(p.a-p.b)));
} 

2.凸包问题
性质:任意两点的连线都在凸包上

//判断是不是凸包
#include<iostream>
using namespace std;
#define N 1000
struct point{
    double x,y;
};
//判断三个点为顺时针
int judge(point a,point b,point c){
    return (a.x-b.x)*(c.y-b.y)-(a.y-b.y)*(c.x-b.x);
} 
int main(){
    int n,s;
    point a[N];
    while(cin>>n){
        if(n==0)break;
        for(int i=0;i<n;i++)cin>>a[i].x>>a[i].y;
        for(int i=0;i<n;i++){
            s=judge(a[i],a[(i+1)%n],a[(i+2)%n]);
            if(s>0)
            break;
        }
        if(s>0)cout<<"concave"<<endl;
        else cout<<"convex"<<endl; 

    }   
}

猜你喜欢

转载自blog.csdn.net/oceansidexue/article/details/80344003