add vertex normals
authoradam <adam@megacz.com>
Mon, 26 Nov 2007 05:16:32 +0000 (21:16 -0800)
committeradam <adam@megacz.com>
Mon, 26 Nov 2007 05:16:32 +0000 (21:16 -0800)
darcs-hash:20071126051632-5007d-c83ba5c3433048ce9e8a77b0bf7a24d72d1759f1.gz

src/Geom.java
src/Main.java

index 1817bea..38e41f2 100644 (file)
@@ -54,6 +54,7 @@ public class Geom implements Iterable<Geom.T> {
     /** [UNIQUE] point in 3-space */
     public final class P {
         public final float x, y, z;
+        private T t = null;  // any of the triangles incident at this point
         public P(float x, float y, float z) { this.x = x; this.y = y; this.z = z; }
         public V minus(P p) { return new V(x-p.x, y-p.y, z-p.z); }
         public P plus(V v) { return newP(x+v.x, y+v.y, z+v.z); }
@@ -70,6 +71,16 @@ public class Geom implements Iterable<Geom.T> {
         }
         public void glVertex(GL gl) { gl.glVertex3f(x, y, z); }
         public String toString() { return "("+x+","+y+","+z+")"; }
+        public V norm() {
+            if (t==null) throw new Error("attempt to get vertex normal for point which does not belong to any triangles");
+            T ti = t;
+            V norm = new V(0, 0, 0);
+            do {
+                norm = norm.plus(ti.norm().times((float)ti.angle(this)));
+                ti = ti.next(this);
+            } while(ti != t);
+            return norm.norm();
+        }
     }
 
     /** vector in 3-space */
@@ -77,6 +88,7 @@ public class Geom implements Iterable<Geom.T> {
         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 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 V plus(V v) { return new V(x+v.x, y+v.y, z+v.z); }
         public V norm() { float m = mag(); return new V(x/m, y/m, z/m); }
         public float mag() { return (float)Math.sqrt(x*x+y*y+z*z); }
         public float dot(V v) { return x*v.x + y*v.y + z*v.z; }
@@ -112,6 +124,16 @@ public class Geom implements Iterable<Geom.T> {
             if (p2==e.p2) return p1;
             throw new Error("no shared vertex in unshared()");
         }
+        public T other(T t) {
+            if (t1==t) return t2;
+            if (t2==t) return t1;
+            throw new Error("edge " + this + " does not own triangle " + t);
+        }
+        public P other(P p) {
+            if (p==p1) return p2;
+            if (p==p2) return p1;
+            throw new Error("edge " + this + " does not own point " + p);
+        }
     }
 
     /** [UNIQUE] a triangle (face) */
@@ -124,6 +146,12 @@ public class Geom implements Iterable<Geom.T> {
             return p2.minus(p1).cross(p3.minus(p1)).norm();
         }
         T(E e1, E e2, E e3) {
+            if (e1.p1.t==null) e1.p1.t = this;
+            if (e1.p2.t==null) e1.p2.t = this;
+            if (e2.p1.t==null) e2.p1.t = this;
+            if (e2.p2.t==null) e2.p2.t = this;
+            if (e3.p1.t==null) e3.p1.t = this;
+            if (e3.p2.t==null) e3.p2.t = this;
             this.e1 = e1;
             this.e2 = e2;
             this.e3 = e3;
@@ -147,6 +175,32 @@ public class Geom implements Iterable<Geom.T> {
             // FIXME: what is this supposed to be?
             return Math.max(Math.max(e1.length(), e2.length()), e3.length()) / 2;
         }
+
+        // FIXME: ambiguity firstEdge or secondEdge?
+        /** returns the next triangle walking "around" shared vertex p */
+        public T next(P p) { return secondEdge(p).other(this); }
+
+        public E firstEdge(P p) {
+            if      (p == e1.shared(e2)) return e1;
+            else if (p == e2.shared(e3)) return e2;
+            else if (p == e3.shared(e1)) return e3;
+            else throw new Error("triangle " + this + " does not own point " + p);
+        }
+
+        public E secondEdge(P p) {
+            if      (p == e1.shared(e2)) return e2;
+            else if (p == e2.shared(e3)) return e3;
+            else if (p == e3.shared(e1)) return e1;
+            else throw new Error("triangle " + this + " does not own point " + p);
+        }
+
+        /** returns the angle at point p */
+        public double angle(P p) {
+            V v1 = firstEdge(p).other(p).minus(p);
+            V v2 = secondEdge(p).other(p).minus(p);
+            return Math.acos(v1.norm().dot(v2.norm()));
+        }
+
     }
 
     /** matrix */
index bd40d13..f598ac1 100644 (file)
@@ -59,8 +59,12 @@ public class Main implements GLEventListener {
 
             Geom.P centroid = t.centroid();
             gl.glBegin(GL.GL_LINES);
+            /*
             centroid.glVertex(gl);
             centroid.plus(t.norm().times(t.diameter())).glVertex(gl);
+            */
+            t.p1().glVertex(gl);
+            t.p1().plus(t.p1().norm().times(t.diameter())).glVertex(gl);
             gl.glEnd();