checkpoint
[anneal.git] / src / edu / berkeley / qfat / Main.java
index 44a8312..83bf281 100644 (file)
@@ -63,8 +63,6 @@ public class Main extends MeshViewer {
             Mesh.T t  = goal.newT(p0, p1, p2, n, 0);
         }
 
-        goal.ignorecollision = true;
-
         // rotate to align major axis -- this probably needs to be done by a human.
         goal.transform(Matrix.rotate(new Vec(0, 0, 1), (float)(Math.PI/2)));
 
@@ -264,11 +262,11 @@ public class Main extends MeshViewer {
         System.out.println("tile volume: " + tile.volume());
         System.out.println("goal volume: " + goal.volume());
 
-        tile.score_against = goal;
-        goal.score_against = tile;
+        tile.error_against = goal;
+        goal.error_against = tile;
     }
 
-    public synchronized void breakit() {
+    public void breakit() {
         int oldverts = verts;
         System.out.println("doubling vertices.");
         PriorityQueue<Mesh.E> es = new PriorityQueue<Mesh.E>();
@@ -276,57 +274,52 @@ public class Main extends MeshViewer {
             es.add(t.e1());
             es.add(t.e2());
             es.add(t.e3());
+            Thread.yield();
+            repaint();
         }
-        for(int i=0; i<oldverts; i++) {
+        for(int i=0; i<Math.min(oldverts,200); i++) {
             Mesh.E e = es.poll();
             verts++;
             //System.out.println("shatter " + e);
             e.shatter();
+            Thread.yield();
+            repaint();
         }
         tile.rebindPoints();
     }
 
     public synchronized void rand(float temp, Mesh.Vertex p) {
 
-        //p.reComputeError();
-        p.reComputeErrorAround();
-        double tile_score = tile.score();
-        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);
-          }
-        */
-        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.norm().times(1/(float)300);
-
-        boolean good = p.move(v);
-
         p.reComputeErrorAround();
-
-        double new_tile_score = tile.score();
-        double new_goal_score = goal.score();
-        double tile_delta = (new_tile_score - tile_score) / tile_score;
-        double goal_delta = (new_goal_score - goal_score) / goal_score;
+        double tile_error = tile.error();
+        double goal_error = goal.error();
+
+        float max = p.averageEdgeLength()/10;
+        Vec v = new Vec(random.nextFloat(), random.nextFloat(), random.nextFloat());
+        v = v.norm().times((random.nextFloat() - 0.5f) * max);
+        //System.out.println(max + " " + p.averageEdgeLength() + " " + v.mag());
+        Matrix m = Matrix.translate(v);
+
+        boolean good = p.move(m, false);
+        if (!good) { /*misses++;*/ return; }
+
+        double new_tile_error = tile.error();
+        double new_goal_error = goal.error();
+        double tile_delta = (new_tile_error - tile_error) / tile_error;
+        double goal_delta = (new_goal_error - goal_error) / goal_error;
         double delta = tile_delta + goal_delta;
-        double swapProbability = Math.exp((-1 * delta) / temp);
+        double swapProbability = Math.exp((-1 * delta) / (((double)temp)/1000000));
         boolean doSwap = good && (Math.random() < swapProbability);
         //boolean doSwap = good && (tile_delta <= 0 && goal_delta <= 0);
         //boolean doSwap = good && (tile_delta + goal_delta <= 0);
         if (doSwap) {
-            tile_score = new_tile_score;
-            goal_score = new_goal_score;
-            //System.out.println("score: " + tile_score + " / " + goal_score);
+            tile_error = new_tile_error;
+            goal_error = new_goal_error;
+            //System.out.println("error: " + tile_error + " / " + goal_error);
             hits++;
+            p.goodp = p.p;
         } else {
-            p.move(v.times(-1));
+            p.move(Matrix.translate(v.times(-1)), true);
             misses++;
         }
     }
