checkpoint
[anneal.git] / src / edu / berkeley / qfat / geom / PointSet.java
1 package edu.berkeley.qfat.geom;
2 import java.util.*;
3
4 /** a set of points, plus many useful methods operating over the set */
5 public class PointSet<V extends HasPoint> implements Iterable<V> {
6
7     private RTree<V> rtree = new RTree<V>();
8
9     private HashMap<Point,V> exact = new HashMap<Point,V>();
10
11     public int size() { return exact.size(); }
12
13     public Iterator<V> iterator() { return rtree.iterator(); }
14
15     public void clear() {
16         exact.clear();
17         rtree = new RTree<V>();
18     }
19
20     public V get(Point p) {
21         return exact.get(p);
22     }
23
24     public void add(V v) {
25         V x = get(v.getPoint());
26         if (x != null && x.equals(v)) return;
27         if (x != null) throw new Error("duplicates!");
28         Point p = v.getPoint();
29         rtree.insert(v);
30         exact.put(p, v);
31     }
32
33     public void remove(V v) {
34         Point p = v.getPoint();
35         rtree.remove(v);
36         exact.remove(p);
37     }
38
39     public V nearest(Point p) { return nearest(p, null); }
40     public V nearest(Point p, Visitor<V> vis) {
41         if (exact.size()==0) return null;
42         return rtree.nearest(p, vis);
43     }
44
45     public Vec diagonal() {
46         float min_x = Float.MAX_VALUE;
47         float min_y = Float.MAX_VALUE;
48         float min_z = Float.MAX_VALUE;
49         float max_x = Float.MIN_VALUE;
50         float max_y = Float.MIN_VALUE;
51         float max_z = Float.MIN_VALUE;
52         for(V v : this) {
53             Point p = v.getPoint();
54             if (p.x < min_x) min_x = p.x;
55             if (p.y < min_y) min_y = p.y;
56             if (p.z < min_z) min_z = p.z;
57             if (p.x > max_x) max_x = p.x;
58             if (p.y > max_y) max_y = p.y;
59             if (p.z > max_z) max_z = p.z;
60         }
61         return new Vec(max_x - min_x, max_y - min_y, max_z - min_z);
62     }
63
64     // FEATURE: compute incrementally?
65     public Point centroid() {
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(V v : this) {
73             Point p = v.getPoint();
74             if (p.x < min_x) min_x = p.x;
75             if (p.y < min_y) min_y = p.y;
76             if (p.z < min_z) min_z = p.z;
77             if (p.x > max_x) max_x = p.x;
78             if (p.y > max_y) max_y = p.y;
79             if (p.z > max_z) max_z = p.z;
80         }
81         return new Point((float)(max_x + min_x)/2,
82                      (float)(max_y + min_y)/2,
83                      (float)(max_z + min_z)/2);
84     }
85 }