sorta works in a half-crippled way
authoradam <adam@megacz.com>
Tue, 18 Dec 2007 03:59:10 +0000 (19:59 -0800)
committeradam <adam@megacz.com>
Tue, 18 Dec 2007 03:59:10 +0000 (19:59 -0800)
darcs-hash:20071218035910-5007d-0f47aa3740c6325930ef161778239cd60e38f532.gz

src/edu/berkeley/qfat/Main.java
src/edu/berkeley/qfat/Mesh.java
src/edu/berkeley/qfat/MeshViewer.java
src/edu/berkeley/qfat/geom/HasBindingGroup.java
src/edu/berkeley/qfat/geom/Matrix.java
src/edu/berkeley/qfat/geom/Point.java

index 12a82fc..75bfd7e 100644 (file)
@@ -86,17 +86,18 @@ public class Main extends MeshViewer {
         float halfup = 0;
 
         translations = new Matrix[] {
-
             Matrix.translate(new Vec(lshift,  depth,    halfup)),
+            /*
             Matrix.translate(new Vec(rshift,  depth,    halfup)),
             Matrix.translate(new Vec(lshift, -depth,    halfup)),
             Matrix.translate(new Vec(rshift, -depth,    halfup)),
+            */
 
             /*
               Matrix.translate(new Vec(0,  depth,    halfup)),
               Matrix.translate(new Vec(0, -depth,    halfup)),
             */
-
+            /*
             Matrix.translate(new Vec(lshift,       0,  height)),
             Matrix.translate(new Vec(rshift,       0,  height)),
             Matrix.translate(new Vec(lshift,       0, -height)),
@@ -105,7 +106,7 @@ public class Main extends MeshViewer {
 
             Matrix.translate(new Vec( width,           0,    0)),
             Matrix.translate(new Vec(-width,           0,    0)),
-
+            */
         };
 
         //   
@@ -214,23 +215,23 @@ public class Main extends MeshViewer {
                     if ((t1.v1().p.times(m).minus(t2.v1().p).mag() < Mesh.EPSILON) &&
                         (t1.v2().p.times(m).minus(t2.v3().p).mag() < Mesh.EPSILON) &&
                         (t1.v3().p.times(m).minus(t2.v2().p).mag() < Mesh.EPSILON)) {
-                        t1.e1().bindEdge(t2.e3());
-                        t1.e2().bindEdge(t2.e2());
-                        t1.e3().bindEdge(t2.e1());
+                        t2.e3().bindEdge(t1.e1(), m);
+                        t2.e2().bindEdge(t1.e2(), m);
+                        t2.e1().bindEdge(t1.e3(), m);
                     }
                     if ((t1.v2().p.times(m).minus(t2.v1().p).mag() < Mesh.EPSILON) &&
                         (t1.v3().p.times(m).minus(t2.v3().p).mag() < Mesh.EPSILON) &&
                         (t1.v1().p.times(m).minus(t2.v2().p).mag() < Mesh.EPSILON)) {
-                        t1.e2().bindEdge(t2.e3());
-                        t1.e3().bindEdge(t2.e2());
-                        t1.e1().bindEdge(t2.e1());
+                        t2.e3().bindEdge(t1.e2(), m);
+                        t2.e2().bindEdge(t1.e3(), m);
+                        t2.e1().bindEdge(t1.e1(), m);
                     }
                     if ((t1.v3().p.times(m).minus(t2.v1().p).mag() < Mesh.EPSILON) &&
                         (t1.v1().p.times(m).minus(t2.v3().p).mag() < Mesh.EPSILON) &&
                         (t1.v2().p.times(m).minus(t2.v2().p).mag() < Mesh.EPSILON)) {
-                        t1.e3().bindEdge(t2.e3());
-                        t1.e1().bindEdge(t2.e2());
-                        t1.e2().bindEdge(t2.e1());
+                        t2.e3().bindEdge(t1.e3(), m);
+                        t2.e2().bindEdge(t1.e1(), m);
+                        t2.e1().bindEdge(t1.e2(), m);
                     }
 
                 }
@@ -282,7 +283,8 @@ public class Main extends MeshViewer {
             verts++;
             //System.out.println("shatter " + e);
             //e.shatter(e.midpoint(), null, null, true, true);
-            e.shatter(e.midpoint(), null, null, true, false);
+            
+            //e.shatter(e.midpoint(), null, null, true, false);
             Thread.yield();
             repaint();
         }
@@ -393,12 +395,13 @@ public class Main extends MeshViewer {
                         if (t.aspect() < 0.1 && e.length()>e.next.length() && e.length()>e.prev.length()) es.add(e);
                     }
                 }
