3b701180b0e6150fc25ae5d3ec50879bd2206d13
[anneal.git] / src / edu / berkeley / qfat / geom / PointSet.java
1 package edu.berkeley.qfat.geom;
2 import edu.wlu.cs.levy.CG.KDTree;
3 import java.util.*;
4
5 public class PointSet<V extends HasPoint> implements Iterable<V> {
6
7     private /*final*/ KDTree kd = new KDTree(3);
8     private final double[] doubles = new double[3];
9
10     private HashMap<Point,V> exact = new HashMap<Point,V>();
11
12     public Iterator<V> iterator() {
13         return exact.values().iterator();
14     }
15     public void clear() {
16         kd = new KDTree(3);
17     }
18
19     public V get(Point p) {
20         return exact.get(p);
21     }
22
23     public void add(V v) {
24         V x = get(v.getPoint());
25         if (x != null && x.equals(v)) return;
26         Point p = v.getPoint();
27         doubles[0] = p.x;
28         doubles[1] = p.y;
29         doubles[2] = p.z;
30         try {
31             kd.insert(doubles, v);
32         } catch (Exception e) {
33             throw new Error(e);
34         }
35         exact.put(p, v);
36     }
37
38     public void remove(HasPoint v) { remove(v.getPoint()); }
39     public void remove(Point p) {
40         doubles[0] = p.x;
41         doubles[1] = p.y;
42         doubles[2] = p.z;
43         try {
44             kd.delete(doubles);
45         } catch (Exception e) { }
46         exact.remove(p);
47     }
48
49     public V nearest(Point p) {
50         if (exact.size()==0) return null;
51         Object[] results;
52         try {
53             doubles[0] = p.x;
54             doubles[1] = p.y;
55             doubles[2] = p.z;
56             results = kd.nearest(doubles,1);
57         } catch (Exception e) {
58             throw new Error(e);
59         }
60         return (V)results[0];
61     }
62
63
64     public Vec diagonal() {
65         float min_x = Float.MAX_VALUE;
66         float min_y = Float.MAX_VALUE;
67         float min_z = Float.MAX_VALUE;
68         float max_x = Float.MIN_VALUE;
69         float max_y = Float.MIN_VALUE;
70         float max_z = Float.MIN_VALUE;
71         for(Point p : exact.keySet()) {
72             if (p.x < min_x) min_x = p.x;
73             if (p.y < min_y) min_y = p.y;
74             if (p.z < min_z) min_z = p.z;
75             if (p.x > max_x) max_x = p.x;
76             if (p.y > max_y) max_y = p.y;
77             if (p.z > max_z) max_z = p.z;
78         }
79         return new Vec(max_x - min_x, max_y - min_y, max_z - min_z);
80     }
81
82     public Point centroid() {
83         float min_x = Float.MAX_VALUE;
84         float min_y = Float.MAX_VALUE;
85         float min_z = Float.MAX_VALUE;
86         float max_x = Float.MIN_VALUE;
87         float max_y = Float.MIN_VALUE;
88         float max_z = Float.MIN_VALUE;
89         for(Point p : exact.keySet()) {
90             if (p.x < min_x) min_x = p.x;
91             if (p.y < min_y) min_y = p.y;
92             if (p.z < min_z) min_z = p.z;
93             if (p.x > max_x) max_x = p.x;
94             if (p.y > max_y) max_y = p.y;
95             if (p.z > max_z) max_z = p.z;
96         }
97         return new Point((float)(max_x + min_x)/2,
98                      (float)(max_y + min_y)/2,
99                      (float)(max_z + min_z)/2);
100     }
101 }