// 点是否在菱形内 bool GlobalManager::isPointInDiamond(Vec2 centerPoint, CCSize size, Vec2 p) { Vec2 p1 = centerPoint + Vec2(0, size.height/2); Vec2 p2 = centerPoint + Vec2(size.width/2, 0); Vec2 p3 = centerPoint + Vec2(0, -size.height/2); Vec2 p4 = centerPoint + Vec2(-size.width/2, 0); bool a = xmult(p, p2, p1) > 0; bool b = xmult(p, p3, p2) > 0; bool c = xmult(p, p4, p3) > 0; bool d = xmult(p, p1, p4) > 0; return (a == b) && (a == c) && (a == d); }
bool CSeriGraph::insertSegCircle(CPoint c,int r,CPoint l1,CPoint l2) //判断线段是否与圆相交 { double t1=distance(c,l1); //求线段两点到圆心的距离 double t2=distance(c,l2); if(fabs(t1-r)<=eps||fabs(t2-r)<=eps) return true; CPoint tmp=c; tmp.x+=l1.y-l2.y; tmp.y+=l2.x-l1.x; if(xmult(l1,c,tmp)*xmult(l2,c,tmp)<=eps&&disptoline(c,l1,l2)-r<=eps) return true; return false; }
int graham(int n,point* p,point* convex,int maxsize=1,int dir=1){ //point* temp=new point[n]; int s,i; _graham(n,p,s,temp); for (convex[0]=temp[0],n=1,i=(dir?1:(s-1));dir?(i<s):i;i+=(dir?1:-1)) if (maxsize||!zero(xmult(temp[i-1],temp[i],temp[(i+1)%s]))) convex[n++]=temp[i]; //delete []temp; return n; }
int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int t; scanf("%d",&t); while(t--) { scanf("%d",&n); int pos=0; for(int i=0;i<n;i++) { scanf("%d %lf %lf",&number[i],&p[i].x,&p[i].y); if(p[pos].y>p[i].y) pos=i; } printf("%d %d",n,number[pos]); memset(vis,0,sizeof(vis)); vis[pos]=1; point last=p[pos]; for(int i=1;i<n;i++) { double dist; for(int j=0;j<n;j++) if(!vis[j]) { pos=j; break; } for(int j=pos+1;j<n;j++) { if(vis[j])continue; double tmp=xmult(p[pos],p[j],last); double tmpdist=distances(last,p[j]); if(tmp<-eps || (zero(tmp) && tmpdist<dist)) { pos=j; dist=tmpdist; } } printf(" %d",number[pos]); vis[pos]=1; last=p[pos]; } printf("\n"); } return 0; }
void _graham(int n,point* p,int& s,point* ch){ int i,k=0; for (p1=p2=p[0],i=1;i<n;p2.x+=p[i].x,p2.y+=p[i].y,i++) if (p1.y-p[i].y>eps||(zero(p1.y-p[i].y)&&p1.x>p[i].x)) p1=p[k=i]; p2.x/=n,p2.y/=n; p[k]=p[0],p[0]=p1; qsort(p+1,n-1,sizeof(point),graham_cp); for (ch[0]=p[0],ch[1]=p[1],ch[2]=p[2],s=i=3;i<n;ch[s++]=p[i++]) for (;s>2&&xmult(ch[s-2],p[i],ch[s-1])<-eps;s--); }
//多边形重心 point barycenter(int n,point* p){ point ret,t; double t1=0,t2; int i; ret.x=ret.y=0; for (i=1;i<n-1;i++) if (fabs(t2=xmult(p[0],p[i],p[i+1]))>eps){ t=barycenter(p[0],p[i],p[i+1]); ret.x+=t.x*t2; ret.y+=t.y*t2; t1+=t2; } if (fabs(t1)>eps) ret.x/=t1,ret.y/=t1; return ret; }
//判点在任意多边形内,顶点按顺时针或逆时针给出 //on_edge表示点在多边形边上时的返回值,offset为多边形坐标上限 int inside_polygon(point q,int n,point* p,int on_edge=1){ point q2; int i=0,count; while (i<n) for (count=i=0,q2.x=rand()+offset,q2.y=rand()+offset;i<n;i++) if (zero(xmult(q,p[i],p[(i+1)%n]))&&(p[i].x-q.x)*(p[(i+1)%n].x-q.x)<eps&&(p[i].y-q.y)*(p[(i+1)%n].y-q.y)<eps) return on_edge; else if (zero(xmult(q,q2,p[i]))) break; else if (xmult(q,p[i],q2)*xmult(q,p[(i+1)%n],q2)<-eps&&xmult(p[i],q,p[(i+1)%n])*xmult(p[i],q2,p[(i+1)%n])<-eps) count++; return count&1; }
int main() { int n; bool flag; double ans; while (scanf("%d", &n) != EOF && n > 0) { for (int i = 0; i < n; i++) { scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].z); } ans = 0; for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { for (int k = j + 1; k < n; k++) { Point dn = xmult(p[j] - p[i], p[k] - p[i]); ss = 0; flag = true; for (int t = 0; t < n; t++) { s[t] = sign(dmult(dn, p[t] - p[i])); if (s[t] != 0) { if (ss == 0) { ss = s[t]; } else if (ss != s[t]) { flag = false; break; } } } if (flag) { ans += abs(dn); } } } } printf("%.0lf\n", ans / 2); } return 0; }
inline int opposite_side(point p1,point p2,point l1,point l2){ return xmult(l1,p1,l2)*xmult(l1,p2,l2)<-eps; }
//判点在凸多边形内,顶点按顺时针或逆时针给出,在多边形边上返回0 int inside_convex_v2(point q,int n,point* p){ int i,s[3]={1,1,1}; for (i=0;i<n&&s[0]&&s[1]|s[2];i++) s[_sign(xmult(p[(i+1)%n],q,p[i]))]=0; return s[0]&&s[1]|s[2]; }
//判点是否在线段上,包括端点和部分重合 int dot_online_in(point p,line l){ return !xmult(p,l.a,l.b)&&(l.a.x-p.x)*(l.b.x-p.x)<=0&&(l.a.y-p.y)*(l.b.y-p.y)<=0; }
int dot_online_in(point p,point l1,point l2){ return !xmult(p,l1,l2)&&(l1.x-p.x)*(l2.x-p.x)<=0&&(l1.y-p.y)*(l2.y-p.y)<=0; }
//判定凸多边形,顶点按顺时针或逆时针给出,允许相邻边共线 int is_convex(int n,point* p){ int i,s[3]={1,1,1}; for (i=0;i<n&&s[1]|s[2];i++) s[_sign(xmult(p[(i+1)%n],p[(i+2)%n],p[i]))]=0; return s[1]|s[2]; }
//判两点在直线同侧,点在直线上返回0 int same_side(point p1,point p2,line l){ return sign(xmult(l.a,p1,l.b))*xmult(l.a,p2,l.b)>0; }
int dot_online_in(int x,int y,int x1,int y1,int x2,int y2){ return !xmult(x,y,x1,y1,x2,y2)&&(x1-x)*(x2-x)<=0&&(y1-y)*(y2-y)<=0; }
int dots_inline(int x1,int y1,int x2,int y2,int x3,int y3){ return !xmult(x1,y1,x2,y2,x3,y3); }
int graham_cp(const void* a,const void* b){ double ret=xmult(*((point*)a),*((point*)b),p1); return zero(ret)?(xmult(*((point*)a),*((point*)b),p2)>0?1:-1):(ret>0?1:-1); }
int dots_inline(point p1,point p2,point p3){ return zero(xmult(p1,p2,p3)); }
int same_side(point p1,point p2,point l1,point l2){ return xmult(l1,p1,l2)*xmult(l1,p2,l2)>eps; }
/* 判两点在线段同侧,点在线段上返回0 */ int same_side(struct point p1,struct point p2,struct point l1,struct point l2){ return xmult(l1,p1,l2)*xmult(l1,p2,l2)>eps; }
int same_side(point p1,point p2,point l1,point l2){ return sign(xmult(l1,p1,l2))*xmult(l1,p2,l2)>0; }
//判两点在直线异侧,点在直线上返回0 int opposite_side(point p1,point p2,line l){ return sign(xmult(l.a,p1,l.b))*xmult(l.a,p2,l.b)<0; }
double CSeriGraph::disptoline(CPoint p,CPoint l1,CPoint l2) //点到直线的距离 { return fabs((double)xmult(p,l1,l2))/distance(l1,l2); }
int opposite_side(point p1,point p2,point l1,point l2){ return sign(xmult(l1,p1,l2))*xmult(l1,p2,l2)<0; }
/* 判三点共线 */ int dots_inline(struct point p1,struct point p2,struct point p3){ return zero(xmult(p1,p2,p3)); }
inline double polygon_area(point p[],int n) { double ans=0; for(int i=0;i<n;i++)ans+=xmult(p[i],p[(i+1)%n],O); return fabs(ans/2); }
int dot_online_in(point p,point l1,point l2){ return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps; }
double ptoline(point3 p,line3 l) { return vlen(xmult(subt(p,l.a),subt(l.b,l.a)))/dist3(l.a,l.b); }
double disptoline(point p,point l1,point l2) { return fabs(xmult(p,l1,l2))/distance(l1,l2); }
double ptoline(point3 p,point3 l1,point3 l2) { return vlen(xmult(subt(p,l1),subt(l2,l1)))/dist3(l1,l2); }