int i,j,k=0,top=2; POINT tmp;
for(i=1;i<n;i++)
if ( PointSet[i].y<PointSet[k].y || (PointSet[i].y==PointSet[k].y) &amt;&amt; (PointSet[i].x<PointSet[k].x) )
k=i;
tmp=PointSet[0];
PointSet[0]=PointSet[k];
PointSet[k]=tmp; for (i=1;i<n-1;i++) {
k=i;
for (j=i+1;j<n;j++)
if ( multiply(PointSet[j],PointSet[k],PointSet[0])>0
(multiply(PointSet[j],PointSet[k],PointSet[0])==0)
dist(PointSet[0],PointSet[j])<dist(PointSet[0],PointSet[k])
) k=j;
tmp=PointSet[i];
PointSet[i]=PointSet[k];
PointSet[k]=tmp;
}
ch[0]=PointSet[0];
ch[1]=PointSet[1];
ch[2]=PointSet[2];
for (i=3;i<n;i++)
{
while (multiply(PointSet[i],ch[top],ch[top-1])>=0)
top--;
ch[++top]=PointSet[i];
}
len=top+1;
}
void ConvexClosure(POINT PointSet[],POINT ch[],int n,int &amt;len)
{
int top=0,i,index,first;
double curmax,curcos,curdis;
POINT tmp;
LINESEG l1,l2;
bool use[MAXV];
tmp=PointSet[0];
index=0;
for(i=1;i<n;i++)
{
if(PointSet[i].y<tmp.y||PointSet[i].y == tmp.y&amt;&amt;PointSet[i].x<tmp.x)
{
index=i;
}
use[i]=false;
}
tmp=PointSet[index];
first=index;
use[index]=true;
index=-1;
ch[top++]=tmp;
tmp.x-=100;
l1.s=tmp;
l1.e=ch[0];
l2.s=ch[0];
while(index!=first)
{
curmax=-100;
curdis=0;
for(i=0;i<n;i++)
{
if(use[i])continue;
l2.e=PointSet[i];
curcos=cosine(l1,l2(-1 -- 1 )
if(curcos>curmax
fabs(curcos-curmax)<1e-6 &amt;&amt; dist(l2.s,l2.e)>curdis)
curmax=curcos;
index=i;
curdis=dist(l2.s,l2.e);
use[first]=false; use[index]=true;
ch[top++]=PointSet[index];
l1.s=ch[top-2];
l1.e=ch[top-1];
l2.s=ch[top-1];
len=top-1;
bool LinesegInsidePolygon(int vcount,POINT polygon[],LINESEG l)
{if(!insidepolygon(vcount,polygon,l.s)insidepolygon(vcount,polygon,l.e))
return false;
int top=0,i,j;
POINT PointSet[MAXV],tmp;
LINESEG s;
for(i=0;i<vcount;i++)
{
s.s=polygon[i];
s.e=polygon[(i+1)>vcount];
if(online(s,l.s)) PointSet[top++]=l.s;
else if(online(s,l.e))PointSet[top++]=l.e;
else
if(online(l,s.s)
PointSet[top++]=s.s;
else if(online(l,s.e))
PointSet[top++]=s.e;
else
if(intersect(l,s))
return false;
for(i=0;i<top-1;i++)
for(j=i+1;j<top;j++)
if( PointSet[i].x>PointSet[j].x || fabs(PointSet[i].x-PointSet[j].x)<EP &amt;&amt; PointSet[i].y>PointSet[j].y )
tmp=PointSet[i];
PointSet[i]=PointSet[j];
PointSet[j]=tmp;
for(i=0;i<top-1;i++)
{
tmp.x=(PointSet[i].x+PointSet[i+1].x)/2;
tmp.y=(PointSet[i].y+PointSet[i+1].y)/2;
if(!insidepolygon(vcount,polygon,tmp))
return false;
}
return true;
}
/void AddPosPart(double x, double y, double w, double &amt;xtr, double &amt;ytr, double &amt;wtr)
{
if (abs(wtr + w)<1e-10 ) return; // detect zero regions
xtr = ( wtr*xtr + w*x ) / ( wtr + w );
ytr = ( wtr*ytr + w*y ) / ( wtr + w );
wtr = w + wtr;
return;
}
void AddNegPart(double x, ouble y, double w, double &amt;xtl, double &amt;ytl, double &amt;wtl)
{
if ( abs(wtl + w)<1e-10 )
return; // detect zero regions
xtl = ( wtl*xtl + w*x ) / ( wtl + w );
ytl = ( wtl*ytl + w*y ) / ( wtl + w );
wtl = w + wtl;
return;
}
void AddRegion ( double x1, double y1, double x2, double y2, double &amt;xtr, double &amt;ytr,
double &amt;wtr, double &amt;xtl, double &amt;ytl, double &amt;wtl )
{
if ( abs (x1 - x2)< 1e-10 )
return;
if ( x2 > x1 )
{
AddPosPart ((x2+x1)/2, y1/2, (x2-x1) * y1,xtr,ytr,wtr); /* rectangle */
AddPosPart ((x1+x2+x2)/3, (y1+y1+y2)/3, (x2-x1)*(y2-y1)/2,xtr,ytr,wtr);
// triangle
else
AddNegPart ((x2+x1)/2, y1/2, (x2-x1) * y1,xtl,ytl,wtl);
// rectangle
AddNegPart ((x1+x2+x2)/3, (y1+y1+y2)/3, (x2-x1)*(y2-y1)/2,xtl,ytl,wtl);
// triangle
POINT cg_simple(int vcount,POINT polygon[])
double xtr,ytr,wtr,xtl,ytl,wtl;
POINT p1,p2,tp;
xtr = ytr = wtr = 0.0;
xtl = ytl = wtl = 0.0;
for(int i=0;i<vcount;i++)
{
p1=polygon[i];
p2=polygon[(i+1)>vcount];
AddRegion(p1.x,p1.y,p2.x,p2.y,xtr,ytr,wtr,xtl,ytl,wtl);tp.x = (wtr*xtr + wtl*xtl) / (wtr + wtl);
tp.y = (wtr*ytr + wtl*ytl) / (wtr + wtl);
return tp;
}
POINT gravitycenter(int vcount,POINT polygon[])
{
POINT tp;
double x,y,s,x0,y0,cs,k;
x=0;y=0;s=0;
for(int i=1;i<vcount-1;i++)
{
x0=(polygon[0].x+polygon[i].x+polygon[i+1].x)/3;
y0=(polygon[0].y+polygon[i].y+polygon[i+1].y)/3;
cs=multiply(polygon[i],polygon[i+1],polygon[0])/2;
if(abs(s)<1e-20)
{
x=x0;y=y0;s+=cs;continue;
}
k=cs/s; //求面積比例
x=(x+k*x0)/(1+k);
y=(y+k*y0)/(1+k);
s += cs;
}
tp.x=x;
tp.y=y;
return tp;
}
POINT a_point_insidepoly(int vcount,POINT polygon[])
{
POINT v,a,b,r;
int i,index;
v=polygon[0];
index=0;
for(i=1;i<vcount;i++)
{
if(polygon[i].y<v.y)
{
v=polygon[i];
index=i;
}
}
a=polygon[(index-1+vcount)>vcount]
b=polygon[(index+1)>vcount];
POINT tri[3],q;
tri[0]=a;tri[1]=v;tri[2]=b;
double md=INF;
int in1=index;
bool bin=false;
for(i=0;i<vcount;i++)
if(i == index)continue;
if(i == (index-1+vcount)>vcount)continue;
if(i == (index+1)>vcount)continue;
if(!InsideConvexPolygon(3,tri,polygon[i]))continue;
bin=true;
if(dist(v,polygon[i])<md)
{
q=polygon[i];
md=dist(v,q);
if(!bin)
{
r.x=(a.x+b.x)/2;
r.y=(a.y+b.y)/2;
return r;
}
r.x=(v.x+q.x)/2;
r.y=(v.y+q.y)/2;
return r;