/** * Triangulate a simple polygon that may have zero or more holes in it. * There is no requirement for the polygon to be concave, but it will be * limited to two-dimensional coordinate systems. If you have a polygon * in 3 dimensions, you will need to project it to 2 dimensions before * calling this method. * <p> * Each part of the polygon is defined by a set of contour points. The * outer-most set of points must be defined in counter-clockwise order. * All inner points must be defined in clock-wise order. * */ public void triangulatePolygon2D(int numContours, int[] contourCounts, float[] vertices, int[] triangles) { if(holeTriangulator == null) holeTriangulator = new SeidelTriangulator(); holeTriangulator.triangulatePolygon(numContours, contourCounts, vertices, triangles); }
private void constructTrapezoids(int nseg) { // Add the first segment and get the query structure and trapezoid // list initialised int root = initQueryStructure(chooseSegment()); for(int i = 1; i <= nseg; i++) segments[i].root0 = segments[i].root1 = root; int ls_n = logStarN(nseg); for(int h = 1; h <= ls_n; h++) { for(int i = nRatio(nseg, h - 1) + 1; i <= nRatio(nseg, h); i++) addSegment(chooseSegment()); /* Find a new root for each of the segment endpoints */ for(int i = 1; i <= nseg; i++) findNewRoots(i); } for(int i = nRatio(nseg, ls_n) + 1; i <= nseg; i++) addSegment(chooseSegment()); }
if(greaterThan(v, rptr.yVal)) // above ret_val = locateEndpoint(v, vo, rptr.rightChild); else if(equalsEpsilon(v, rptr.yVal)) if(greaterThan(vo, rptr.yVal)) // above ret_val = locateEndpoint(v, vo, rptr.rightChild); else ret_val = locateEndpoint(v, vo, rptr.leftChild); // below ret_val = locateEndpoint(v, vo, rptr.leftChild); // below break; if(equalsEpsilon(v, segments[rptr.segmentIndex].v0) || equalsEpsilon(v, segments[rptr.segmentIndex].v1)) if(equalsEpsilon(v.y, vo.y)) // horizontal segment ret_val = locateEndpoint(v, vo, rptr.leftChild); else ret_val = locateEndpoint(v, vo, rptr.rightChild); else if(isLeftOf(rptr.segmentIndex, vo)) ret_val = locateEndpoint(v, vo, rptr.leftChild); else ret_val = locateEndpoint(v, vo, rptr.rightChild); else if(isLeftOf(rptr.segmentIndex, v)) ret_val = locateEndpoint(v, vo, rptr.leftChild); else
if(greaterThan(s.v1, s.v0)) // Get higher vertex in v0 if((is_swapped) ? !inserted(segnum, false) : !inserted(segnum, true)) int tu = locateEndpoint(s.v0, s.v1, s.root0); int tl = newTrapezoid(); // tl is the new lower trapezoid trapezoidList[tl].valid = true; trapezoidList[tl] = trapezoidList[tu]; int i1 = newNode(); // Upper trapezoid sink int i2 = newNode(); // Lower trapezoid sink int sk = trapezoidList[tu].sink; tfirst = locateEndpoint(s.v0, s.v1, s.root0); if((is_swapped) ? !inserted(segnum, true) : !inserted(segnum, false)) int tu = locateEndpoint(s.v1, s.v0, s.root1); int tl = newTrapezoid(); // tl is the new lower trapezoid trapezoidList[tl].valid = true; trapezoidList[tl] = trapezoidList[tu]; int i1 = newNode(); // Upper trapezoid sink int i2 = newNode(); // Lower trapezoid sink int sk = trapezoidList[tu].sink; tlast = locateEndpoint(s.v1, s.v0, s.root1);
monotoneChain[p].marked = true; if(greaterThan(vertexChain[v].point, ymax)) if(lessThan(vertexChain[v].point, ymin)) if(equalsEpsilon(vertexChain[v].point, ymin)) op_idx = triangulateSinglePolygon(nvert, posmax, false, op_idx = triangulateSinglePolygon(nvert, posmax, true,
initialise(i - 1); constructTrapezoids(i - 1); int nmonpoly = monotonateTrapezoids(i - 1); triangulateMonotonePolygons(i - 1, nmonpoly, triangles);
int mnew = newMonotone(); int ip = getVertexPosition(v0, v1); int iq = getVertexPosition(v1, v0); int i = newChainElement(); // for the new list int j = newChainElement();
double area; if(greaterThan(s.v1, s.v0)) /* seg. going upwards */ if(equalsEpsilon(s.v1.y, v.y)) area = -1; else if(equalsEpsilon(s.v0.y, v.y)) area = tripleCross(s.v0, s.v1, v); if(equalsEpsilon(s.v1.y, v.y)) area = -1; else if(equalsEpsilon(s.v0.y, v.y)) area = tripleCross(s.v1, s.v0, v);
int mnew = makeNewMonotonePoly(mcur, v1, v0); traversePolygon(mcur, t.d1, trapezoidIndex, true); traversePolygon(mnew, t.d0, trapezoidIndex, true); int mnew = makeNewMonotonePoly(mcur, v0, v1); traversePolygon(mcur, t.d0, trapezoidIndex, true); traversePolygon(mnew, t.d1, trapezoidIndex, true); traversePolygon(mcur, t.u0, trapezoidIndex, false); traversePolygon(mcur, t.u1, trapezoidIndex, false); traversePolygon(mcur, t.d0, trapezoidIndex, true); traversePolygon(mcur, t.d1, trapezoidIndex, true); int mnew = makeNewMonotonePoly(mcur, v1, v0); traversePolygon(mcur, t.u1, trapezoidIndex, false); traversePolygon(mnew, t.u0, trapezoidIndex, false); int mnew = makeNewMonotonePoly(mcur, v0, v1); traversePolygon(mcur, t.u0, trapezoidIndex, false); traversePolygon(mnew, t.u1, trapezoidIndex, false); traversePolygon(mcur, t.u0, trapezoidIndex, false); traversePolygon(mcur, t.u1, trapezoidIndex, false); traversePolygon(mcur, t.d0, trapezoidIndex, true); traversePolygon(mcur, t.d1, trapezoidIndex, true); int mnew = makeNewMonotonePoly(mcur, v1, v0); traversePolygon(mcur, t.u1, trapezoidIndex, false); traversePolygon(mcur, t.d1, trapezoidIndex, true);
private int min(Point2d yval, Point2d v0, Point2d v1) { if(v0.y < v1.y - EPSILON) yval.set(v0); else if(equalsEpsilon(v0.y, v1.y)) { if(v0.x < v1.x) yval.set(v0); else yval.set(v1); } else yval.set(v1); return 0; }
/** * Check to see if the trapezoid lies inside the polygon. * * @param t The trapezoid to test against the polygon * @return true if the trapezoid lies completely inside the polygon */ private boolean insidePolygon(SeidelTrapezoid t) { if((!t.valid) || ((t.leftSegment <= 0) || (t.rightSegment <= 0))) return false; if(((t.u0 <= 0) && (t.u1 <= 0)) || ((t.d0 <= 0) && (t.d1 <= 0))) { int rseg = t.rightSegment; return greaterThan(segments[rseg].v1, segments[rseg].v0); } return false; }
/** * (v0, v1) is the new diagonal to be added to the polygon. Find which * chain to use and return the positions of v0 and v1 in p and q */ private int getVertexPosition(int v0, int v1) { SeidelVertexChain vp0 = vertexChain[v0]; SeidelVertexChain vp1 = vertexChain[v1]; // p is identified as follows. Scan from (v0, v1) rightwards till // you hit the first segment starting from v0. That chain is the // chain of our interest double angle = -4.0; int ret_val = 0; for(int i = 0; i < 4; i++) { if(vp0.nextVertex[i] <= 0) continue; double temp = getAngle(vp0.point, vertexChain[vp0.nextVertex[i]].point, vp1.point); if(temp > angle) { angle = temp; ret_val = i; } } return ret_val; }
while((t > 0) && greaterThanOrEqualTo(trapezoidList[t].lo, trapezoidList[tlast].lo))
/** * Return the maximum of the two points into the yval structure */ private int max(Point2d yval, Point2d v0, Point2d v1) { if(v0.y > v1.y + EPSILON) yval.set(v0); else if(equalsEpsilon(v0.y, v1.y)) { if(v0.x > v1.x + EPSILON) yval.set(v0); else yval.set(v1); } else yval.set(v1); return 0; }