1 /* =============================================================================
5 * =============================================================================
7 * Copyright (C) Stanford University, 2006. All Rights Reserved.
10 * =============================================================================
12 * For the license of bayes/sort.h and bayes/sort.c, please see the header
15 * ------------------------------------------------------------------------
17 * For the license of kmeans, please see kmeans/LICENSE.kmeans
19 * ------------------------------------------------------------------------
21 * For the license of ssca2, please see ssca2/COPYRIGHT
23 * ------------------------------------------------------------------------
25 * For the license of lib/mt19937ar.c and lib/mt19937ar.h, please see the
26 * header of the files.
28 * ------------------------------------------------------------------------
30 * For the license of lib/rbtree.h and lib/rbtree.c, please see
31 * lib/LEGALNOTICE.rbtree and lib/LICENSE.rbtree
33 * ------------------------------------------------------------------------
35 * Unless otherwise noted, the following license applies to STAMP files:
37 * Copyright (c) 2007, Stanford University
38 * All rights reserved.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions are
44 * * Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
47 * * Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in
49 * the documentation and/or other materials provided with the
52 * * Neither the name of Stanford University nor the names of its
53 * contributors may be used to endorse or promote products derived
54 * from this software without specific prior written permission.
56 * THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY
57 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
59 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE
60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
61 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
62 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
63 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
64 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
65 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
66 * THE POSSIBILITY OF SUCH DAMAGE.
68 * =============================================================================
71 public class element {
72 coordinate coordinates[];
74 coordinate circumCenter;
79 coordinate midpoints[]; /* midpoint of each edge */
80 double radii[]; /* half of edge length */
81 edge encroachedEdgePtr; /* opposite obtuse angle */
83 List_t neighborListPtr;
89 /* =============================================================================
91 * -- put smallest coordinate in position 0
92 * =============================================================================
94 void minimizeCoordinates() {
97 for (int i = 1; i < numCoordinate; i++) {
98 if (coordinate.coordinate_compare(coordinates[i], coordinates[minPosition]) < 0) {
103 while(minPosition != 0) {
104 coordinate tmp = coordinates[0];
105 for (int j = 0; j < (numCoordinate - 1); j++) {
106 coordinates[j] = coordinates[j+1];
108 coordinates[numCoordinate-1] = tmp;
114 /* =============================================================================
116 * -- Sets isSkinny to TRUE if the angle constraint is not met
117 * =============================================================================
119 void checkAngles (double angleConstraint) {
120 //double angleConstraint = global_angleConstraint;
123 yada.Assert(numCoordinate == 2 || numCoordinate == 3);
124 isReferenced = false;
126 encroachedEdgePtr = null;
128 if (numCoordinate == 3) {
130 for (i = 0; i < 3; i++) {
131 double angle = coordinate.coordinate_angle(coordinates[i],
132 coordinates[(i + 1) % 3],
133 coordinates[(i + 2) % 3]);
134 yada.Assert(angle > 0.0);
135 yada.Assert(angle < 180.0);
137 encroachedEdgePtr = edges[(i + 1) % 3];
139 if (angle < angleConstraint) {
142 if (angle < minAngle) {
146 yada.Assert(minAngle < 180.0);
151 /* =============================================================================
152 * calculateCircumCenter
154 * Given three points A(ax,ay), B(bx,by), C(cx,cy), circumcenter R(rx,ry):
157 * | by - ay (||b - a||)^2 |
159 * | cy - ay (||c - a||)^2 |
161 * rx = ax - -----------------------------
163 * | bx - ax by - ay |
165 * | cx - ax cy - ay |
169 * | bx - ax (||b - a||)^2 |
171 * | cx - ax (||c - a||)^2 |
173 * ry = ay + -----------------------------
175 * | bx - ax by - ay |
177 * | cx - ax cy - ay |
180 * =============================================================================
182 void calculateCircumCircle() {
183 coordinate circumCenterPtr = this.circumCenter;
184 yada.Assert(numCoordinate == 2 || numCoordinate == 3);
186 if (numCoordinate == 2) {
187 circumCenterPtr.x = (coordinates[0].x + coordinates[1].x) / 2.0;
188 circumCenterPtr.y = (coordinates[0].y + coordinates[1].y) / 2.0;
190 double ax = coordinates[0].x;
191 double ay = coordinates[0].y;
192 double bx = coordinates[1].x;
193 double by = coordinates[1].y;
194 double cx = coordinates[2].x;
195 double cy = coordinates[2].y;
196 double bxDelta = bx - ax;
197 double byDelta = by - ay;
198 double cxDelta = cx - ax;
199 double cyDelta = cy - ay;
200 double bDistance2 = (bxDelta * bxDelta) + (byDelta * byDelta);
201 double cDistance2 = (cxDelta * cxDelta) + (cyDelta * cyDelta);
202 double xNumerator = (byDelta * cDistance2) - (cyDelta * bDistance2);
203 double yNumerator = (bxDelta * cDistance2) - (cxDelta * bDistance2);
204 double denominator = 2 * ((bxDelta * cyDelta) - (cxDelta * byDelta));
205 double rx = ax - (xNumerator / denominator);
206 double ry = ay + (yNumerator / denominator);
207 yada.Assert(Math.fabs(denominator) > 2.2250738585072014e-308); /* make sure not colinear */
208 circumCenterPtr.x = rx;
209 circumCenterPtr.y = ry;
212 circumRadius = coordinate.coordinate_distance(circumCenterPtr,
217 /* =============================================================================
220 * Note: Makes pairPtr sorted; i.e., coordinate_compare(first, second) < 0
221 * =============================================================================
223 public void setEdge(int i) {
224 coordinate firstPtr = coordinates[i];
225 coordinate secondPtr = coordinates[(i + 1) % numCoordinate];
227 edge edgePtr = edges[i];
228 int cmp = coordinate.coordinate_compare(firstPtr, secondPtr);
229 yada.Assert(cmp != 0);
231 edgePtr.firstPtr = firstPtr;
232 edgePtr.secondPtr = secondPtr;
234 edgePtr.firstPtr = secondPtr;
235 edgePtr.secondPtr = firstPtr;
238 coordinate midpointPtr = midpoints[i];
239 midpointPtr.x = (firstPtr.x + secondPtr.x) / 2.0;
240 midpointPtr.y = (firstPtr.y + secondPtr.y) / 2.0;
242 radii[i] = coordinate.coordinate_distance(firstPtr, midpointPtr);
246 /* =============================================================================
248 * =============================================================================
250 void initEdges(coordinate[] coordinates, int numCoordinate) {
251 numEdge = ((numCoordinate * (numCoordinate - 1)) / 2);
253 for (int e = 0; e < numEdge; e++) {
259 /* =============================================================================
261 * =============================================================================
263 static int element_compare (element aElementPtr, element bElementPtr) {
264 int aNumCoordinate = aElementPtr.numCoordinate;
265 int bNumCoordinate = bElementPtr.numCoordinate;
266 coordinate aCoordinates[] = aElementPtr.coordinates;
267 coordinate bCoordinates[] = bElementPtr.coordinates;
269 if (aNumCoordinate < bNumCoordinate) {
271 } else if (aNumCoordinate > bNumCoordinate) {
275 for (int i = 0; i < aNumCoordinate; i++) {
276 int compareCoordinate =
277 coordinate.coordinate_compare(aCoordinates[i], bCoordinates[i]);
278 if (compareCoordinate != 0) {
279 return compareCoordinate;
287 /* =============================================================================
288 * element_listCompare
291 * =============================================================================
293 int element_listCompare (Object aPtr, Object bPtr) {
294 element aElementPtr = (element)aPtr;
295 element bElementPtr = (element)bPtr;
297 return element_compare(aElementPtr, bElementPtr);
301 /* =============================================================================
305 * =============================================================================
307 static int element_mapCompare(Object aPtr, Object bPtr) {
308 element aElementPtr = (element)(((edge)aPtr).firstPtr);
309 element bElementPtr = (element)(((edge)bPtr).firstPtr);
311 return element_compare(aElementPtr, bElementPtr);
315 /* =============================================================================
318 * Contains a copy of input arg 'coordinates'
319 * =============================================================================
322 double angleConstraint;
323 public element(coordinate[] coordinates, int numCoordinate, double angle) {
324 this.circumCenter=new coordinate();
325 this.coordinates=new coordinate[3];
326 this.midpoints=new coordinate[3]; /* midpoint of each edge */
327 this.radii=new double[3]; /* half of edge length */
328 this.edges=new edge[3];
329 for (int i = 0; i < 3; i++) {
330 this.midpoints[i] = new coordinate();
331 this.edges[i]=new edge();
333 for (int i = 0; i < numCoordinate; i++) {
334 this.coordinates[i] = coordinates[i];
336 this.numCoordinate = numCoordinate;
337 minimizeCoordinates();
338 this.angleConstraint=angle;
340 calculateCircumCircle();
341 initEdges(coordinates, numCoordinate);
342 neighborListPtr = new List_t(0);//TMLIST_ALLOC(element_listCompare);
344 isReferenced = false;
348 /* =============================================================================
350 * =============================================================================
352 int element_getNumEdge() {
357 /* =============================================================================
360 * Returned edgePtr is sorted; i.e., coordinate_compare(first, second) < 0
361 * =============================================================================
363 edge element_getEdge(int i) {
364 if (i < 0 || i > numEdge)
370 /* =============================================================================
371 * element_compareEdge
372 * =============================================================================
374 static int compareEdge(edge aEdgePtr, edge bEdgePtr) {
375 int diffFirst = coordinate.coordinate_compare((coordinate)aEdgePtr.firstPtr,
376 (coordinate)bEdgePtr.firstPtr);
378 return ((diffFirst != 0) ?
380 (coordinate.coordinate_compare((coordinate)aEdgePtr.secondPtr,
381 (coordinate)bEdgePtr.secondPtr)));
385 /* ============================================================================
386 * element_listCompareEdge
389 * ============================================================================
391 int element_listCompareEdge (Object aPtr, Object bPtr) {
392 edge aEdgePtr = (edge)(aPtr);
393 edge bEdgePtr = (edge)(bPtr);
395 return compareEdge(aEdgePtr, bEdgePtr);
399 /* =============================================================================
400 * element_mapCompareEdge
403 * =============================================================================
405 static int element_mapCompareEdge (edge aPtr, edge bPtr) {
406 edge aEdgePtr = (edge)(aPtr.firstPtr);
407 edge bEdgePtr = (edge)(bPtr.firstPtr);
409 return compareEdge(aEdgePtr, bEdgePtr);
413 /* =============================================================================
414 * element_heapCompare
416 * For use in heap_t. Consider using minAngle instead of "do not care".
417 * =============================================================================
419 int element_heapCompare (Object aPtr, Object bPtr) {
420 element aElementPtr = (element)aPtr;
421 element bElementPtr = (element)bPtr;
423 if (aElementPtr.encroachedEdgePtr!=null) {
424 if (bElementPtr.encroachedEdgePtr!=null) {
425 return 0; /* do not care */
431 if (bElementPtr.encroachedEdgePtr!=null) {
435 return 0; /* do not care */
439 /* =============================================================================
440 * element_isInCircumCircle
441 * =============================================================================
443 boolean element_isInCircumCircle(coordinate coordinatePtr) {
444 double distance = coordinate.coordinate_distance(coordinatePtr, circumCenter);
445 return distance <= circumRadius;
449 /* =============================================================================
451 * =============================================================================
453 boolean isEncroached() {
454 return encroachedEdgePtr!=null;
458 /* =============================================================================
459 * element_setEncroached
460 * =============================================================================
462 void element_clearEncroached() {
463 encroachedEdgePtr = null;
467 /* =============================================================================
468 * element_getEncroachedPtr
469 * =============================================================================
471 edge element_getEncroachedPtr() {
472 return encroachedEdgePtr;
476 /* =============================================================================
478 * =============================================================================
480 boolean element_isSkinny() {
485 /* =============================================================================
487 * -- Does it need to be refined?
488 * =============================================================================
490 boolean element_isBad() {
491 return (isEncroached() || element_isSkinny());
495 /* =============================================================================
496 * TMelement_isReferenced
497 * -- Held by another data structure?
498 * =============================================================================
500 boolean element_isReferenced () {
505 /* =============================================================================
506 * TMelement_setIsReferenced
507 * =============================================================================
509 void element_setIsReferenced(boolean status) {
510 isReferenced= status;
514 /* =============================================================================
516 * -- Can we deallocate?
517 * =============================================================================
520 /* =============================================================================
521 * TMelement_isGarbage
522 * -- Can we deallocate?
523 * =============================================================================
525 public boolean element_isGarbage() {
531 /* =============================================================================
532 * TMelement_setIsGarbage
533 * =============================================================================
535 void element_setIsGarbage(boolean status) {
540 /* =============================================================================
541 * TMelement_addNeighbor
542 * =============================================================================
544 void element_addNeighbor(element neighborPtr) {
545 neighborListPtr.insert(neighborPtr);
549 /* =============================================================================
550 * element_getNeighborListPtr
551 * =============================================================================
553 List_t element_getNeighborListPtr () {
554 return neighborListPtr;
558 /* =============================================================================
559 * element_getCommonEdge
561 * Returns pointer to aElementPtr's shared edge
562 * =============================================================================
564 static edge element_getCommonEdge (element aElementPtr, element bElementPtr) {
565 edge aEdges[] = aElementPtr.edges;
566 edge bEdges[] = bElementPtr.edges;
567 int aNumEdge = aElementPtr.numEdge;
568 int bNumEdge = bElementPtr.numEdge;
570 for (int a = 0; a < aNumEdge; a++) {
571 edge aEdgePtr = aEdges[a];
572 for (int b = 0; b < bNumEdge; b++) {
573 edge bEdgePtr = bEdges[b];
574 if (compareEdge(aEdgePtr, bEdgePtr) == 0) {
584 /* =============================================================================
585 * element_getNewPoint
586 * -- Either the element is encroached or is skinny, so get the new point to add
587 * =============================================================================
589 coordinate element_getNewPoint() {
590 if (encroachedEdgePtr!=null) {
591 for (int e = 0; e < numEdge; e++) {
592 if (compareEdge(encroachedEdgePtr, edges[e]) == 0) {
602 /* =============================================================================
603 * element_checkAngles
605 * Return FALSE if minimum angle constraint not met
606 * =============================================================================
608 boolean checkAngles() {
609 // double angleConstraint = global_angleConstraint;
610 if (numCoordinate == 3) {
611 for (int i = 0; i < 3; i++) {
612 double angle = coordinate.coordinate_angle(coordinates[i],
613 coordinates[(i + 1) % 3],
614 coordinates[(i + 2) % 3]);
615 if (angle < angleConstraint) {
624 /* =============================================================================
626 * =============================================================================
628 void element_print() {
629 for (int c = 0; c < numCoordinate; c++) {
630 coordinates[c].coordinate_print();
631 System.out.println(" ");
636 /* =============================================================================
638 * =============================================================================
640 void element_printEdge (edge edgePtr) {
641 ((coordinate)edgePtr.firstPtr).coordinate_print();
642 System.out.println(" -> ");
643 ((coordinate)edgePtr.secondPtr).coordinate_print();
647 /* =============================================================================
648 * element_printAngles
649 * =============================================================================
651 void element_printAngles() {
652 if (numCoordinate == 3) {
653 for (int i = 0; i < 3; i++) {
654 double angle = coordinate.coordinate_angle(coordinates[i],
655 coordinates[(i + 1) % 3],
656 coordinates[(i + 2) % 3]);
657 System.out.println(angle);