+ //add(goalMenu);
+ //add(hideMenu);
+ }
+
+ }
+
+ private static Matrix preMultiplyTranslationalComponentBy(Matrix mthis, Matrix mm) {
+ Vec v = mm.times(mthis.getTranslationalComponent());
+ return new Matrix(mthis.a, mthis.b, mthis.c, v.x,
+ mthis.e, mthis.f, mthis.g, v.y,
+ mthis.i, mthis.j, mthis.k, v.z,
+ mthis.m, mthis.n, mthis.o, 1);
+ }
+
+//////////////////////////////////////////////////////////////////////////////
+ public void breakit() {
+ int oldverts = verts;
+ if (verts > 2000 && !force) return;
+ force = false;
+ System.out.println("doubling vertices.");
+ PriorityQueue<Mesh.E> es = new PriorityQueue<Mesh.E>();
+ for(Mesh.T t : tile) {
+ es.add(t.e1());
+ es.add(t.e2());
+ es.add(t.e3());
+ Thread.yield();
+ repaint();
+ }
+ for(int i=0; i<Math.min(oldverts,50); i++) {
+ Mesh.E e = es.poll();
+ verts++;
+ e.shatter();
+ Thread.yield();
+ repaint();
+ }
+ System.out.println("now have " + verts + " vertices; max is 2000");
+ tile.rebindPoints();
+ }
+
+ public boolean rand(double temp, Mesh.Vertex p) {
+
+ p.reComputeErrorAround();
+ double tile_error = tile.error();
+ double goal_error = goal.error();
+
+ float max = p.averageEdgeLength()/5;
+ Vec v = new Vec(random.nextFloat(), random.nextFloat(), random.nextFloat());
+ v = v.norm().times((random.nextFloat() - 0.5f) * max);
+ Matrix m = Matrix.translate(v);
+ boolean good = p.move(v, false);
+ if (!good) { return false; }
+
+ 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);
+
+ //boolean doSwap = good && (tile_delta <= 0 && goal_delta <= 0);
+ //boolean doSwap = good && (tile_delta + goal_delta <= 0);
+ //if (temp < 0.000001) doSwap = good && (tile_delta <= 0 && goal_delta <= 0);
+ boolean doSwap = good && (Math.random() < swapProbability);
+
+ // always move uphill if possible -- potential idea
+ if (tile_delta <= 0 && goal_delta <= 0 && good) doSwap = true;
+ if (hillclimb)
+ doSwap = tile_delta <= 0 && goal_delta <= 0 && good;
+
+ if (doSwap) {
+ tile_error = new_tile_error;
+ goal_error = new_goal_error;
+ hits++;
+ p.goodp = p.p;
+ } else {
+ p.move(v.times(-1), true);
+ misses++;