3 * A class that represents the quad edge data structure which implements
4 * the edge algebra as described in the algorithm.
6 * Each edge contains 4 parts, or other edges. Any edge in the group may
7 * be accessed using a series of rotate and flip operations. The 0th
8 * edge is the canonical representative of the group.
10 * The quad edge class does not contain separate information for vertice
11 * or faces; a vertex is implicitly defined as a ring of edges (the ring
12 * is created using the next field).
17 * Group of edges that describe the quad edge
21 * The position of this edge within the quad list
25 * The vertex that this edge represents
29 * Contains a reference to a connected quad edge
37 * Create a new edge which.
39 public Edge(Vertex v, Edge ql[], int pos)
47 * Create a new edge which.
49 public Edge(Edge ql[], int pos)
55 * Create a string representation of the edge
57 /*public String toString()
60 return vertex.toString();
65 public Edge makeEdge(Vertex o, Vertex d)
67 Edge ql[] = new Edge[4];
68 ql[0] = new Edge(ql, 0);
69 ql[1] = new Edge(ql, 1);
70 ql[2] = new Edge(ql, 2);
71 ql[3] = new Edge(ql, 3);
84 public void setNext(Edge n)
90 * Initialize the data (vertex) for the edge's origin
92 public void setOrig(Vertex o)
98 * Initialize the data (vertex) for the edge's destination
100 public void setDest(Vertex d)
102 symmetric().setOrig(d);
112 return this.rotate().oNext().rotate();
117 return this.rotateInv().oNext().rotate();
122 return this.oNext().symmetric();
127 return this.rotate().oNext().rotateInv();
132 return this.symmetric().oNext();
137 return this.symmetric().oNext().symmetric();
142 return this.rotateInv().oNext().rotateInv();
152 return symmetric().orig();
156 * Return the symmetric of the edge. The symmetric is the same edge
157 * with the opposite direction.
158 * @return the symmetric of the edge
162 return quadList[(listPos+2)%4];
166 * Return the rotated version of the edge. The rotated version is a
167 * 90 degree counterclockwise turn.
168 * @return the rotated version of the edge
172 return quadList[(listPos+1)%4];
176 * Return the inverse rotated version of the edge. The inverse
177 * is a 90 degree clockwise turn.
178 * @return the inverse rotated edge.
182 return quadList[(listPos+3)%4];
187 return quadList[(listPos+1)%4];
190 Edge connectLeft(Edge b)
199 ans = e.makeEdge(t1, t2);
201 ans.symmetric().splice(b);
205 Edge connectRight(Edge b)
215 ans = e.makeEdge(t1, t2);
216 ans.splice(symmetric());
217 ans.symmetric().splice(oprevb);
221 /****************************************************************/
222 /* Quad-edge manipulation primitives
223 ****************************************************************/
227 Edge syme = symmetric();
228 Edge b = syme.oPrev();
231 Edge lnexttmp = a.lNext();
233 lnexttmp = b.lNext();
234 syme.splice(lnexttmp);
235 Vertex a1 = a.dest();
236 Vertex b1 = b.dest();
243 Edge alpha = oNext().rotate();
244 Edge beta = b.oNext().rotate();
245 Edge t1 = beta.oNext();
246 Edge temp = alpha.oNext();
255 boolean valid(Edge basel)
257 Vertex t1 = basel.orig();
258 Vertex t3 = basel.dest();
260 return t1.ccw(t2, t3);
267 f = symmetric().oPrev();
268 symmetric().splice(f);
271 EdgePair doMerge(Edge ldo, Edge ldi, Edge rdi, Edge rdo)
273 boolean torun = true;
275 Vertex t3 = rdi.orig();
276 Vertex t1 = ldi.orig();
277 Vertex t2 = ldi.dest();
279 while (t1.ccw(t2, t3)) {
288 if (t2.ccw(t3, t1)) {
296 Edge basel = rdi.symmetric().connectLeft(ldi);
298 Edge lcand = basel.rPrev();
299 Edge rcand = basel.oPrev();
300 Vertex t1 = basel.orig();
301 Vertex t2 = basel.dest();
303 if (t1 == rdo.orig())
305 if (t2 == ldo.orig())
306 ldo = basel.symmetric();
309 Edge t = lcand.oNext();
310 if (t.valid(basel)) {
311 Vertex v4 = basel.orig();
313 Vertex v1 = lcand.dest();
314 Vertex v3 = lcand.orig();
315 Vertex v2 = t.dest();
316 while (v1.incircle(v2,v3,v4)){
328 if (t.valid(basel)) {
329 Vertex v4 = basel.dest();
330 Vertex v1 = t.dest();
331 Vertex v2 = rcand.dest();
332 Vertex v3 = rcand.orig();
333 while (v1.incircle(v2,v3,v4)) {
343 boolean lvalid = lcand.valid(basel);
345 boolean rvalid = rcand.valid(basel);
346 if ((!lvalid) && (!rvalid)) {
347 return new EdgePair(ldo, rdo);
350 Vertex v1 = lcand.dest();
351 Vertex v2 = lcand.orig();
352 Vertex v3 = rcand.orig();
353 Vertex v4 = rcand.dest();
354 if (!lvalid || (rvalid && v1.incircle(v2,v3,v4))) {
355 basel = rcand.connectLeft(basel.symmetric());
356 rcand = basel.symmetric().lNext();
358 basel = lcand.connectRight(basel).symmetric();
359 lcand = basel.rPrev();