staticfinalfloat EPSILON=0.0000000001f;staticpublicfloatArea(List<PointF> contour){int n = contour.size();floatA=0.0f;for(int p=n-1,q=0; q<n; p=q++){A+= contour.get(p).x*contour.get(q).y - contour.get(q).x*contour.get(p).y;}returnA*0.5f;}/*
InsideTriangle decides if a point P is Inside of the triangle
defined by A, B, C.
*/staticpublicbooleanInsideTriangle(floatAx,floatAy,floatBx,floatBy,floatCx,floatCy,floatPx,floatPy){float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;float cCROSSap, bCROSScp, aCROSSbp;
ax =Cx-Bx; ay =Cy-By;
bx =Ax-Cx; by =Ay-Cy;
cx =Bx-Ax; cy =By-Ay;
apx=Px-Ax; apy=Py-Ay;
bpx=Px-Bx; bpy=Py-By;
cpx=Px-Cx; cpy=Py-Cy;
aCROSSbp = ax*bpy - ay*bpx;
cCROSSap = cx*apy - cy*apx;
bCROSScp = bx*cpy - by*cpx;return((aCROSSbp >=0.0f)&&(bCROSScp >=0.0f)&&(cCROSSap >=0.0f));};staticpublicbooleanSnip(List<PointF> contour,int u,int v,int w,int n,int[]V){int p;floatAx,Ay,Bx,By,Cx,Cy,Px,Py;Ax= contour.get(V[u]).x;Ay= contour.get(V[u]).y;Bx= contour.get(V[v]).x;By= contour.get(V[v]).y;Cx= contour.get(V[w]).x;Cy= contour.get(V[w]).y;if( EPSILON >(((Bx-Ax)*(Cy-Ay))-((By-Ay)*(Cx-Ax))))returnfalse;for(p=0;p<n;p++){if((p == u)||(p == v)||(p == w))continue;Px= contour.get(V[p]).x;Py= contour.get(V[p]).y;if(InsideTriangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py))returnfalse;}returntrue;}//result保存生成所有三角的点publicstaticbooleanProcess1(List<PointF> contour,List<PointF> result){/* allocate and initialize list of Vertices in polygon */int n = contour.size();if( n <3)returnfalse;int[]V=newint[n];/* we want a counter-clockwise polygon in V */if(0.0f<Area(contour))for(int v=0; v<n; v++)V[v]= v;elsefor(int v=0; v<n; v++)V[v]=(n-1)-v;int nv = n;/* remove nv-2 Vertices, creating 1 triangle every time */int count =2*nv;/* error detection */for(int m=0, v=nv-1; nv>2;){/* if we loop, it is probably a non-simple polygon */if(0>=(count--)){//** Triangulate: ERROR - probable bad polygon!returnfalse;}/* three consecutive vertices in current polygon, <u,v,w> */int u = v ;if(nv <= u) u =0;/* previous */
v = u+1;if(nv <= v) v =0;/* new v */int w = v+1;if(nv <= w) w =0;/* next */if(Snip(contour,u,v,w,nv,V)){int a,b,c,s,t;/* true names of the vertices */
a =V[u]; b =V[v]; c =V[w];/* output Triangle */
result.add( contour.get(a));
result.add( contour.get(b));
result.add( contour.get(c));
m++;/* remove v from remaining polygon */for(s=v,t=v+1;t<nv;s++,t++)V[s]=V[t]; nv--;/* resest error detection counter */
count =2*nv;}}returntrue;}//result保存所有生成的三角形的点的索引(contour 中的位置) publicstaticbooleanProcess2(List<PointF> contour,List<Integer> result){/* allocate and initialize list of Vertices in polygon */int n = contour.size();if( n <3)returnfalse;int[]V=newint[n];/* we want a counter-clockwise polygon in V */if(0.0f<Area(contour))for(int v=0; v<n; v++)V[v]= v;elsefor(int v=0; v<n; v++)V[v]=(n-1)-v;int nv = n;/* remove nv-2 Vertices, creating 1 triangle every time */int count =2*nv;/* error detection */for(int m=0, v=nv-1; nv>2;){/* if we loop, it is probably a non-simple polygon */if(0>=(count--)){//** Triangulate: ERROR - probable bad polygon!returnfalse;}/* three consecutive vertices in current polygon, <u,v,w> */int u = v ;if(nv <= u) u =0;/* previous */
v = u+1;if(nv <= v) v =0;/* new v */int w = v+1;if(nv <= w) w =0;/* next */if(Snip(contour,u,v,w,nv,V)){int a,b,c,s,t;/* true names of the vertices */
a =V[u]; b =V[v]; c =V[w];/* output Triangle */
result.add( a );
result.add( b );
result.add( c );
m++;/* remove v from remaining polygon */for(s=v,t=v+1;t<nv;s++,t++)V[s]=V[t]; nv--;/* resest error detection counter */
count =2*nv;}}returntrue;}