From: adam Date: Mon, 26 Nov 2007 05:16:32 +0000 (-0800) Subject: add vertex normals X-Git-Url: http://git.megacz.com/?p=anneal.git;a=commitdiff_plain;h=2a27d25e38de18ff97d4c15e79f542d2f40ce25a add vertex normals darcs-hash:20071126051632-5007d-c83ba5c3433048ce9e8a77b0bf7a24d72d1759f1.gz --- diff --git a/src/Geom.java b/src/Geom.java index 1817bea..38e41f2 100644 --- a/src/Geom.java +++ b/src/Geom.java @@ -54,6 +54,7 @@ public class Geom implements Iterable { /** [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 { } 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 { 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 { 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 { 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 { // 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 */ diff --git a/src/Main.java b/src/Main.java index bd40d13..f598ac1 100644 --- a/src/Main.java +++ b/src/Main.java @@ -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();