public class Main extends MeshViewer {
- public static int verts = 0;
+ public static int verts = 1;
public static final Random random = new Random();
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)),
}
public synchronized void breakit() {
- if (verts > 800) return;
- //while(verts < 800) {
+ int oldverts = verts;
+ System.out.println("doubling vertices.");
PriorityQueue<Mesh.E> es = new PriorityQueue<Mesh.E>();
for(Mesh.E e : tile.edges()) es.add(e);
- for(int i=0; i<10; i++) {
+ for(int i=0; i<oldverts; i++) {
Mesh.E e = es.poll();
verts++;
- System.out.println("shatter " + e);
+ //System.out.println("shatter " + e);
e.shatter();
}
tile.rebindPoints();
- //}
}
public synchronized void rand(float temp, Mesh.Vert p) {
float hits = 0;
float misses = 0;
public void anneal() throws Exception {
- int verts = 0;
float hightemp = 10;
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;
accepts = (int)(Math.ceil(ratio*100));
temps = (int)(Math.ceil(temp*1000));
vertss = tile.size();
- if (breaks) {
- breaks = false;
+ if (breaks > 0) { while (breaks>0) {
+ breaks--;
breakit();
//gamma = 1;
gamma = 1;
//temp = last * 0.8f;
//last = temp;
//temp = hightemp;
- } else
+ } } else
if (acceptance > 0.96) gamma = 0.4f;
else if (acceptance > 0.9) gamma = 0.5f;
else if (acceptance > 0.8) gamma = 0.65f;
gamma = 0.9f;
} else if (acceptance > 0.15) {
gamma = 0.95f;
+ } else if (acceptance > 0.10) {
+ gamma = 0.98f;
} else {
breakit();
//gamma = 1;
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) {
- if (anneal) rand(temp,v);
- Thread.yield();
- repaint();
+ Mesh.Vert[] pts = (Mesh.Vert[])hs.toArray(new Mesh.Vert[0]);
+
+ int count = 0;
+ long then = System.currentTimeMillis();
+ for(int i=0; i<100; i++) {
+ if (anneal) {
+ count++;
+ Mesh.Vert v = pts[Math.abs(random.nextInt()) % pts.length];
+ rand(temp,v);
}
+ Thread.yield();
+ repaint();
}
+ System.out.println("temp="+temp + " ratio="+(Math.ceil(ratio*100)) + " " +
+ "points_per_second=" +
+ (count*1000)/((double)(System.currentTimeMillis()-then)));
tile.rebuildPointSet();
repaint();
//breakit();
*/
return ts.iterator();
}
+
public HashSet<T> ts = new HashSet<T>();
+ public RTree<T> tris = new RTree<T>();
public Mesh score_against = null;
public double score = 0;
score += oldscore;
}
+ private void removeTrianglesFromRTree() {
+ E e = this.e;
+ do {
+ if (e.t != null) e.t.removeFromRTree();
+ e = e.pair.next;
+ } while(e != this.e);
+ }
+ private void addTrianglesToRTree() {
+ E e = this.e;
+ do {
+ if (e.t != null) e.t.addToRTree();
+ e = e.pair.next;
+ } while(e != this.e);
+ }
+
/** does NOT update bound pairs! */
public boolean transform(Matrix m) {
unApplyQuadricToNeighbor();
+ Point oldp = this.p;
try {
if (pointset.get(this.p)==null) throw new Error();
pointset.remove(this);
+ removeTrianglesFromRTree();
float newx = m.a*p.x + m.b*p.y + m.c*p.z + m.d;
float newy = m.e*p.x + m.f*p.y + m.g*p.z + m.h;
float newz = m.i*p.x + m.j*p.y + m.k*p.z + m.l;
this.p = new Point(newx, newy, newz);
+ addTrianglesToRTree();
pointset.add(this);
} catch (Exception e) {
throw new RuntimeException(e);
applyQuadricToNeighbor();
// FIXME: intersection test needed?
- boolean good = true;
+ good = true;
// should recompute fundamental quadrics of all vertices sharing a face, but we defer...
E e = this.e;
e = e.pair.next;
} while(e != this.e);
- if (!ignorecollision)
- for(T t : Mesh.this) {
- if (!good) break;
- e = this.e;
- do {
- if (!t.has(e.p1) && !t.has(e.p2) && e.intersects(t)) { good = false; break; }
- if (e.t != null) {
- //if (!e.t.has(t.e1().p1) && !e.t.has(t.e1().p2) && t.e1().intersects(e.t)) { good = false; break; }
- //if (!e.t.has(t.e2().p1) && !e.t.has(t.e2().p2) && t.e2().intersects(e.t)) { good = false; break; }
- //if (!e.t.has(t.e3().p1) && !e.t.has(t.e3().p2) && t.e3().intersects(e.t)) { good = false; break; }
- }
- e = e.pair.next;
- } while(e != this.e);
+
+ if (!ignorecollision && good) {
+
+ tris.range(new Segment(oldp, this.p),
+ new Visitor<T>() {
+ public void visit(T t) {
+ if (!good) return;
+ E e = Vert.this.e;
+ do {
+ if (!t.has(e.p1) && !t.has(e.p2) && e.intersects(t)) { good = false; }
+ if (e.t != null) {
+ if (!e.t.has(t.e1().p1) && !e.t.has(t.e1().p2) && t.e1().intersects(e.t)) { good = false; }
+ if (!e.t.has(t.e2().p1) && !e.t.has(t.e2().p2) && t.e2().intersects(e.t)) { good = false; }
+ if (!e.t.has(t.e3().p1) && !e.t.has(t.e3().p2) && t.e3().intersects(e.t)) { good = false; }
+ }
+ e = e.pair.next;
+ } while(e != Vert.this.e);
+ }
+ });
+
+ /*
+ for(T t : Mesh.this) {
+ if (!good) break;
+ e = this.e;
+ do {
+ if (!t.has(e.p1) && !t.has(e.p2) && e.intersects(t)) { good = false; break; }
+ if (e.t != null) {
+ if (!e.t.has(t.e1().p1) && !e.t.has(t.e1().p2) && t.e1().intersects(e.t)) { good = false; break; }
+ if (!e.t.has(t.e2().p1) && !e.t.has(t.e2().p2) && t.e2().intersects(e.t)) { good = false; break; }
+ if (!e.t.has(t.e3().p1) && !e.t.has(t.e3().p2) && t.e3().intersects(e.t)) { good = false; break; }
+ }
+ e = e.pair.next;
+ } while(e != this.e);
+ }
+ */
}
+
reComputeErrorAround();
return good;
}
+ private boolean good;
public boolean move(Vec v) {
Matrix m = new Matrix(v);
public final int color;
public final int colorclass;
+ public void removeFromRTree() { tris.remove(this); }
+ public void addToRTree() { tris.insert(this); }
+
public void destroy() {
+ tris.remove(this);
ts.remove(this);
}
this.color = color;
this.colorclass = colorclass;
ts.add(this);
+ tris.add(this);
}
public E e1() { return e1; }
public E e2() { return e1.next; }
public boolean goalon = true;
public boolean anneal = false;
- public boolean breaks = false;
+ public int breaks = 0;
boolean alt = false;
boolean shift = false;
boolean control = false;
case KeyEvent.VK_CONTROL: control = 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_SPACE: breaks++; break;
case KeyEvent.VK_D: dump(); break;
case KeyEvent.VK_A: anneal = !anneal; break;
case KeyEvent.VK_T: tileon = !tileon; break;
package edu.berkeley.qfat.geom;
-import edu.wlu.cs.levy.CG.KDTree;
import java.util.*;
public class PointSet<V extends HasPoint> implements Iterable<V> {
- private final RTree<V> rtree = new RTree<V>();
+ private RTree<V> rtree = new RTree<V>();
- private /*final*/ KDTree kd = new KDTree(3);
- private final double[] doubles = new double[3];
+ private HashMap<Point,V> exact = new HashMap<Point,V>();
public int size() { return exact.size(); }
- private HashMap<Point,V> exact = new HashMap<Point,V>();
public Iterator<V> iterator() {
return exact.values().iterator();
}
public void clear() {
- kd = new KDTree(3);
exact = new HashMap<Point,V>();
+ rtree = new RTree<V>();
}
public V get(Point p) {
}
public void rebuild() {
- /*
- HashMap<Point,V> old_exact = exact;
- exact = new HashMap<Point,V>();
- kd = new KDTree(3);
- for(V v : old_exact.values()) add(v);
- */
}
public void add(V v) {
if (x != null && x.equals(v)) return;
if (x != null) throw new Error("duplicates!");
Point p = v.getPoint();
- /*
- doubles[0] = p.x;
- doubles[1] = p.y;
- doubles[2] = p.z;
- try {
- kd.insert(doubles, v);
- } catch (Exception e) {
- throw new Error(e);
- }
- */
rtree.insert(v);
exact.put(p, v);
}
public void remove(V v) {
Point p = v.getPoint();
- /*
- doubles[0] = p.x;
- doubles[1] = p.y;
- doubles[2] = p.z;
- try {
- kd.delete(doubles);
- } catch (Exception e) { }
- */
rtree.remove(v);
exact.remove(p);
}
public V nearest(Point p) {
if (exact.size()==0) return null;
- /*
- Object[] results;
- try {
- doubles[0] = p.x;
- doubles[1] = p.y;
- doubles[2] = p.z;
- results = kd.nearest(doubles,1);
- } catch (Exception e) {
- throw new Error(e);
- }
- V kd_says = (V)results[0];
- */
- V rt_says = rtree.nearest(p);
- //if (kd_says != rt_says) System.err.println("disagree: " + p + " " + kd_says + " " + rt_says);
- return rt_says;
+ return rtree.nearest(p);
}
-
public Vec diagonal() {
float min_x = Float.MAX_VALUE;
float min_y = Float.MAX_VALUE;
rtree.init(props);
}
+ public void add(V v) { insert(v); }
public void insert(V v) {
int id = lowid++;
idToV.put(id, v);
}
public void remove(V v) {
- int id = vToId.get(v);
+ Integer idi = vToId.get(v);
+ if (idi==null) return;
+ int id = idi;
idToV.remove(id);
vToId.remove(v);
rtree.delete(new com.infomatiq.jsi.Rectangle(v.getMinX(), v.getMinY(), v.getMinZ(),
id);
}
-
+ // gross...
V found = null;
-
private IntProcedure finder = new IntProcedure() {
public boolean execute(int id) {
found = idToV.get(id);
found = null;
return ret;
}
+
+ Visitor<V> visitor = null;
+ private IntProcedure searcher = new IntProcedure() {
+ public boolean execute(int id) {
+ V v = idToV.get(id);
+ visitor.visit(v);
+ return true;
+ }
+ };
+ public void range(HasBoundingBox v, Visitor vis) {
+ visitor = vis;
+ rtree.intersects(new com.infomatiq.jsi.Rectangle(v.getMinX(), v.getMinY(), v.getMinZ(),
+ v.getMaxX(), v.getMaxY(), v.getMaxZ()),
+ searcher);
+ visitor = null;
+ }
+
}