3 import java.awt.event.*;
5 import javax.media.opengl.*;
6 import javax.media.opengl.glu.*;
8 public class Geom implements Iterable<Geom.T> {
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>();
14 public Iterator<T> iterator() { return ts.iterator(); }
16 public P newP(float x, float y, float z) {
19 if (p2 != null) return p2;
24 public E newE(P p1, P p2) {
27 if (e2 != null) return e2;
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);
42 /** [UNIQUE] 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 new V(x-p.x, y-p.y, z-p.z); }
47 public boolean equals(Object o) {
48 if (o==null || !(o instanceof P)) return false;
50 return p.x==x && p.y==y && p.z==z;
52 public int hashCode() {
54 Float.floatToIntBits(x) ^
55 Float.floatToIntBits(y) ^
56 Float.floatToIntBits(z);
58 public void glVertex(GL gl) { gl.glVertex3f(x, y, z); }
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 boolean sameDirection(V v) { throw new Error(); }
66 public V cross(V v) { return new V(y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x); }
67 public float mag() { return (float)Math.sqrt(x*x+y*y+z*z); }
68 public V norm() { float m = mag(); return new V(x/m, y/m, z/m); }
71 /** [UNIQUE] an edge */
72 public final class E {
73 public final P p1, p2;
75 public E(P p1, P p2) { this.p1 = p1; this.p2 = p2; }
76 public int hashCode() { return p1.hashCode() ^ p2.hashCode(); }
77 public boolean equals(Object o) {
78 if (o==null || !(o instanceof E)) return false;
80 if (this.p1 == e.p1 && this.p2 == e.p2) return true;
81 if (this.p2 == e.p1 && this.p1 == e.p2) return true;
84 public P shared(E e) {
85 if (p1==e.p1) return p1;
86 if (p1==e.p2) return p1;
87 if (p2==e.p1) return p2;
88 if (p2==e.p2) return p2;
89 throw new Error("no shared vertex in shared()");
91 public P unshared(E e) {
92 if (p1==e.p1) return p2;
93 if (p1==e.p2) return p2;
94 if (p2==e.p1) return p1;
95 if (p2==e.p2) return p1;
96 throw new Error("no shared vertex in unshared()");
100 /** [UNIQUE] a triangle (face) */
101 public final class T {
102 public final E e1, e2, e3;
103 public T(E e1, E e2, E e3, V normal) {
104 P p1 = e1.shared(e2);
105 P p2 = e2.shared(e3);
106 P p3 = e3.shared(e1);
107 V norm = p2.minus(p1).cross(p3.minus(p1));
108 if (norm.sameDirection(normal)) {
117 if (e1.t1 == null) e1.t1 = this; else if (e1.t2 == null) e1.t2 = this; else throw new Error("non-manifold surface");
118 if (e2.t1 == null) e2.t1 = this; else if (e2.t2 == null) e2.t2 = this; else throw new Error("non-manifold surface");
119 if (e3.t1 == null) e3.t1 = this; else if (e3.t2 == null) e3.t2 = this; else throw new Error("non-manifold surface");
123 P p1 = e1.shared(e2);
124 P p2 = e2.shared(e3);
125 P p3 = e3.shared(e1);
126 return p2.minus(p1).cross(p3.minus(p1)).norm();
128 public T(E e1, E e2, E e3) {
132 if (e1.t1 == null) e1.t1 = this; else if (e1.t2 == null) e1.t2 = this; else throw new Error("non-manifold surface");
133 if (e2.t1 == null) e2.t1 = this; else if (e2.t2 == null) e2.t2 = this; else throw new Error("non-manifold surface");
134 if (e3.t1 == null) e3.t1 = this; else if (e3.t2 == null) e3.t2 = this; else throw new Error("non-manifold surface");
137 public boolean hasE(E e) { return e1==e || e2==e || e3==e; }
138 public void glVertices(GL gl) {
139 e1.unshared(e2).glVertex(gl);
140 e1.shared(e2).glVertex(gl);
141 e2.shared(e3).glVertex(gl);