checkpoint
authoradam <adam@megacz.com>
Thu, 13 Dec 2007 01:47:53 +0000 (17:47 -0800)
committeradam <adam@megacz.com>
Thu, 13 Dec 2007 01:47:53 +0000 (17:47 -0800)
darcs-hash:20071213014753-5007d-8337f477ddaa925e518fc812281fae254673527c.gz

src/edu/berkeley/qfat/Main.java
src/edu/berkeley/qfat/Mesh.java
src/edu/berkeley/qfat/MeshViewer.java
src/edu/berkeley/qfat/geom/PointSet.java
src/edu/berkeley/qfat/geom/Triangle.java

index 1582d69..6a02d08 100644 (file)
@@ -12,6 +12,34 @@ import edu.berkeley.qfat.geom.Point;
 // - real anneal
 // - solve self-intersection problem
 // - get a better test model?
 // - real anneal
 // - solve self-intersection problem
 // - get a better test model?
+// - symmetry constraints withing the tile
+// - rotation matrices
+// - overbinding results in forced equational constraints on the leader
+// - shatter in invertd-triforce pattern brian mentioned
+// - aspect ratio?  non-uniform deformation?
+// - rotational alignment
+
+// - movie-style user interface like
+//      http://www.coleran.com/markcoleranreell.html ?
+
+// - consider recasting the Shewchuk predicates in Java?
+//    http://www.cs.cmu.edu/afs/cs/project/quake/public/code/predicates.c
+
+/*
+blender keys
+- middle mouse = option+click
+- right mouse = command+click
+
+3,7,1 = view along axes (control for opp direction)
+4, 8, 7, 2 = rotate in discrete increments (+control to translate)
+middle trag: rotate space
+shift+middle drag: translate space
+wheel: zoom
+home: home view: take current angle, zoom to whole scnee
+5 = ortho vs non-ortho
+
+ */
+
 
 // FIXME: re-orient goal (how?)
 
 
 // FIXME: re-orient goal (how?)
 
