convexhull

//大白p263
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <functional>
#include <set>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const double eps=1e-8;//精度
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
inline int dcmp(const double& x){//判断double等于0或。。。
    if(fabs(x)<eps)return 0;else return x<0?-1:1;
}
struct Point{
    double x,y;
    Point(){}
    Point(double x,double y):x(x),y(y){}
};
typedef Point Vector;
typedef vector<Point> Polygon;
inline Vector operator+(const Vector& a,const Vector& b){return Vector(a.x+b.x,a.y+b.y);}//向量+向量=向量
inline Vector operator-(const Point& a,const Point& b){return Vector(a.x-b.x,a.y-b.y);}//点-点=向量
inline Vector operator*(const Vector& a,const double& p){return Vector(a.x*p,a.y*p);}//向量*实数=向量
inline Vector operator/(const Vector& a,const double& p){return Vector(a.x/p,a.y/p);}//向量/实数=向量
inline bool operator<( const Point& A,const Point& B ){return dcmp(A.x-B.x)<0||(dcmp(A.x-B.x)==0&&dcmp(A.y-B.y)<0);}
inline bool operator==(const Point&a,const Point&b){return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;}
inline bool operator!=(const Point&a,const Point&b){return a==b?false:true;}
struct Segment{
    Point a,b;
    Segment(){}
    Segment(Point _a,Point _b){a=_a,b=_b;}
    inline bool friend operator<(const Segment& p,const Segment& q){return p.a<q.a||(p.a==q.a&&p.b<q.b);}
    inline bool friend operator==(const Segment& p,const Segment& q){return (p.a==q.a&&p.b==q.b)||(p.a==q.b&&p.b==q.a);}
};
struct Circle{
    Point c;
    double r;
    Circle(){}
    Circle(Point _c, double _r):c(_c),r(_r) {}
    Point point(double a)const{return Point(c.x+cos(a)*r,c.y+sin(a)*r);}
    bool friend operator<(const Circle& a,const Circle& b){return a.r<b.r;}
};
struct Line{
    Point p;
    Vector v;
    double ang;
    Line() {}
    Line(const Point &_p, const Vector &_v):p(_p),v(_v){ang = atan2(v.y, v.x);}
    inline bool operator<(const Line &L)const{return  ang < L.ang;}
};
inline double Dot(const Vector& a,const Vector& b){return a.x*b.x+a.y*b.y;}//|a|*|b|*cosθ 点积
inline double Length(const Vector& a){return sqrt(Dot(a,a));}//|a| 向量长度
inline double Angle(const Vector& a,const Vector& b){return acos(Dot(a,b)/Length(a)/Length(b));}//向量夹角θ
inline double Cross(const Vector& a,const Vector& b){return a.x*b.y-a.y*b.x;}//叉积 向量围成的平行四边形的面积
inline double Area2(const Point& a,const Point& b,Point c){return Cross(b-a,c-a);}//同上 参数为三个点
inline double DegreeToRadius(const double& deg){return deg/180*PI;}
inline double GetRerotateAngle(const Vector& a,const Vector& b){//向量a顺时针旋转theta度得到向量b的方向
    double tempa=Angle(a,Vector(1,0));
    if(a.y<0) tempa=2*PI-tempa;
    double tempb=Angle(b,Vector(1,0));
    if(b.y<0) tempb=2*PI-tempb;
    if((tempa-tempb)>0) return tempa-tempb;
    else return tempa-tempb+2*PI;
}
inline double torad(const double& deg){return deg/180*PI;}//角度化为弧度
inline Vector Rotate(const Vector& a,const double& rad){//向量逆时针旋转rad弧度
    return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
}
int ConvexHull(Point* p,int n,Point* sol){//计算凸包
    sort(p,p+n);
    int m=0;
    for(int i=0;i<n;i++){
        while(m>1&&dcmp(Cross(sol[m-1]-sol[m-2],p[i]-sol[m-2]))<=0) m--;
        sol[m++]=p[i];
    }
    int k=m;
    for(int i=n-2;i>=0;i--){
        while(m>k&&dcmp(Cross(sol[m-1]-sol[m-2],p[i]-sol[m-2]))<=0) m--;
        sol[m++]=p[i];
    }
    if(n>0) m--;
    return m;
}
int myconvexhull(Point *p,int n,Point *sol){
 sort(p,p+n);
 Vector v=Point(p[0].x-1,p[0].y)-p[0];
 int next=1;
 double tempa=0;
 for(int i=1;i<n;i++){
  Vector v1=p[i]-p[0];
  if(GetRerotateAngle(v,v1)>tempa){
   tempa=GetRerotateAngle(v,v1);
   next=i;
  }
 }
 sol[0]=p[0];
 int m=1;
 while(next!=0){
  sol[m++]=p[next];
  v=sol[m-1]-sol[m-2];
  tempa=2*PI;
  for(int i=0;i<n;i++){
   Vector v1=p[i]-sol[m-1];
   double hehe = GetRerotateAngle(v1,v);
   if(GetRerotateAngle(v1,v)<tempa){
    tempa=GetRerotateAngle(v1,v);
    next=i;
   }
  }
 }
 return m;
}
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;
}
//--------------------------------------
//--------------------------------------
//--------------------------------------
//--------------------------------------
//--------------------------------------
Point source[50],result[50];
int main()
{
 int n;
 scanf("%d",&n);
 for(int i=0;i<n;i++){
  scanf("%lf%lf",&source[i].x,&source[i].y);
 }
 int m = ConvexHull(source,n,result);
 printf("%lf\n",PolygonArea(result,m));
 int xx = myconvexhull(source,n,result);
 printf("%lf\n",PolygonArea(result,xx));
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值