@@ -334,49 +327,42 @@ public class Main extends MeshViewer {
     float hits = 0;
     float misses = 0;
     public void anneal() throws Exception {
-        float hightemp = 10;
+        float hightemp = 1;
         float temp = hightemp;
         float last = 10;
+        boolean seek_upward = false;
+        double acceptance = 1;
         while(true) {
             synchronized(this) {
                 double ratio = (hits+misses==0) ? 1 : (hits / (hits+misses));
                 hits = 0;
                 misses = 0;
-                float gamma = 0;
-                double acceptance = ratio;
+                float gamma = 1;
+                acceptance = (ratio+acceptance)/2;
                 accepts = (int)(Math.ceil(ratio*100));
                 temps = (int)(Math.ceil(temp*1000));
                 vertss = tile.size();
-                if (breaks > 0) { while (breaks>0) {
+                if (breaks > 0) {
+                    while (breaks>0) {
                         breaks--;
                         breakit();
-                        //gamma = 1;
-                        gamma = 1;
-                        //temp = last * 0.8f;
-                        //last = temp;
-                        //temp = hightemp;
-                    } } else
-                    if (acceptance > 0.96) gamma = 0.4f;
-                    else if (acceptance > 0.9) gamma = 0.5f;
-                    else if (acceptance > 0.8) gamma = 0.65f;
-                    else if (acceptance > 0.6) gamma = 0.7f;
-                    else {
-                        if (acceptance > 0.3) {
-                            gamma = 0.9f;
-                        } else if (acceptance > 0.15) {
-                            gamma = 0.95f;
-                        } else if (acceptance > 0.10) {
-                            gamma = 0.98f;
-                        } else {
-                            breakit();
-                            //gamma = 1;
-                            gamma = 0.99f;
-                            //gamma = 1;
-                            //temp = last * 0.8f;
-                            //last = temp;
-                            //temp = hightemp;
-                        }
                     }
+                    seek_upward = true;
+                } else if (acceptance > 0.96) gamma = 0.4f;
+                else if (acceptance > 0.9)    gamma = 0.5f;
+                else if (acceptance > 0.8)    gamma = 0.65f;
+                else if (acceptance > 0.6)    gamma = 0.7f;
+                else if (acceptance > 0.3)    gamma = 0.8f;
+                else if (acceptance > 0.15)   gamma = 0.9f;
+                else if (acceptance > 0.05)   gamma = 0.95f;
+                else if (acceptance > 0.01)   gamma = 0.98f;
+                else { /*breaks++;*/ }
+
+                if (seek_upward) {
+                    if (acceptance > 0.2) seek_upward = false;
+                    else gamma = 2-gamma;
+                }
+
                 temp = temp * gamma;
 
 
@@ -397,7 +383,24 @@ public class Main extends MeshViewer {
                     Thread.yield();
                     repaint();
                 }
-                System.out.println("temp="+temp + " ratio="+(Math.ceil(ratio*100)) + " " +
+                PriorityQueue<Mesh.E> es = new PriorityQueue<Mesh.E>();
+                for(Mesh.T t : tile) {
+                    float max = 5;
+                    for(Mesh.E e : new Mesh.E[] { t.e1(), t.e2(), t.e3() }) {
+                        if (e==null) continue;
+                        if (e.stretchRatio() > max) es.add(e);
+                        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)) + " " +
                                    "points_per_second=" +
                                    (count*1000)/((double)(System.currentTimeMillis()-then)));
 
@@ -405,7 +408,9 @@ public class Main extends MeshViewer {
 
                 synchronized(safeTriangles) {
                     safeTriangles.clear();
-                    for(Mesh.T t : tile) if (t.shouldBeDrawn()) safeTriangles.add(t);
+                    for(Mesh.T t : tile) 
+                        if (t.shouldBeDrawn())
+                            safeTriangles.add(t);
                 }
             }
         }