-
+                /*
                 for(int i=0; i<5; i++) {
                     Mesh.E e = es.poll();
                     if (e==null) break;
                     e.shatter();
                 }
+                */
                 tile.rebindPoints();
 
                 System.out.println("temp="+temp + " ratio="+(Math.ceil(acceptance*100)) + " " +
index d5e0db2..60aa9ab 100644 (file)
@@ -45,6 +45,7 @@ public class Mesh implements Iterable<Mesh.T> {
             t.e2().dobind();
             t.e3().dobind();
         }
+        System.out.println("rebound!");
     }
 
     public void transform(Matrix m) {
@@ -161,12 +162,18 @@ public class Mesh implements Iterable<Mesh.T> {
         public boolean move(Matrix m, boolean ignoreProblems) {
             boolean good = true;
 
-            for(Vertex p : (Iterable<Vertex>)getBoundPeers())
-                good &= p.transform(m.times(p.p), ignoreProblems);
+            //     t1' = M * t1
+            //     t2' = t2.getMatrix(t1) * t1'
+            //     t2' = t2.getMatrix(t1) * M * t1
+            //     t1 =     t1.getMatrix(t2) * t2
+            // M * t1 = M * t1.getMatrix(t2) * t2
+            for(Vertex v : (Iterable<Vertex>)getBoundPeers())
+                good &= v.transform(v.getBindingMatrix(this).times(m).times(this.p),
+                                    ignoreProblems);
 
-            for(Vertex p : (Iterable<Vertex>)getBoundPeers())
-                if (good || ignoreProblems)  p.reComputeErrorAround();
-                else                         p.transform(p.oldp, true);
+            for(Vertex v : (Iterable<Vertex>)getBoundPeers())
+                if (good || ignoreProblems)  v.reComputeErrorAround();
+                else                         v.transform(v.oldp, true);
 
             return good;
         }
@@ -281,7 +288,7 @@ public class Mesh implements Iterable<Mesh.T> {
             e.bind_to    = bind_others;
             for (E epeer  : e_bind_peers.set) add(epeer);
             for (E eother : e_bind_to.set)    bind_others.add(eother);
-
+            /*
             for(E eother : bind_others.set) {
                 if (e.next.bind_to.set.contains(eother.prev)) {
                     e.next.next.bindEdge(eother.prev.prev);
@@ -290,7 +297,7 @@ public class Mesh implements Iterable<Mesh.T> {
                     e.prev.prev.bindEdge(eother.next.next);
                 }
             }
-
+            */
         }
         public void dobind(E e) {
             for(E ebound : set) {
@@ -320,13 +327,16 @@ public class Mesh implements Iterable<Mesh.T> {
         public boolean intersects(T t) { return t.intersects(p1.p, p2.p); }
 
         public void bindingGroupChanged(edu.berkeley.qfat.geom.BindingGroup newBindingGroup_) {
-            edu.berkeley.qfat.geom.BindingGroup<E> newBindingGroup = (edu.berkeley.qfat.geom.BindingGroup<E>)newBindingGroup_;
+            edu.berkeley.qfat.geom.BindingGroup<E> newBindingGroup =
+                (edu.berkeley.qfat.geom.BindingGroup<E>)newBindingGroup_;
             if (newBindingGroup==null) return;
             if (this==newBindingGroup.getMaster()) return;
+            /*
             for(E eother : (Iterable<E>)newBindingGroup) {
                 this.next.bindTo(newBindingGroup.getMatrix(eother), eother.next);
                 this.prev.bindTo(newBindingGroup.getMatrix(eother), eother.prev);
             }
+            */
         }
 
         public float stretchRatio() {
@@ -344,8 +354,41 @@ public class Mesh implements Iterable<Mesh.T> {
         public int compareTo(E e) {
             return e.comparator() > comparator() ? 1 : -1;
         }
-        public void bindEdge(E e) { bind_to.add(e); }
-        public void dobind() { bind_to.dobind(this); }
+        public void bindEdge(E e, Matrix m) {
+            //bind_to.add(e);
+
+            //assumes edges are identical length at binding time
+            e = e.pair;
+            Vec reflectionPlaneNormal = e.p2.p.minus(e.p1.p).norm();
+            float a = reflectionPlaneNormal.x;
+            float b = reflectionPlaneNormal.y;
+            float c = reflectionPlaneNormal.z;
+            Matrix reflectionMatrix =
+                new Matrix( 1-2*a*a,  -2*a*b,  -2*a*c, 0,
+                            -2*a*b,  1-2*b*b,  -2*b*c, 0,
+                            -2*a*c,   -2*b*c, 1-2*c*c, 0,
+                            0,       0,       0,       1);
+            /*
+            m = m.times(Matrix.translate(e.midpoint().minus(Point.ORIGIN))
+                        .times(reflectionMatrix)
+                        .times(Matrix.translate(Point.ORIGIN.minus(e.midpoint()))));
+            */
+            System.out.println(reflectionPlaneNormal);
+            System.out.println("  " + p1.p + " " + m.times(e.p1.p));
+            System.out.println("  " + p2.p + " " + m.times(e.p2.p));
+            if (m.times(e.p1.p).minus(p1.p).mag() > EPSILON) throw new Error();
+            if (m.times(e.p2.p).minus(p2.p).mag() > EPSILON) throw new Error();
+            this.bindTo(m, e);
+        }
+        
+        public void dobind() {
+            //bind_to.dobind(this);
+            for(E e : (Iterable<E>)getBoundPeers()) {
+                if (e==this) continue;
+                p1.bindTo(getBindingMatrix(e), e.p1);
+                p2.bindTo(getBindingMatrix(e), e.p2);
+            }
+        }
 
         public Point shatter() { return shatter(true); }
         public Point shatter(boolean triangles) { return shatter(midpoint(), null, null, triangles); }
@@ -599,12 +642,14 @@ public class Mesh implements Iterable<Mesh.T> {
         public void reinsert() { triangles.remove(this); triangles.add(this); }
 
         public boolean shouldBeDrawn() {
+            /*
             if (e1().bind_to==null) return false;
             if (e2().bind_to==null) return false;
             if (e3().bind_to==null) return false;
             if (e1().bind_to.set.size() == 0) return false;
             if (e2().bind_to.set.size() == 0) return false;
             if (e3().bind_to.set.size() == 0) return false;
+            */
             return true;
         }
 
index a886aa4..f24e2ad 100644 (file)
@@ -199,12 +199,12 @@ public class MeshViewer implements GLEventListener, MouseListener, MouseMotionLi
         for(Matrix m : translations) {
             //if (v1.z==0 && v1.y==0) continue;
             i++;
-            if (i!=2&&i!=5) continue;
+            //if (i!=2&&i!=5) continue;
             Point p = new Point(0, 0, 0).times(m);
             Vec v = new Vec(p.x, p.y, p.z);
             v = v.times((float)1.04);
             gl.glTranslatef(v.x, v.y, v.z);
-            //draw(gl, false, safeTriangles);
+            draw(gl, false, safeTriangles);
             gl.glTranslatef(-v.x, -v.y, -v.z);
         }
         //gl.glEnable(GL.GL_DEPTH_TEST);
index 715f763..fc12a29 100644 (file)
@@ -16,8 +16,11 @@ public abstract class HasBindingGroup {
         if (other.bindingGroup == null) other.bindingGroup = new BindingGroup(other);
 
         if (other.bindingGroup == this.bindingGroup) {
-            if (bindingGroup.getMatrix(other).equals(Matrix.ONE)) return;
-            throw new Error("rebind attempt with " + bindingGroup.getMatrix(other));
+            if (getBindingMatrix(other).equals(bindingMatrix)) return;
+            throw new Error("rebind attempt: "+this+" and "+other+" with "
+                            + bindingMatrix
+                            + "; expected "
+                            + getBindingMatrix(other));
         }
 
         bindingMatrix =
@@ -32,6 +35,10 @@ public abstract class HasBindingGroup {
         return bindingGroup.getMatrix(this);
     }
 
+    public Matrix getBindingMatrix(HasBindingGroup other) {
+        return bindingGroup.getMatrix(this, other);
+    }
+
     public HasBindingGroup getMaster() {
         if (bindingGroup==null) return this;
         return bindingGroup.getMaster();
@@ -48,6 +55,9 @@ public abstract class HasBindingGroup {
         return bindingGroup.contains(t);
     }
 
-    public Iterable getBoundPeers() { return bindingGroup; }
+    public Iterable getBoundPeers() {
+        if (bindingGroup==null) bindingGroup = new BindingGroup(this);
+        return bindingGroup;
+    }
     public void bindingGroupChanged(BindingGroup newBindingGroup) { }
 }
index 9303233..1c52d00 100644 (file)
@@ -238,23 +238,25 @@ public class Matrix {
         if (!(oo instanceof Matrix)) return false;
         Matrix z = (Matrix)oo;
         return
-            a==z.a && 
-            b==z.b && 
-            c==z.c && 
-            d==z.d && 
-            e==z.e && 
-            f==z.f && 
-            g==z.g && 
-            h==z.h && 
-            i==z.i && 
-            j==z.j && 
-            k==z.k && 
-            l==z.l && 
-            m==z.m && 
-            n==z.n && 
-            o==z.o && 
-            p==z.p;
+            near(a,z.a) && 
+            near(b,z.b) && 
+            near(c,z.c) && 
+            near(d,z.d) && 
+            near(e,z.e) && 
+            near(f,z.f) && 
+            near(g,z.g) && 
+            near(h,z.h) && 
+            near(i,z.i) && 
+            near(j,z.j) && 
+            near(k,z.k) && 
+            near(l,z.l) && 
+            near(m,z.m) && 
+            near(n,z.n) && 
+            near(o,z.o) && 
+            near(p,z.p);
     }
+    private static final float EPSILON = 0.001f;
+    private static boolean near(float a, float b) { return a==b; }
 
     public int hashCode() {
         return
index 38f872d..fdef5e6 100644 (file)
@@ -7,9 +7,13 @@ public final class Point implements HasBoundingBox {
     public Point(double x, double y, double z) { this((float)x, (float)y, (float)z); }
     public Point(float x, float y, float z) { this.x = x; this.y = y; this.z = z; }
 
+    public static final Point ORIGIN = new Point(0,0,0);
+
     public float distance(Point p) { return (float)Math.sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y)+(z-p.z)*(z-p.z)); }
 
+    // FIXME: this should be eliminated; wrong order
     public Point times(Matrix m) { return m.times(this); }
+
     public Vec minus(Point p) { return new Vec(x-p.x, y-p.y, z-p.z); }
     public Point plus(Vec v) { return new Point(x+v.x, y+v.y, z+v.z); }