2 * A class that represents a voronoi diagram. The diagram is represnted as a
3 * binary tree of points.
5 class Vertex extends Vec2 {
7 * The left child of the tree that represents the voronoi diagram.
11 * The right child of the tree that represents the voronoi diagram.
16 * Seed value used during tree creation.
23 public Vertex(double x, double y) {
29 public void setLeft(Vertex l) {
33 public void setRight(Vertex r) {
37 public Vertex getLeft() {
41 public Vertex getRight() {
46 * Generate a voronoi diagram
48 static Vertex createPoints(int n, MyDouble curmax, int i) {
53 Vertex cur = new Vertex();
55 Vertex right = Vertex.createPoints(n / 2, curmax, i);
57 cur.x = curmax.value * Math.exp(Math.log(Vertex.drand()) / i);
59 // cur.y = Vertex.drand();
60 cur.norm = cur.x * cur.x + cur.y * cur.y;
62 curmax.value = cur.X();
63 Vertex left = Vertex.createPoints(n / 2, curmax, i - 1);
70 * Builds delaunay triangulation.
72 Edge buildDelaunayTriangulation(Vertex extra, int depth) {
73 EdgePair retVal = buildDelaunay(extra, depth);
74 return retVal.getLeft();
77 EdgePair buildDelaunaySerial(Vertex extra) {
79 EdgePair retval = null;
80 if (getRight() != null && getLeft() != null) {
81 // more than three elements; do recursion
82 Vertex minx = getLow();
85 EdgePair delright = getRight().buildDelaunay(extra);
86 EdgePair delleft = getLeft().buildDelaunay(this);
90 e.doMerge(delleft.getLeft(), delleft.getRight(), delright.getLeft(), delright.getRight());
92 Edge ldo = retval.getLeft();
93 while (ldo.orig() != minx) {
96 Edge rdo = retval.getRight();
97 while (rdo.orig() != maxx) {
101 retval = new EdgePair(ldo, rdo);
103 } else if (getLeft() == null) {
105 Edge a = makeEdge(this, extra);
106 retval = new EdgePair(a, a.symmetric());
108 // left, !right three points
109 // 3 cases: triangles of 2 orientations, and 3 points on a line. */
110 Vertex s1 = getLeft();
114 Edge a = makeEdge(s1, s2);
115 Edge b = makeEdge(s2, s3);
116 a.symmetric().splice(b);
117 Edge c = b.connectLeft(a);
118 if (s1.ccw(s3, s2)) {
119 retval = new EdgePair(c.symmetric(), c);
121 retval = new EdgePair(a, b.symmetric());
129 EdgePair buildDelaunay(Vertex extra, int depth) {
131 EdgePair retval = null;
134 return buildDelaunaySerial(extra);
137 if (getRight() != null && getLeft() != null) {
138 // more than three elements; do recursion
139 Vertex minx = getLow();
143 EdgePair delright = getRight().buildDelaunay(extra,depth);
145 EdgePair delleft = getLeft().buildDelaunay(this,depth);
149 e.doMerge(delleft.getLeft(), delleft.getRight(), delright.getLeft(), delright.getRight());
151 Edge ldo = retval.getLeft();
152 while (ldo.orig() != minx) {
155 Edge rdo = retval.getRight();
156 while (rdo.orig() != maxx) {
160 retval = new EdgePair(ldo, rdo);
162 } else if (getLeft() == null) {
164 Edge a = makeEdge(this, extra);
165 retval = new EdgePair(a, a.symmetric());
167 // left, !right three points
168 // 3 cases: triangles of 2 orientations, and 3 points on a line. */
169 Vertex s1 = getLeft();
172 Edge a = makeEdge(s1, s2);
173 Edge b = makeEdge(s2, s3);
174 a.symmetric().splice(b);
175 Edge c = b.connectLeft(a);
176 if (s1.ccw(s3, s2)) {
177 retval = new EdgePair(c.symmetric(), c);
179 retval = new EdgePair(a, b.symmetric());
190 * Recursive delaunay triangulation procedure Contains modifications for
191 * axis-switching division.
193 EdgePair buildDelaunay(Vertex extra) {
194 EdgePair retval = null;
195 if (getRight() != null && getLeft() != null) {
196 // more than three elements; do recursion
197 Vertex minx = getLow();
200 EdgePair delright = getRight().buildDelaunay(extra);
201 EdgePair delleft = getLeft().buildDelaunay(this);
205 e.doMerge(delleft.getLeft(), delleft.getRight(), delright.getLeft(), delright.getRight());
207 Edge ldo = retval.getLeft();
208 while (ldo.orig() != minx) {
211 Edge rdo = retval.getRight();
212 while (rdo.orig() != maxx) {
216 retval = new EdgePair(ldo, rdo);
218 } else if (getLeft() == null) {
220 Edge a = makeEdge(this, extra);
221 retval = new EdgePair(a, a.symmetric());
223 // left, !right three points
224 // 3 cases: triangles of 2 orientations, and 3 points on a line. */
225 Vertex s1 = getLeft();
228 Edge a = makeEdge(s1, s2);
229 Edge b = makeEdge(s2, s3);
230 a.symmetric().splice(b);
231 Edge c = b.connectLeft(a);
232 if (s1.ccw(s3, s2)) {
233 retval = new EdgePair(c.symmetric(), c);
235 retval = new EdgePair(a, b.symmetric());
247 Vertex tleft, tright;
249 System.out.println("X=" + X() + " Y=" + Y());
251 System.out.println("NULL");
255 System.out.println("NULL");
261 * Traverse down the left child to the end
267 while ((temp = tree.getLeft()) != null)
272 /****************************************************************/
274 * Geometric primitives
275 * **************************************************************
277 boolean incircle(Vertex b, Vertex c, Vertex d)
278 /* incircle, as in the Guibas-Stolfi paper. */
280 double adx, ady, bdx, bdy, cdx, cdy, dx, dy, anorm, bnorm, cnorm, dnorm;
282 Vertex loc_a, loc_b, loc_c, loc_d;
284 int donedx, donedy, donednorm;
288 dnorm = loc_d.Norm();
290 adx = loc_a.X() - dx;
291 ady = loc_a.Y() - dy;
292 anorm = loc_a.Norm();
294 bdx = loc_b.X() - dx;
295 bdy = loc_b.Y() - dy;
296 bnorm = loc_b.Norm();
298 cdx = loc_c.X() - dx;
299 cdy = loc_c.Y() - dy;
300 cnorm = loc_c.Norm();
301 dret = (anorm - dnorm) * (bdx * cdy - bdy * cdx);
302 dret += (bnorm - dnorm) * (cdx * ady - cdy * adx);
303 dret += (cnorm - dnorm) * (adx * bdy - ady * bdx);
304 return ((0.0 < dret) ? true : false);
307 boolean ccw(Vertex b, Vertex c)
308 /* TRUE iff this, B, C form a counterclockwise oriented triangle */
311 double xa, ya, xb, yb, xc, yc;
312 Vertex loc_a, loc_b, loc_c;
314 int donexa, doneya, donexb, doneyb, donexc, doneyc;
325 dret = (xa - xc) * (yb - yc) - (xb - xc) * (ya - yc);
326 return ((dret > 0.0) ? true : false);
330 * A routine used by the random number generator
332 static int mult(int p, int q) {
334 int CONST_m1 = 10000;
340 return (((p0 * q1 + p1 * q0) % CONST_m1) * CONST_m1 + p0 * q0);
344 * Generate the nth random number
346 static int skiprand(int seed, int n) {
352 static int random(int seed) {
353 int CONST_b = 31415821;
355 seed = mult(seed, CONST_b) + 1;
359 static double drand() {
360 double retval = ((double) (Vertex.seed = Vertex.random(Vertex.seed))) / (double) 2147483647;
364 public Edge makeEdge(Vertex o, Vertex d) {
365 Edge ql[] = new Edge[4];
366 ql[0] = new Edge(ql, 0);
367 ql[1] = new Edge(ql, 1);
368 ql[2] = new Edge(ql, 2);
369 ql[3] = new Edge(ql, 3);