@@ -60,20 +88,23 @@ public class Main extends MeshViewer {
         float halfup = 0;
 
         translations = new Matrix[] {
         float halfup = 0;
 
         translations = new Matrix[] {
-
+            /*
             new Matrix(new Vec(lshift,  depth,    halfup)),
             new Matrix(new Vec(rshift,  depth,    halfup)),
             new Matrix(new Vec(lshift, -depth,    halfup)),
             new Matrix(new Vec(rshift, -depth,    halfup)),
             new Matrix(new Vec(lshift,  depth,    halfup)),
             new Matrix(new Vec(rshift,  depth,    halfup)),
             new Matrix(new Vec(lshift, -depth,    halfup)),
             new Matrix(new Vec(rshift, -depth,    halfup)),
-            /*
+            */
+
             new Matrix(new Vec(0,  depth,    halfup)),
             new Matrix(new Vec(0, -depth,    halfup)),
             new Matrix(new Vec(0,  depth,    halfup)),
             new Matrix(new Vec(0, -depth,    halfup)),
-            */
+
+
             new Matrix(new Vec(lshift,       0,  height)),
             new Matrix(new Vec(rshift,       0,  height)),
             new Matrix(new Vec(lshift,       0, -height)),
             new Matrix(new Vec(rshift,       0, -height)),
 
             new Matrix(new Vec(lshift,       0,  height)),
             new Matrix(new Vec(rshift,       0,  height)),
             new Matrix(new Vec(lshift,       0, -height)),
             new Matrix(new Vec(rshift,       0, -height)),
 
+
             new Matrix(new Vec( width,           0,    0)),
             new Matrix(new Vec(-width,           0,    0)),
 
             new Matrix(new Vec( width,           0,    0)),
             new Matrix(new Vec(-width,           0,    0)),
 
@@ -260,16 +291,18 @@ public class Main extends MeshViewer {
         double goal_score = goal.score();
 
         Vec v;
         double goal_score = goal.score();
 
         Vec v;
+        /*
         Matrix inv = p.errorQuadric();
         v = new Vec(inv.d, inv.h, inv.l).norm().times(1/(float)300);
         if (p.quadric_count == 0) {
             v = goal.nearest(p.p).p.minus(p.p).norm().times(1/(float)300);
         }
         Matrix inv = p.errorQuadric();
         v = new Vec(inv.d, inv.h, inv.l).norm().times(1/(float)300);
         if (p.quadric_count == 0) {
             v = goal.nearest(p.p).p.minus(p.p).norm().times(1/(float)300);
         }
+        */
         Vec v2 = new Vec((random.nextFloat() - (float)0.5) / 500,
                         (random.nextFloat() - (float)0.5)  / 500,
                         (random.nextFloat() - (float)0.5)  / 500);
         Vec v2 = new Vec((random.nextFloat() - (float)0.5) / 500,
                         (random.nextFloat() - (float)0.5)  / 500,
                         (random.nextFloat() - (float)0.5)  / 500);
-        v = v.plus(v2.norm().times(1/(float)300));
-        //v = v2;
+        //v = v.plus(v2.norm().times(1/(float)300));
+        v = v2.norm().times(1/(float)300);
 
         boolean good = p.move(v);
 
 
         boolean good = p.move(v);
 
@@ -281,9 +314,9 @@ public class Main extends MeshViewer {
         double goal_delta = (new_goal_score - goal_score) / goal_score;
         double delta = tile_delta + goal_delta;
         double swapProbability = Math.exp((-1 * delta) / temp);
         double goal_delta = (new_goal_score - goal_score) / goal_score;
         double delta = tile_delta + goal_delta;
         double swapProbability = Math.exp((-1 * delta) / temp);
-        //boolean doSwap = good && (Math.random() < swapProbability);
+        boolean doSwap = good && (Math.random() < swapProbability);
         //boolean doSwap = good && (tile_delta <= 0 && goal_delta <= 0);
         //boolean doSwap = good && (tile_delta <= 0 && goal_delta <= 0);
-        boolean doSwap = good && (tile_delta + goal_delta <= 0);
+        //boolean doSwap = good && (tile_delta + goal_delta <= 0);
         if (doSwap) {
             tile_score = new_tile_score;
             goal_score = new_goal_score;
         if (doSwap) {
             tile_score = new_tile_score;
             goal_score = new_goal_score;
@@ -303,12 +336,16 @@ public class Main extends MeshViewer {
         float temp = hightemp;
         float last = 10;
         while(true) {
         float temp = hightemp;
         float last = 10;
         while(true) {
+            synchronized(this) {
             double ratio = (hits+misses==0) ? 1 : (hits / (hits+misses));
             System.out.println("temp="+temp + " ratio="+(Math.ceil(ratio*100)));
             hits = 0;
             misses = 0;
             float gamma = 0;
             double acceptance = ratio;
             double ratio = (hits+misses==0) ? 1 : (hits / (hits+misses));
             System.out.println("temp="+temp + " ratio="+(Math.ceil(ratio*100)));
             hits = 0;
             misses = 0;
             float gamma = 0;
             double acceptance = ratio;
+            accepts = (int)(Math.ceil(ratio*100));
+            temps = (int)(Math.ceil(temp*1000));
+            vertss = tile.size();
             if (breaks) {
                 breaks = false;
                     breakit();
             if (breaks) {
                 breaks = false;
                     breakit();
@@ -328,7 +365,7 @@ public class Main extends MeshViewer {
                 } else if (acceptance > 0.15) {
                     gamma = 0.95f;
                 } else {
                 } else if (acceptance > 0.15) {
                     gamma = 0.95f;
                 } else {
-                    //breakit();
+                    breakit();
                     //gamma = 1;
                     gamma = 0.99f;
                     //gamma = 1;
                     //gamma = 1;
                     gamma = 0.99f;
                     //gamma = 1;
@@ -339,11 +376,16 @@ public class Main extends MeshViewer {
             }
             temp = temp * gamma;
 
             }
             temp = temp * gamma;
 
+
             HashSet<Mesh.Vert> hs = new HashSet<Mesh.Vert>();
             for(Mesh.Vert p : tile.vertices()) hs.add(p);
             for(int i=0; i<10; i++) {
                 repaint();
             HashSet<Mesh.Vert> hs = new HashSet<Mesh.Vert>();
             for(Mesh.Vert p : tile.vertices()) hs.add(p);
             for(int i=0; i<10; i++) {
                 repaint();
-                for(Mesh.Vert v : hs) rand(temp,v);
+                for(Mesh.Vert v : hs) {
+                    if (anneal) rand(temp,v);
+                    Thread.yield();
+                    repaint();
+                }
             }
             tile.rebuildPointSet();
             repaint();
             }
             tile.rebuildPointSet();
             repaint();
@@ -354,6 +396,7 @@ public class Main extends MeshViewer {
             tile.recomputeAllFundamentalQuadrics();
             repaint();
             goal.applyQuadricToNeighborAll();
             tile.recomputeAllFundamentalQuadrics();
             repaint();
             goal.applyQuadricToNeighborAll();
+            }
        }
     }
 
        }
     }
 
index 264e379..1d4967f 100644 (file)
@@ -15,7 +15,7 @@ public class Mesh implements Iterable<Mesh.T> {
     public static final Random random = new Random();
 
     private PointSet<Vert> pointset = new PointSet<Vert>();
     public static final Random random = new Random();
 
     private PointSet<Vert> pointset = new PointSet<Vert>();
-
+    public int size() { return pointset.size(); }
     public Iterable<Vert> vertices() { return pointset; }
 
     public Iterable<E> edges() {
     public Iterable<Vert> vertices() { return pointset; }
 
     public Iterable<E> edges() {
@@ -265,11 +265,11 @@ public class Mesh implements Iterable<Mesh.T> {
                     aspects += e.t.aspect()*e.t.aspect();
                 }
                 */
                     aspects += e.t.aspect()*e.t.aspect();
                 }
                 */
-                /*
-                float minangle = (float)(Math.PI * 0.9);
+
+                float minangle = (float)(Math.PI * 0.8);
                 if (ang > minangle)
                     oldscore += (ang - minangle);
                 if (ang > minangle)
                     oldscore += (ang - minangle);
-                */
+
                 e = e.pair.next;
             } while (e != this.e);
             if (numaspects > 0) oldscore += (aspects / numaspects);
                 e = e.pair.next;
             } while (e != this.e);
             if (numaspects > 0) oldscore += (aspects / numaspects);
@@ -295,16 +295,25 @@ public class Mesh implements Iterable<Mesh.T> {
             }
             applyQuadricToNeighbor();
 
             }
             applyQuadricToNeighbor();
 
+            // FIXME: intersection test needed?
+            boolean good = true;
+
             // should recompute fundamental quadrics of all vertices sharing a face, but we defer...
             E e = this.e;
             do {
             // should recompute fundamental quadrics of all vertices sharing a face, but we defer...
             E e = this.e;
             do {
+                /*
+                if (Math.abs(e.crossAngle()) > (Math.PI * 0.9) ||
+                    Math.abs(e.next.crossAngle()) > (Math.PI * 0.9)) {
+                    good = false;
+                }
+                if (e.t.aspect() < 0.1) {
+                    good = false;
+                }
+                */
                 e.p2.quadricStale = true;
                 e = e.pair.next;
             } while(e != this.e);
 
                 e.p2.quadricStale = true;
                 e = e.pair.next;
             } while(e != this.e);
 
-            // FIXME: intersection test needed?
-            boolean good = true;
-
             if (!ignorecollision)
             for(T t : Mesh.this) {
                 if (!good) break;
             if (!ignorecollision)
             for(T t : Mesh.this) {
                 if (!good) break;
@@ -472,6 +481,7 @@ public class Mesh implements Iterable<Mesh.T> {
             return length()*t.area();
             */
             return (float)Math.max(length(), midpoint().distance(nearest.p));
             return length()*t.area();
             */
             return (float)Math.max(length(), midpoint().distance(nearest.p));
+            //return length();
         }
         public int compareTo(E e) {
             return e.comparator() > comparator() ? 1 : -1;
         }
         public int compareTo(E e) {
             return e.comparator() > comparator() ? 1 : -1;
index fdbb1c7..fc17683 100644 (file)
@@ -1,9 +1,11 @@
 package edu.berkeley.qfat;
 package edu.berkeley.qfat;
+import java.io.*;
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
 import javax.media.opengl.*;
 import javax.media.opengl.glu.*;
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
 import javax.media.opengl.*;
 import javax.media.opengl.glu.*;
+import com.sun.opengl.util.*;
 import java.util.*;
 import edu.berkeley.qfat.geom.*;
 import edu.berkeley.qfat.geom.Point;
 import java.util.*;
 import edu.berkeley.qfat.geom.*;
 import edu.berkeley.qfat.geom.Point;
@@ -16,6 +18,11 @@ public class MeshViewer implements GLEventListener, MouseListener, MouseMotionLi
     public Mesh.Vert[] points;
 
 
     public Mesh.Vert[] points;
 
 
+    public boolean tileon = false;
+    public boolean tilemeshon = false;
+    public boolean goalon = true;
+    public boolean anneal = false;
+
     public boolean breaks = false;
     boolean alt = false;
     boolean shift = false;
     public boolean breaks = false;
     boolean alt = false;
     boolean shift = false;
@@ -32,7 +39,31 @@ public class MeshViewer implements GLEventListener, MouseListener, MouseMotionLi
             case KeyEvent.VK_ALT: alt = true; break;
             case KeyEvent.VK_SHIFT: shift = true; break;
             case KeyEvent.VK_SPACE: breaks = true; break;
             case KeyEvent.VK_ALT: alt = true; break;
             case KeyEvent.VK_SHIFT: shift = true; break;
             case KeyEvent.VK_SPACE: breaks = true; break;
+            case KeyEvent.VK_D: dump(); break;
+            case KeyEvent.VK_A: anneal = !anneal; break;
+            case KeyEvent.VK_T: tileon = !tileon; break;
+            case KeyEvent.VK_G: goalon = !goalon; break;
+            case KeyEvent.VK_M: tilemeshon = !tilemeshon; break;
+        }
+    }
+    public synchronized void dump() {
+        try {
+        PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("dump.stl")));
+        pw.println("solid dump");
+        for(Mesh.T t : tile) {
+            Vec normal = t.norm();
+            pw.println("facet normal " + normal.x + " " + normal.y + " " + normal.z);
+            pw.println("  outer loop");
+            for(Mesh.Vert v : new Mesh.Vert[] { t.v1(), t.v2(), t.v3() }) {
+                pw.println("    vertex " + v.p.x + " " + v.p.y + " " + v.p.z);
+            }
+            pw.println("  endloop");
+            pw.println("endfacet");
         }
         }
+        pw.println("endsolid dump");
+        pw.flush();
+        pw.close();
+        } catch (Exception e) { throw new RuntimeException(e); }
     }
     public void keyReleased(KeyEvent e) {
         switch(e.getKeyCode()) {
     }
     public void keyReleased(KeyEvent e) {
         switch(e.getKeyCode()) {
@@ -111,12 +142,30 @@ public class MeshViewer implements GLEventListener, MouseListener, MouseMotionLi
         gl.glEnable(GL.GL_COLOR_MATERIAL);
 
         display(gld);
         gl.glEnable(GL.GL_COLOR_MATERIAL);
 
         display(gld);
+
     }
 
     }
 
+    public int temps;
+    public int accepts;
+    public    int vertss;
     public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
     public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { }
     public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
     public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { }
-    public synchronized void display(GLAutoDrawable drawable) {
+    public void display(GLAutoDrawable drawable) {
         if (translations==null) return;
         if (translations==null) return;
+
+        glcanvas.setSize(f.getWidth(), f.getHeight() - 100);
+        Graphics2D g = (Graphics2D)f.getGraphics();
+        g.setColor(Color.black);
+        g.fillRect(0, f.getHeight()-100, f.getWidth(), f.getHeight());
+        g.setColor(Color.red);
+        int top = f.getHeight()-100;
+        g.drawString("temperature: "+temps, 10, 30+top);
+        g.drawString("acceptance: "+accepts, 10, 50+top);
+        g.drawString("vertices: "+vertss, 10, 70+top);
+        g.fillRect(140, 25+top, temps, 10);
+        g.fillRect(140, 45+top, accepts, 10);
+        g.fillRect(140, 65+top, vertss, 10);
+
         GL gl = drawable.getGL();
         GLU glu = new GLU();
         gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
         GL gl = drawable.getGL();
         GLU glu = new GLU();
         gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
@@ -129,11 +178,17 @@ public class MeshViewer implements GLEventListener, MouseListener, MouseMotionLi
         gl.glRotatef(angley/3, 1, 0, 0);
 
         gl.glBegin(GL.GL_TRIANGLES);
         gl.glRotatef(angley/3, 1, 0, 0);
 
         gl.glBegin(GL.GL_TRIANGLES);
+        if (tileon)
         draw(gl, true, tile);
         draw(gl, true, tile);
+        if (tilemeshon)
+        draw(gl, false, tile);
         gl.glEnd();
 
         gl.glEnd();
 
+        //draw(gl, false, tile);
+
         gl.glBegin(GL.GL_TRIANGLES);
         gl.glColor4f((float)0.5, (float)0.5, (float)0.5, (float)0.8);
         gl.glBegin(GL.GL_TRIANGLES);
         gl.glColor4f((float)0.5, (float)0.5, (float)0.5, (float)0.8);
+        if (goalon)
         draw(gl, false, goal);
         gl.glEnd();
 
         draw(gl, false, goal);
         gl.glEnd();
 
@@ -144,19 +199,19 @@ public class MeshViewer implements GLEventListener, MouseListener, MouseMotionLi
         for(Matrix m : translations) {
             //if (v1.z==0 && v1.y==0) continue;
             i++;
         for(Matrix m : translations) {
             //if (v1.z==0 && v1.y==0) continue;
             i++;
-            if (i != 7 /*&& i!=4*/) continue;
+            //if (i != 7 && i!=4) 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);
             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, tile);
+            //draw(gl, false, tile);
             gl.glTranslatef(-v.x, -v.y, -v.z);
         }
         //gl.glEnable(GL.GL_DEPTH_TEST);
         gl.glEnable (GL.GL_LIGHTING);
     }
 
             gl.glTranslatef(-v.x, -v.y, -v.z);
         }
         //gl.glEnable(GL.GL_DEPTH_TEST);
         gl.glEnable (GL.GL_LIGHTING);
     }
 
-    private synchronized void draw(GL gl, boolean triangles, Mesh mesh) {
+    private void draw(GL gl, boolean triangles, Mesh mesh) {
         float red = 0.0f;
         float green = 0.0f;
         float blue = 0.0f;
         float red = 0.0f;
         float green = 0.0f;
         float blue = 0.0f;
@@ -177,6 +232,7 @@ public class MeshViewer implements GLEventListener, MouseListener, MouseMotionLi
                 case 5: gl.glColor4f((float)0.25, (float)0.75, (float)0.75, (float)0.3); break;
                 case 6: gl.glColor4f((float)0.75, (float)0.25, (float)0.75, (float)0.3); break;
             }
                 case 5: gl.glColor4f((float)0.25, (float)0.75, (float)0.75, (float)0.3); break;
                 case 6: gl.glColor4f((float)0.75, (float)0.25, (float)0.75, (float)0.3); break;
             }
+            gl.glColor4f((float)0.75, (float)0.25, (float)0.25, (float)0.3);
             //gl.glBegin(GL.GL_LINES);
 
             if (triangles) {
             //gl.glBegin(GL.GL_LINES);
 
             if (triangles) {
@@ -184,7 +240,7 @@ public class MeshViewer implements GLEventListener, MouseListener, MouseMotionLi
                 t.glVertices(gl);
                 gl.glEnd();
             } else {
                 t.glVertices(gl);
                 gl.glEnd();
             } else {
-                /*
+
                 gl.glDisable(GL.GL_LIGHTING);
                 gl.glBegin(GL.GL_LINES);
                 gl.glColor3f(1, 1, 1);
                 gl.glDisable(GL.GL_LIGHTING);
                 gl.glBegin(GL.GL_LINES);
                 gl.glColor3f(1, 1, 1);
@@ -196,7 +252,7 @@ public class MeshViewer implements GLEventListener, MouseListener, MouseMotionLi
                 t.e3().p2.p.glVertex(gl);
                 gl.glEnd();
                 gl.glEnable(GL.GL_LIGHTING);
                 t.e3().p2.p.glVertex(gl);
                 gl.glEnd();
                 gl.glEnable(GL.GL_LIGHTING);
-                */
+
             }
 
             Point centroid = t.centroid();
             }
 
             Point centroid = t.centroid();
@@ -206,7 +262,7 @@ public class MeshViewer implements GLEventListener, MouseListener, MouseMotionLi
             centroid.glVertex(gl);
             centroid.plus(t.norm().times(t.diameter())).glVertex(gl);
             */
             centroid.glVertex(gl);
             centroid.plus(t.norm().times(t.diameter())).glVertex(gl);
             */
-
+            /*
             if (mesh==goal)
                 for(Mesh.Vert p : new Mesh.Vert[] { t.v1(), t.v2(), t.v3() }) {
                 gl.glDisable(GL.GL_LIGHTING);
             if (mesh==goal)
                 for(Mesh.Vert p : new Mesh.Vert[] { t.v1(), t.v2(), t.v3() }) {
                 gl.glDisable(GL.GL_LIGHTING);
@@ -219,15 +275,19 @@ public class MeshViewer implements GLEventListener, MouseListener, MouseMotionLi
                 gl.glEnd();
                 gl.glEnable(GL.GL_LIGHTING);
                 }
                 gl.glEnd();
                 gl.glEnable(GL.GL_LIGHTING);
                 }
-
+            */
             gl.glEnd();
 
         }
     }
 
             gl.glEnd();
 
         }
     }
 
+
+    //private JTextArea ocanvas = new JTextArea();
+    private Frame f;
     private GLCanvas glcanvas;
     public MeshViewer(Frame f) {
     private GLCanvas glcanvas;
     public MeshViewer(Frame f) {
-        GLCapabilities glcaps = new GLCapabilities();
+        this.f = f;
+       GLCapabilities glcaps = new GLCapabilities();
         glcanvas = new GLCanvas();
         glcanvas.addGLEventListener(this);
         f.add(glcanvas, BorderLayout.CENTER);
         glcanvas = new GLCanvas();
         glcanvas.addGLEventListener(this);
         f.add(glcanvas, BorderLayout.CENTER);
index 0934336..cd3edb7 100644 (file)
@@ -7,6 +7,7 @@ public class PointSet<V extends HasPoint> implements Iterable<V> {
     private /*final*/ KDTree kd = new KDTree(3);
     private final double[] doubles = new double[3];
 
     private /*final*/ KDTree kd = new KDTree(3);
     private final double[] doubles = new double[3];
 
+    public int size() { return exact.size(); }
     private HashMap<Point,V> exact = new HashMap<Point,V>();
 
     public Iterator<V> iterator() {
     private HashMap<Point,V> exact = new HashMap<Point,V>();
 
     public Iterator<V> iterator() {
index 6024e8f..6a938a3 100644 (file)
@@ -37,5 +37,11 @@ public abstract class Triangle {
                              p3().distance(p1())) / 2;
         return 1/(1+area()/(max*max));
     }
                              p3().distance(p1())) / 2;
         return 1/(1+area()/(max*max));
     }
+    public float aspect0() {
+        float max = Math.max(Math.max(p1().distance(p2()),
+                                      p2().distance(p3())),
+                             p3().distance(p1())) / 2;
+        return (area()/(max*max));
+    }
 
 }
\ No newline at end of file
 
 }
\ No newline at end of file