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