09343367acb9475a933ca456ef92bd6b2531bb1e
[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         exact = new HashMap<Point,V>();
18     }
19
20     public V get(Point p) {
21         return exact.get(p);
22     }
23
24     public void rebuild() {
25         HashMap<Point,V> old_exact = exact;
26         exact = new HashMap<Point,V>();
27         kd = new KDTree(3);
28         for(V v : old_exact.values()) add(v);
29     }
30
31     public void add(V v) {
32         V x = get(v.getPoint());
33         if (x != null && x.equals(v)) return;
34         if (x != null) throw new Error("duplicates!");
35         Point p = v.getPoint();
36         doubles[0] = p.x;
37         doubles[1] = p.y;
38         doubles[2] = p.z;
39         try {
40             kd.insert(doubles, v);
41         } catch (Exception e) {
42             throw new Error(e);
43         }
44         exact.put(p, v);
45     }
46
47     public void remove(HasPoint v) { remove(v.getPoint()); }
48     public void remove(Point p) {
49         doubles[0] = p.x;
50         doubles[1] = p.y;
51         doubles[2] = p.z;
52         try {
53             kd.delete(doubles);
54         } catch (Exception e) { }
55         exact.remove(p);
56     }
57
58     public V nearest(Point p) {
59         if (exact.size()==0) return null;
60         Object[] results;
61         try {
62             doubles[0] = p.x;
63             doubles[1] = p.y;
64             doubles[2] = p.z;
65             results = kd.nearest(doubles,1);
66         } catch (Exception e) {
67             throw new Error(e);
68         }
69         return (V)results[0];
70     }
71
72
73     public Vec diagonal() {
74         float min_x = Float.MAX_VALUE;
75         float min_y = Float.MAX_VALUE;
76         float min_z = Float.MAX_VALUE;
77         float max_x = Float.MIN_VALUE;
78         float max_y = Float.MIN_VALUE;
79         float max_z = Float.MIN_VALUE;
80         for(Point p : exact.keySet()) {
81             if (p.x < min_x) min_x = p.x;
82             if (p.y < min_y) min_y = p.y;
83             if (p.z < min_z) min_z = p.z;
84             if (p.x > max_x) max_x = p.x;
85             if (p.y > max_y) max_y = p.y;
86             if (p.z > max_z) max_z = p.z;
87         }
88         return new Vec(max_x - min_x, max_y - min_y, max_z - min_z);
89     }
90
91     public Point centroid() {
92         float min_x = Float.MAX_VALUE;
93         float min_y = Float.MAX_VALUE;
94         float min_z = Float.MAX_VALUE;
95         float max_x = Float.MIN_VALUE;
96         float max_y = Float.MIN_VALUE;
97         float max_z = Float.MIN_VALUE;
98         for(Point p : exact.keySet()) {
99             if (p.x < min_x) min_x = p.x;
100             if (p.y < min_y) min_y = p.y;
101             if (p.z < min_z) min_z = p.z;
102             if (p.x > max_x) max_x = p.x;
103             if (p.y > max_y) max_y = p.y;
104             if (p.z > max_z) max_z = p.z;
105         }
106         return new Point((float)(max_x + min_x)/2,
107                      (float)(max_y + min_y)/2,
108                      (float)(max_z + min_z)/2);
109     }
110 }