checkpoint
[anneal.git] / src / Geom.java
index 9cc1a4c..c9404d9 100644 (file)
@@ -95,7 +95,7 @@ public class Geom implements Iterable<Geom.T> {
     public P newP(float x, float y, float z) { return new P(x, y, z); }
     
     public T newT(V p12, V p23, V p31, Vec norm) {
-        Vec norm2 = p31.minus(p12).cross(p23.minus(p12));
+        Vec norm2 = p31.p.minus(p12.p).cross(p23.p.minus(p12.p));
         float dot = norm.dot(norm2);
         //if (Math.abs(dot) < EPSILON) throw new Error("dot products within epsilon of each other: "+norm+" "+norm2);
         if (dot < 0) { V p = p12; p12=p23; p23 = p; }
@@ -115,16 +115,13 @@ public class Geom implements Iterable<Geom.T> {
         return (float)total;
     }
 
-    public P nearest(P p) {
+    public V nearest(P p) {
         Object[] results;
         try { results = kd.nearest(new double[]{p.x,p.y,p.z},1); } catch (Exception e) { throw new Error(e); }
-        return (P)results[0];
+        return (V)results[0];
     }
 
     public T newT(V p1, V p2, V p3) {
-        p1 = p1.register();
-        p2 = p2.register();
-        p3 = p3.register();
         E e12 = p1.makeE(p2);
         E e23 = p2.makeE(p3);
         E e31 = p3.makeE(p1);
@@ -140,12 +137,11 @@ public class Geom implements Iterable<Geom.T> {
         return ret;
     }
 
-    public final class V extends P {
-        public P p = this;
+    public final class V {
+        public P p;
         public V(P p) {
-            super(p.x, p.y, p.z);
-            if (ps.get(p) != null) throw new Error();
             this.p = p;
+            if (ps.get(p) != null) throw new Error();
             ps.put(this.p, this);
         }
         /*
@@ -167,9 +163,9 @@ public class Geom implements Iterable<Geom.T> {
         public float score() { return oldscore; }
         public void unscore() {
             if (watch == null) return;
-            watch.watch_x -= x;
-            watch.watch_y -= y;
-            watch.watch_z -= z;
+            watch.watch_x -= p.x;
+            watch.watch_y -= p.y;
+            watch.watch_z -= p.z;
             watch.watch_count--;
             if (watch.watch_count==0) {
                 watch.watch_x = 0;
@@ -190,23 +186,23 @@ public class Geom implements Iterable<Geom.T> {
             if (watch != null) unscore();
             V po = this;
             if (watch == null) {
-                watch = (V)score_against.nearest(po);
+                watch = score_against.nearest(po.p);
 
                 // don't attract to vertices that face the other way
                 if (watch.norm().dot(norm()) < 0) {
                     watch = null;
                 } else {
-                    watch.watch_x += po.x;
-                    watch.watch_y += po.y;
-                    watch.watch_z += po.z;
+                    watch.watch_x += po.p.x;
+                    watch.watch_y += po.p.y;
+                    watch.watch_z += po.p.z;
                     watch.watch_count++;
                 }
             }
 
             double s1, s2;
             if (watch_count==0) s1 = 0;
-            else                s1 = this.distance(watch_x/watch_count, watch_y/watch_count, watch_z/watch_count);
-            s2 = watch==null ? 0 : po.distance(watch);
+            else                s1 = p.distance(watch_x/watch_count, watch_y/watch_count, watch_z/watch_count);
+            s2 = watch==null ? 0 : po.p.distance(watch.p);
             oldscore = (float)(s1 + s2);
             score += oldscore;
         }
@@ -223,9 +219,6 @@ public class Geom implements Iterable<Geom.T> {
                 float newx = m.a*p.x + m.b*p.y + m.c*p.z + m.d;
                 float newy = m.e*p.x + m.f*p.y + m.g*p.z + m.h;
                 float newz = m.i*p.x + m.j*p.y + m.k*p.z + m.l;
-                this.x = newx;
-                this.y = newy;
-                this.z = newz;
                 this.p = new P(newx, newy, newz);
                 // FIXME: what if we move onto exactly where another point is?
                 ps.put(this.p,(V)this);
@@ -289,7 +282,6 @@ public class Geom implements Iterable<Geom.T> {
         }
 
         public E getE(V p2) {
-            p2 = p2.register();
             E e = this.e;
             do {
                 if (e==null) return null;
@@ -300,7 +292,6 @@ public class Geom implements Iterable<Geom.T> {
         }
 
         public boolean isBoundTo(V p) {
-            p = p.register();
             V px = p;
             do {
                 if (px==this) return true;
@@ -312,7 +303,6 @@ public class Geom implements Iterable<Geom.T> {
         public void unbind() { bound_to = this; binding = new M(); }
         public void bind(V p) { bind(p, new M()); }
         public void bind(V p, M binding) {
-            p = p.register();
             if (isBoundTo(p)) return;
             V temp_bound_to = p.bound_to;
             M temp_binding = p.binding;
@@ -405,11 +395,11 @@ public class Geom implements Iterable<Geom.T> {
     public final class E implements Comparable<E> {
 
         public boolean intersects(T t) {
-            double A0=t.p1().x, A1=t.p1().y, A2=t.p1().z;
-            double B0=t.p2().x, B1=t.p2().y, B2=t.p2().z;
-            double C0=t.p3().x, C1=t.p3().y, C2=t.p3().z;
-            double j0=p1.x, j1=p1.y, j2=p1.z;
-            double k0=p2.x, k1=p2.y, k2=p2.z;
+            double A0=t.p1().p.x, A1=t.p1().p.y, A2=t.p1().p.z;
+            double B0=t.p2().p.x, B1=t.p2().p.y, B2=t.p2().p.z;
+            double C0=t.p3().p.x, C1=t.p3().p.y, C2=t.p3().p.z;
+            double j0=p1.p.x, j1=p1.p.y, j2=p1.p.z;
+            double k0=p2.p.x, k1=p2.p.y, k2=p2.p.z;
             double J0, J1, J2;
             double K0, K1, K2;
             double i0, i1, i2;
@@ -502,7 +492,6 @@ public class Geom implements Iterable<Geom.T> {
         boolean shattered = false;
         public V shatter() { return shatter(midpoint().register(), null, null); }
         public V shatter(V mid, BindingGroup bg1, BindingGroup bg2) {
-            mid = mid.register();
             if (shattered) return mid;
             shattered = true;
 
@@ -572,8 +561,8 @@ public class Geom implements Iterable<Geom.T> {
 
         /** angle between this half-edge and the next */
         public double angle() {
-            Vec v1 = next.p2.minus(p2);
-            Vec v2 = this.p1.minus(p2);
+            Vec v1 = next.p2.p.minus(p2.p);
+            Vec v2 = this.p1.p.minus(p2.p);
             return Math.acos(v1.norm().dot(v2.norm()));
         }
 
@@ -599,8 +588,6 @@ public class Geom implements Iterable<Geom.T> {
 
         /** creates an isolated edge out in the middle of space */
         public E(V p1, V p2) {
-            p1 = p1.register();
-            p2 = p2.register();
             if (p1==p2) throw new Error("attempt to create edge with single vertex: " + p1);
             this.p1 = p1;
             this.p2 = p2;
@@ -610,7 +597,6 @@ public class Geom implements Iterable<Geom.T> {
 
         /** adds a new half-edge from prev.p2 to p2 */
         public E(E prev, V p2) {
-            p2 = p2.register();
             this.p1 = prev.p2;
             this.p2 = p2;
             this.prev = prev;
@@ -637,12 +623,9 @@ public class Geom implements Iterable<Geom.T> {
             this.pair = pair;
             sync();
         }
-        public P midpoint() { return newP((p1.x+p2.x)/2, (p1.y+p2.y)/2, (p1.z+p2.z)/2).register(); }
-        public boolean has(P p) {
-            p = p.register();
-            return p==p1 || p==p2;
-        }
-        public float length() { return p1.minus(p2).mag(); }
+        public P midpoint() { return newP((p1.p.x+p2.p.x)/2, (p1.p.y+p2.p.y)/2, (p1.p.z+p2.p.z)/2); }
+        public boolean has(V v) { return v==p1 || v==p2; }
+        public float length() { return p1.p.minus(p2.p).mag(); }
         public String toString() { return p1+"->"+p2; }
     }
 
@@ -655,10 +638,10 @@ public class Geom implements Iterable<Geom.T> {
             ts.remove(this);
         }
 
-        public P nearest(P p) {
-            float d1 = p1().distance(p);
-            float d2 = p2().distance(p);
-            float d3 = p3().distance(p);
+        public V nearest(P p) {
+            float d1 = p1().p.distance(p);
+            float d2 = p2().p.distance(p);
+            float d3 = p3().p.distance(p);
             if (d1 < d2 && d1 < d3) return p1();
             if (d2 < d3) return p2();
             return p3();
@@ -701,23 +684,23 @@ public class Geom implements Iterable<Geom.T> {
         public E e1() { return e1; }
         public E e2() { return e1.next; }
         public E e3() { return e1.prev; }
-        public Vec norm() { return p2().minus(p1()).cross(p3().minus(p1())).norm(); }
+        public Vec norm() { return p2().p.minus(p1().p).cross(p3().p.minus(p1().p)).norm(); }
         public boolean hasE(E e) { return e1==e || e1.next==e || e1.prev==e; }
-        public boolean has(P p) { return p1()==p || p2()==p || p3()==p; }
+        public boolean has(V v) { return p1()==v || p2()==v || p3()==v; }
 
         public float area() {
-            return (float)Math.abs(0.5 * e1().length() * new Vec(p1(), p2()).norm().dot(new Vec(p2(), p3())));
+            return (float)Math.abs(0.5 * e1().length() * new Vec(p1().p, p2().p).norm().dot(new Vec(p2().p, p3().p)));
         }
 
         public void glVertices(GL gl) {
-            p1().glVertex(gl);
-            p2().glVertex(gl);
-            p3().glVertex(gl);
+            p1().p.glVertex(gl);
+            p2().p.glVertex(gl);
+            p3().p.glVertex(gl);
         }
 
-        public P centroid() { return newP((p1().x+p2().x+p3().x)/3,
-                                          (p1().y+p2().y+p3().y)/3, 
-                                          (p1().z+p2().z+p3().z)/3); }
+        public P centroid() { return newP((p1().p.x+p2().p.x+p3().p.x)/3,
+                                          (p1().p.y+p2().p.y+p3().p.y)/3, 
+                                          (p1().p.z+p2().p.z+p3().p.z)/3); }
         public float diameter() {
             // FIXME: what is this supposed to be?
             return Math.max(Math.max(e1().length(), e2().length()), e3().length()) / 2;