版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Game_Acm/article/details/82624087
//符号判断
int sgn( double x )
{
if ( fabs(x)<eps ) return 0;
if ( x<0 ) return -1;
if ( x>0 ) return 1;
}
//点类定义
struct Point
{
double x,y;
Point(){}
Point( double _x , double _y )
{
x = _x; y = _y;
}
Point operator -( const Point&b )const
{
return Point( x-b.x , y-b.y );
}
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 CalcArea( Point p[] , int n )
{
double res = 0;
for ( int i=0 ; i<n ; i++ )
res += p[i]^p[i+1];
if ( res<0 ) res = -res;
return 0.5*res;
}
//两点确定直线方程
void Get_equation( Point p1 , Point p2 , double &a , double &b , double &c )
{
a = p2.y-p1.y;
b = p1.x-p2.x;
c = p2.x*p1.y-p1.x*p2.y;
}
//求交点
Point Intersection( Point p1 , Point p2 , double &a , double &b , double &c )
{
double u = fabs(a*p1.x+b*p1.y+c);
double v = fabs(a*p2.x+b*p2.y+c);
Point t;
t.x = (p1.x*v+p2.x*u)/(u+v);
t.y = (p1.y*v+p2.y*u)/(u+v);
return t;
}
Point tp[110];
void Cut( double a , double b , double c , Point p[] , int &cnt )
{
int tmp = 0;
for ( int i=1 ; i<=cnt ; i++ )
{
//逆时针写法,顺时针写法a*p[i].x+b*p[i].y+c>-eps
if(a*p[i].x+b*p[i].y+c<eps) tp[++tmp] = p[i];
else
{
//逆时针写法,顺时针写法a*p[i-1].x+b*p[i-1].y+c>eps
if ( a*p[i-1].x+b*p[i-1].y+c<-eps )
tp[++tmp] = Intersection( p[i-1] , p[i] , a , b , c );
//逆时针写法,顺时针写法a*p[i+1].x+b*p[i+1].y+c>eps
if ( a*p[i+1].x+b*p[i+1].y+c<-eps )
tp[++tmp] = Intersection( p[i] , p[i+1] , a , b , c );
}
}
for ( int i=1 ; i<=tmp ; i++ ) p[i] = tp[i];
p[0] = p[tmp],p[tmp+1] = p[1],cnt = tmp;
}
int n; Point s[110],p[110];
bool solve()
{
//逆时针写法,顺时针改成顺时针
p[1] = Point( -inf , -inf );
p[2] = Point( +inf , -inf );
p[3] = Point( +inf , +inf );
p[4] = Point( -inf , +inf );
p[0] = p[4];
p[5] = p[1];
int cnt = 4;
for ( int i=n-1 ; i>=0 ; i-- )
{
//两点转方程
double a,b,c; Get_equation( s[i] , s[(i-1+n)%n] , a , b , c );
if ( sgn(a)==0&&sgn(b)==0 )
{
//逆时针写法,顺时针写法sgn(c)<=0
if ( sgn(c)>=0 ) return false;
else continue;
}
Cut( a , b , c , p , cnt );
}
//判核写法,若判唯一解(要求最后多边形面积>0)
if ( cnt==0 ) return false;
else return true;
}