From: adam Date: Thu, 13 Dec 2007 01:47:53 +0000 (-0800) Subject: checkpoint X-Git-Url: http://git.megacz.com/?p=anneal.git;a=commitdiff_plain;h=57376a862c00fa1c8731f9989085fcfceeee0370 checkpoint darcs-hash:20071213014753-5007d-8337f477ddaa925e518fc812281fae254673527c.gz --- diff --git a/src/edu/berkeley/qfat/Main.java b/src/edu/berkeley/qfat/Main.java index 1582d69..6a02d08 100644 --- a/src/edu/berkeley/qfat/Main.java +++ b/src/edu/berkeley/qfat/Main.java @@ -12,6 +12,34 @@ import edu.berkeley.qfat.geom.Point; // - 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?) @@ -60,20 +88,23 @@ public class Main extends MeshViewer { 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(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( 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; + /* 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; + //v = v.plus(v2.norm().times(1/(float)300)); + v = v2.norm().times(1/(float)300); 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); - //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 + goal_delta <= 0); + //boolean doSwap = good && (tile_delta + goal_delta <= 0); 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) { + 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; + accepts = (int)(Math.ceil(ratio*100)); + temps = (int)(Math.ceil(temp*1000)); + vertss = tile.size(); if (breaks) { breaks = false; breakit(); @@ -328,7 +365,7 @@ public class Main extends MeshViewer { } else if (acceptance > 0.15) { gamma = 0.95f; } else { - //breakit(); + breakit(); //gamma = 1; gamma = 0.99f; //gamma = 1; @@ -339,11 +376,16 @@ public class Main extends MeshViewer { } temp = temp * gamma; + HashSet hs = new HashSet(); 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(); @@ -354,6 +396,7 @@ public class Main extends MeshViewer { tile.recomputeAllFundamentalQuadrics(); repaint(); goal.applyQuadricToNeighborAll(); + } } } diff --git a/src/edu/berkeley/qfat/Mesh.java b/src/edu/berkeley/qfat/Mesh.java index 264e379..1d4967f 100644 --- a/src/edu/berkeley/qfat/Mesh.java +++ b/src/edu/berkeley/qfat/Mesh.java @@ -15,7 +15,7 @@ public class Mesh implements Iterable { public static final Random random = new Random(); private PointSet pointset = new PointSet(); - + public int size() { return pointset.size(); } public Iterable vertices() { return pointset; } public Iterable edges() { @@ -265,11 +265,11 @@ public class Mesh implements Iterable { 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); - */ + e = e.pair.next; } while (e != this.e); if (numaspects > 0) oldscore += (aspects / numaspects); @@ -295,16 +295,25 @@ public class Mesh implements Iterable { } 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 { + /* + 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); - // FIXME: intersection test needed? - boolean good = true; - if (!ignorecollision) for(T t : Mesh.this) { if (!good) break; @@ -472,6 +481,7 @@ public class Mesh implements Iterable { 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; diff --git a/src/edu/berkeley/qfat/MeshViewer.java b/src/edu/berkeley/qfat/MeshViewer.java index fdbb1c7..fc17683 100644 --- a/src/edu/berkeley/qfat/MeshViewer.java +++ b/src/edu/berkeley/qfat/MeshViewer.java @@ -1,9 +1,11 @@ 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 com.sun.opengl.util.*; 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 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; @@ -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_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()) { @@ -111,12 +142,30 @@ public class MeshViewer implements GLEventListener, MouseListener, MouseMotionLi 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 synchronized void display(GLAutoDrawable drawable) { + public void display(GLAutoDrawable drawable) { 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); @@ -129,11 +178,17 @@ public class MeshViewer implements GLEventListener, MouseListener, MouseMotionLi gl.glRotatef(angley/3, 1, 0, 0); gl.glBegin(GL.GL_TRIANGLES); + if (tileon) draw(gl, true, tile); + if (tilemeshon) + draw(gl, false, tile); 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); + if (goalon) 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++; - 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); - 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); } - 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; @@ -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; } + gl.glColor4f((float)0.75, (float)0.25, (float)0.25, (float)0.3); //gl.glBegin(GL.GL_LINES); if (triangles) { @@ -184,7 +240,7 @@ public class MeshViewer implements GLEventListener, MouseListener, MouseMotionLi t.glVertices(gl); gl.glEnd(); } else { - /* + 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); - */ + } 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); */ - + /* 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(); } } + + //private JTextArea ocanvas = new JTextArea(); + private 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); diff --git a/src/edu/berkeley/qfat/geom/PointSet.java b/src/edu/berkeley/qfat/geom/PointSet.java index 0934336..cd3edb7 100644 --- a/src/edu/berkeley/qfat/geom/PointSet.java +++ b/src/edu/berkeley/qfat/geom/PointSet.java @@ -7,6 +7,7 @@ public class PointSet implements Iterable { private /*final*/ KDTree kd = new KDTree(3); private final double[] doubles = new double[3]; + public int size() { return exact.size(); } private HashMap exact = new HashMap(); public Iterator iterator() { diff --git a/src/edu/berkeley/qfat/geom/Triangle.java b/src/edu/berkeley/qfat/geom/Triangle.java index 6024e8f..6a938a3 100644 --- a/src/edu/berkeley/qfat/geom/Triangle.java +++ b/src/edu/berkeley/qfat/geom/Triangle.java @@ -37,5 +37,11 @@ public abstract class Triangle { 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