X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=src%2FGeom.java;h=9c639e153179dd42a7b1f85fb671d3b181dbc7d0;hb=a18e40f15c9b054cdd16c3a5416a36a10033b632;hp=c879bfed1acb27b5d8b5423d2253ef6fb8e93732;hpb=8a19e3f30ae67231e204c28d5ec93e5a6d812861;p=anneal.git diff --git a/src/Geom.java b/src/Geom.java index c879bfe..9c639e1 100644 --- a/src/Geom.java +++ b/src/Geom.java @@ -5,23 +5,45 @@ import javax.swing.*; import javax.media.opengl.*; import javax.media.opengl.glu.*; -public class Geom { +public class Geom implements Iterable { private HashMap ps = new HashMap(); + private HashMap es = new HashMap(); + private HashSet ts = new HashSet(); + + public Iterator iterator() { return ts.iterator(); } public P newP(float x, float y, float z) { P p = new P(x, y, z); P p2 = ps.get(p); if (p2 != null) return p2; - ps.put(p, p); + ps.put(p,p); return p; } + + public E newE(P p1, P p2) { + E e = new E(p1, p2); + E e2 = es.get(e); + if (e2 != null) return e2; + es.put(e,e); + return e; + } + + public T newT(E e1, E e2, E e3) { + if (e1.t1 != null && e1.t1.hasE(e1) && e1.t1.hasE(e2) && e1.t1.hasE(e3)) return e1.t1; + if (e1.t2 != null && e1.t2.hasE(e1) && e1.t2.hasE(e2) && e1.t2.hasE(e3)) return e1.t2; + if (e2.t1 != null && e2.t1.hasE(e1) && e2.t1.hasE(e2) && e2.t1.hasE(e3)) return e2.t1; + if (e2.t2 != null && e2.t2.hasE(e1) && e2.t2.hasE(e2) && e2.t2.hasE(e3)) return e2.t2; + if (e3.t1 != null && e3.t1.hasE(e1) && e3.t1.hasE(e2) && e3.t1.hasE(e3)) return e3.t1; + if (e3.t2 != null && e3.t2.hasE(e1) && e3.t2.hasE(e2) && e3.t2.hasE(e3)) return e3.t2; + return new T(e1, e2, e3); + } - /** point in 3-space */ - public class P { + /** [UNIQUE] point in 3-space */ + public final class P { public final float x, y, z; public P(float x, float y, float z) { this.x = x; this.y = y; this.z = z; } - public V minus(P p) { return null; } + public V minus(P p) { return new V(x-p.x, y-p.y, z-p.z); } public boolean equals(Object o) { if (o==null || !(o instanceof P)) return false; P p = (P)o; @@ -33,22 +55,25 @@ public class Geom { Float.floatToIntBits(y) ^ Float.floatToIntBits(z); } + public void glVertex(GL gl) { gl.glVertex3f(x, y, z); } } /** vector in 3-space */ - public class V { + public final class V { private final float x, y, z; public V(float x, float y, float z) { this.x = x; this.y = y; this.z = z; } - public V norm() { return null; /* FIXME */ } public boolean sameDirection(V v) { throw new Error(); } - public V cross(V v) { return null; } + 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); } + public float mag() { return (float)Math.sqrt(x*x+y*y+z*z); } + public V norm() { float m = mag(); return new V(x/m, y/m, z/m); } } - /** an edge */ - public class E { + /** [UNIQUE] an edge */ + public final class E { public final P p1, p2; - private T t1, t2; + T t1, t2; public E(P p1, P p2) { this.p1 = p1; this.p2 = p2; } + public int hashCode() { return p1.hashCode() ^ p2.hashCode(); } public boolean equals(Object o) { if (o==null || !(o instanceof E)) return false; E e = (E)o; @@ -56,11 +81,24 @@ public class Geom { if (this.p2 == e.p1 && this.p1 == e.p2) return true; return false; } - public P shared(E e) { return null; } + public P shared(E e) { + if (p1==e.p1) return p1; + if (p1==e.p2) return p1; + if (p2==e.p1) return p2; + if (p2==e.p2) return p2; + throw new Error("no shared vertex in shared()"); + } + public P unshared(E e) { + if (p1==e.p1) return p2; + if (p1==e.p2) return p2; + if (p2==e.p1) return p1; + if (p2==e.p2) return p1; + throw new Error("no shared vertex in unshared()"); + } } - /** a triangle (face) */ - public class T { + /** [UNIQUE] a triangle (face) */ + public final class T { public final E e1, e2, e3; public T(E e1, E e2, E e3, V normal) { P p1 = e1.shared(e2); @@ -76,6 +114,10 @@ public class Geom { this.e2 = e2; this.e3 = e1; } + if (e1.t1 == null) e1.t1 = this; else if (e1.t2 == null) e1.t2 = this; else throw new Error("non-manifold surface"); + if (e2.t1 == null) e2.t1 = this; else if (e2.t2 == null) e2.t2 = this; else throw new Error("non-manifold surface"); + if (e3.t1 == null) e3.t1 = this; else if (e3.t2 == null) e3.t2 = this; else throw new Error("non-manifold surface"); + ts.add(this); } public V norm() { P p1 = e1.shared(e2); @@ -83,7 +125,21 @@ public class Geom { P p3 = e3.shared(e1); return p2.minus(p1).cross(p3.minus(p1)).norm(); } - public T(E e1, E e2, E e3) { this.e1 = e1; this.e2 = e2; this.e3 = e3; } + public T(E e1, E e2, E e3) { + this.e1 = e1; + this.e2 = e2; + this.e3 = e3; + if (e1.t1 == null) e1.t1 = this; else if (e1.t2 == null) e1.t2 = this; else throw new Error("non-manifold surface"); + if (e2.t1 == null) e2.t1 = this; else if (e2.t2 == null) e2.t2 = this; else throw new Error("non-manifold surface"); + if (e3.t1 == null) e3.t1 = this; else if (e3.t2 == null) e3.t2 = this; else throw new Error("non-manifold surface"); + ts.add(this); + } + public boolean hasE(E e) { return e1==e || e2==e || e3==e; } + public void glVertices(GL gl) { + e1.unshared(e2).glVertex(gl); + e1.shared(e2).glVertex(gl); + e2.shared(e3).glVertex(gl); + } } /** matrix */