checkpoint
[anneal.git] / src / Geom.java
1 import java.awt.*;
2 import java.util.*;
3 import java.awt.event.*;
4 import javax.swing.*;
5 import javax.media.opengl.*;
6 import javax.media.opengl.glu.*;
7
8 public class Geom implements Iterable<Geom.T> {
9
10     private HashMap<P,P> ps = new HashMap<P,P>();
11     private HashMap<E,E> es = new HashMap<E,E>();
12     private HashSet<T> ts = new HashSet<T>();
13
14     public Iterator<T> iterator() { return ts.iterator(); }
15
16     public P newP(float x, float y, float z) {
17         P p = new P(x, y, z);
18         P p2 = ps.get(p);
19         if (p2 != null) return p2;
20         ps.put(p,p);
21         return p;
22     }
23     
24     public E newE(P p1, P p2) {
25         E e = new E(p1, p2);
26         E e2 = es.get(e);
27         if (e2 != null) return e2;
28         es.put(e,e);
29         return e;
30     }
31
32     public T newT(E e1, E e2, E e3) {
33         if (e1.t1 != null && e1.t1.hasE(e1) && e1.t1.hasE(e2) && e1.t1.hasE(e3)) return e1.t1;
34         if (e1.t2 != null && e1.t2.hasE(e1) && e1.t2.hasE(e2) && e1.t2.hasE(e3)) return e1.t2;
35         if (e2.t1 != null && e2.t1.hasE(e1) && e2.t1.hasE(e2) && e2.t1.hasE(e3)) return e2.t1;
36         if (e2.t2 != null && e2.t2.hasE(e1) && e2.t2.hasE(e2) && e2.t2.hasE(e3)) return e2.t2;
37         if (e3.t1 != null && e3.t1.hasE(e1) && e3.t1.hasE(e2) && e3.t1.hasE(e3)) return e3.t1;
38         if (e3.t2 != null && e3.t2.hasE(e1) && e3.t2.hasE(e2) && e3.t2.hasE(e3)) return e3.t2;
39         return new T(e1, e2, e3);
40     }
41
42     /** point in 3-space */
43     public final class P {
44         public final float x, y, z;
45         public P(float x, float y, float z) { this.x = x; this.y = y; this.z = z; }
46         public V minus(P p) { return null; }
47         public boolean equals(Object o) {
48             if (o==null || !(o instanceof P)) return false;
49             P p = (P)o;
50             return p.x==x && p.y==y && p.z==z;
51         }
52         public int hashCode() {
53             return
54                 Float.floatToIntBits(x) ^
55                 Float.floatToIntBits(y) ^
56                 Float.floatToIntBits(z);
57         }
58         public void glVertex(GL gl) { gl.glVertex3f(x, y, z); }
59     }
60
61     /** vector in 3-space */
62     public final class V {
63         private final float x, y, z;
64         public V(float x, float y, float z) { this.x = x; this.y = y; this.z = z; }
65         public V norm() { return null; /* FIXME */ }
66         public boolean sameDirection(V v) { throw new Error(); }
67         public V cross(V v) { return null; }
68     }
69
70     /** an edge */
71     public final class E {
72         public final P p1, p2;
73         T t1, t2;
74         public E(P p1, P p2) { this.p1 = p1; this.p2 = p2; }
75         public int hashCode() { return p1.hashCode() ^ p2.hashCode(); }
76         public boolean equals(Object o) {
77             if (o==null || !(o instanceof E)) return false;
78             E e = (E)o;
79             if (this.p1 == e.p1 && this.p2 == e.p2) return true;
80             if (this.p2 == e.p1 && this.p1 == e.p2) return true;
81             return false;
82         }
83         public P shared(E e) {
84             if (p1==e.p1) return p1;
85             if (p1==e.p2) return p1;
86             if (p2==e.p1) return p2;
87             if (p2==e.p2) return p2;
88             throw new Error("no shared vertex in shared()");
89         }
90         public P unshared(E e) {
91             if (p1==e.p1) return p2;
92             if (p1==e.p2) return p2;
93             if (p2==e.p1) return p1;
94             if (p2==e.p2) return p1;
95             throw new Error("no shared vertex in unshared()");
96         }
97     }
98
99     /** a triangle (face) */
100     public final class T {
101         public final E e1, e2, e3;
102         public T(E e1, E e2, E e3, V normal) {
103             P p1 = e1.shared(e2);
104             P p2 = e2.shared(e3);
105             P p3 = e3.shared(e1);
106             V norm = p2.minus(p1).cross(p3.minus(p1));
107             if (norm.sameDirection(normal)) {
108                 this.e1 = e1;
109                 this.e2 = e2;
110                 this.e3 = e3;
111             } else {
112                 this.e1 = e3;
113                 this.e2 = e2;
114                 this.e3 = e1;
115             }
116             if (e1.t1 == null) e1.t1 = this; else if (e1.t2 == null) e1.t2 = this; else throw new Error("non-manifold surface");
117             if (e2.t1 == null) e2.t1 = this; else if (e2.t2 == null) e2.t2 = this; else throw new Error("non-manifold surface");
118             if (e3.t1 == null) e3.t1 = this; else if (e3.t2 == null) e3.t2 = this; else throw new Error("non-manifold surface");
119             ts.add(this);
120         }
121         public V norm() {
122             P p1 = e1.shared(e2);
123             P p2 = e2.shared(e3);
124             P p3 = e3.shared(e1);
125             return p2.minus(p1).cross(p3.minus(p1)).norm();
126         }
127         public T(E e1, E e2, E e3) {
128             this.e1 = e1;
129             this.e2 = e2;
130             this.e3 = e3;
131             if (e1.t1 == null) e1.t1 = this; else if (e1.t2 == null) e1.t2 = this; else throw new Error("non-manifold surface");
132             if (e2.t1 == null) e2.t1 = this; else if (e2.t2 == null) e2.t2 = this; else throw new Error("non-manifold surface");
133             if (e3.t1 == null) e3.t1 = this; else if (e3.t2 == null) e3.t2 = this; else throw new Error("non-manifold surface");
134             ts.add(this);
135         }
136         public boolean hasE(E e) { return e1==e || e2==e || e3==e; }
137
138         // technically not required
139         /*
140         public int hashCode() { return e1.hashCode() ^ e2.hashCode() ^ e3.hashCode(); }
141         public boolean equals(Object o) {
142             if (o==null || !(o instanceof T)) return false;
143             T t = (T)o;
144             if (this.e1 == t.e1 && this.e2 == t.e2 && this.e3 == t.e3) return true;
145             if (this.e1 == t.e2 && this.e2 == t.e3 && this.e3 == t.e1) return true;
146             if (this.e1 == t.e3 && this.e2 == t.e1 && this.e3 == t.e2) return true;
147             return false;
148         }
149         */
150         public void glVertices(GL gl) {
151             e1.unshared(e2).glVertex(gl);
152             e1.shared(e2).glVertex(gl);
153             e2.shared(e3).glVertex(gl);
154         }
155     }
156
157     /** matrix */
158     public class M {
159     }
160
161 }