public static Random random = new Random();
private HashMap<P,P> ps = new HashMap<P,P>();
- private HashSet<T> ts = new HashSet<T>();
+ public PriorityQueue<E> es = new PriorityQueue<E>();
+ //private HashSet<T> ts = new HashSet<T>();
+ public ArrayList<T> ts = new ArrayList<T>();
public Iterator<T> iterator() { return ts.iterator(); }
if (p2 != null) return p2;
ps.put(p,p);
p.name = allname++;
- try { kd.insert(new double[]{p.x,p.y,p.z},p); } catch (Exception e) { throw new Error(e); }
+ //try { kd.insert(new double[]{p.x,p.y,p.z},p); } catch (Exception e) { throw new Error(e); }
return p;
}
public P(float x, float y, float z) {
this.x = x; this.y = y; this.z = z;
}
-
+ /*
public P nearest() {
Object[] results;
try { results = kd.nearest(new double[]{x,y,z},2); } catch (Exception e) { throw new Error(e); }
if (results[0] != this) throw new Error();
return (P)results[1];
}
-
+ */
public V minus(P p) { return new V(x-p.x, y-p.y, z-p.z); }
public P plus(V v) { return newP(x+v.x, y+v.y, z+v.z); }
public P times(M m) { return m.apply(this); }
public class BindingGroup {
public HashSet<E> es = new HashSet<E>();
public BindingGroup() { }
- public merge(E e) {
- if (e.bg != null) merge(e.bg);
- else { es.add(e); e.bg = this; }
+ public BindingGroup(E e) { es.add(e); }
+ public void add(E e) {
+ if (e.bg != null) { merge(e.bg); return; }
+ es.add(e);
+ e.bg = this;
}
- public merge(BindingGroup bg) {
+ public void merge(BindingGroup bg) {
for(E e : bg.es) {
- e.bg = this;
- this.bg.add(e);
+ e.bg = null;
+ add(e);
}
}
}
/** [UNIQUE] an edge */
- public final class E {
+ public final class E implements Comparable<E> {
+
+ public int compareTo(E e) {
+ return e.length() > length() ? 1 : -1;
+ }
+
public final P p1, p2;
T t; // triangle to our "left"
E prev; // previous half-edge
E pair; // partner half-edge
- public BindingGroup bg = null;
+ public BindingGroup bg = new BindingGroup(this);
public void bind(E e) { bind(e, new M()); }
- public void bind(E e, M m) {
- if (e.bg != null) e.bg.merge(this);
- else if (bg != null) bg.merge(e);
- else {
- bg = new BindingGroup();
- bg.merge(this);
- bg.merge(e);
- }
- }
+ public void bind(E e, M m) { e.bg.add(this); }
public void dobind() {
if (bg==null) return;
}
}
- public boolean destroyed = false;
- public void shatter() {
- if (destroyed) return;
- /*
- HashSet<E> eh = new HashSet<E>();
- eh.add(this);
- for(E ex = bound_to; ex != this; ex = ex.bound_to) eh.add(ex);
- E[] es = (E[])eh.toArray(new E[0]);
- */
- destroy();
+ boolean shattered = false;
+ public P shatter() { return shatter(midpoint(), null, null); }
+ public P shatter(P mid, BindingGroup bg1, BindingGroup bg2) {
+ if (shattered) return mid;
+ shattered = true;
+
+ P r = next.p2;
+ E next = this.next;
+ E prev = this.prev;
+
+ if (bg1==null) bg1 = new BindingGroup();
+ if (bg2==null) bg2 = new BindingGroup();
+ for(E e : bg.es) e.shatter(e.midpoint(), bg1, bg2);
pair.shatter();
- for(E ex = bound_to; ex != this; ex = ex.bound_to) ex.shatter();
+ destroy();
+
+ newT(r, p1, mid);
+ newT(r, mid, p2);
+ bg1.add(p1.getE(mid));
+ bg2.add(mid.getE(p2));
+ return mid;
}
+
+ public boolean destroyed = false;
public void destroy() {
- this.destroyed = true;
+ if (destroyed) return;
+ destroyed = true;
+ pair.destroyed = true;
+ if (next.t != null) ts.remove(next.t);
+ if (prev.t != null) ts.remove(prev.t);
+ if (pair.next.t != null) ts.remove(pair.next.t);
+ if (pair.prev.t != null) ts.remove(pair.prev.t);
+ next.t = null;
+ prev.t = null;
+ pair.next.t = null;
+ pair.prev.t = null;
+ this.bg = null;
+ pair.bg = null;
+ pair.prev.next = next;
+ next.prev = pair.prev;
+ prev.next = pair.next;
+ pair.next = prev;
+ if (p1.e == this) p1.e = prev.next;
+ if (pair.p1.e == pair) pair.p1.e = pair.prev.next;
+ es.remove(this);
+ es.remove(pair);
}
private void sync() {
if (this.next.p1 != p2) throw new Error();
if (this.prev.p2 != p1) throw new Error();
if (this.p1.e == null) this.p1.e = this;
+ es.add(this);
}
public T makeT() { return t==null ? (t = new T(this)) : t; }
public M times(M m) { return this; }
}
+ public void unbind() {
+ /*
+ for(Geom.T t : this) {
+ t.p1().unbind();
+ t.p2().unbind();
+ t.p3().unbind();
+ }
+ */
+ }
+ public void bind() {
+ for(Geom.T t : this) {
+ t.e1().dobind();
+ t.e2().dobind();
+ t.e3().dobind();
+ }
+ }
}
}
}
- //Geom.P mid = geom.newE(ltf, lbn).shatter();
+ Geom.P mid = ltn.getE(mbn).shatter();
//tx.e2.shatter();
//tx.e3.shatter();
- //mid.move(geom.new V((float)-0.05,0,0));
- //mtf.move(geom.new V(0, (float)-0.05, (float)0.05));
+ geom.bind();
+ mid.move(geom.new V((float)0,0,(float)-0.05));
+ //ltn.move(geom.new V((float)0,0,(float)-0.05));
- for(Geom.T t : geom) {
- t.e1().dobind();
- t.e2().dobind();
- t.e3().dobind();
- }
-
+ //mtf.move(geom.new V(0, (float)-0.05, (float)0.05));
+ /*
for(int i=0; i<100; i++) {
rand();
}
-
+ */
/*
}
Random random = new Random();
- public void rand() {
- int which = Math.abs(random.nextInt()) % points.length;
+ public synchronized void breakit() {
+ int i = Math.abs(random.nextInt()) % geom.es.size();
+ Geom.E e = geom.es.poll();
+ System.out.println("shatter " + e);
+ e.shatter();
+ geom.unbind();
+ geom.bind();
+ }
+ public synchronized void rand() {
+ for(int i=0; i<10; i++) {
+ Geom.P p = geom.ts.get(Math.abs(random.nextInt()) % geom.ts.size()).e1().p1;
float r1 = Math.abs(random.nextFloat());
r1 = r1 - (float)Math.floor(r1);
r1 = r1 * (float)0.01;
r1 = r1 - (float)0.005;
switch(Math.abs(random.nextInt()) % 3) {
- case 0: points[which].move(geom.new V((float)0, (float)r1, (float)0.00)); break;
- case 1: points[which].move(geom.new V((float)r1, (float)0, (float)0.00)); break;
- case 2: points[which].move(geom.new V((float)0, (float)0, (float)r1)); break;
+ case 0: p.move(geom.new V((float)0, (float)r1, (float)0)); break;
+ case 1: p.move(geom.new V((float)r1, (float)0, (float)0)); break;
+ case 2: p.move(geom.new V((float)0, (float)0, (float)r1)); break;
}
+ }
}
/**
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { }
- public void display(GLAutoDrawable drawable) {
+ public synchronized void display(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
GLU glu = new GLU();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
glu.gluPerspective(50-tz, ((float)drawable.getWidth())/drawable.getHeight(), 0.5, 10);
glu.gluLookAt(0, 0, -1, 0, 0, 0, 0, 1, 0);
gl.glTranslatef(tx/(float)20, ty/(float)20, 0);
- gl.glRotatef(anglex, 0, 1, 0);
- gl.glRotatef(angley, 1, 0, 0);
+ gl.glRotatef(anglex/3, 0, 1, 0);
+ gl.glRotatef(angley/3, 1, 0, 0);
gl.glBegin(GL.GL_TRIANGLES);
draw(gl, true);
gl.glTranslatef(v.x, v.y, v.z);
draw(gl, false);
gl.glTranslatef(-v.x, -v.y, -v.z);
+ break;
}
}
- private void draw(GL gl, boolean triangles) {
+ private synchronized void draw(GL gl, boolean triangles) {
float red = 0.0f;
float green = 0.0f;
float blue = 0.0f;
glcanvas.addMouseWheelListener(main);
glcanvas.addKeyListener(main);
+ int i = 0;
while(true) {
- Thread.sleep(100);
+ Thread.sleep(10);
glcanvas.repaint();
main.rand();
+ if (i++>10) { main.breakit(); i = 0; }
}
}