Mesh.E e = es.poll();
verts++;
//System.out.println("shatter " + e);
- e.shatter(e.midpoint(), null, null, true, true);
+ //e.shatter(e.midpoint(), null, null, true, true);
+ e.shatter(e.midpoint(), null, null, true, false);
Thread.yield();
repaint();
}
public Point p, oldp, goodp;
E e; // some edge *leaving* this point
- Matrix binding = Matrix.ONE;
- Vertex bound_to = this;
private boolean illegal = false;
public Point getPoint() { return p; }
public boolean move(Matrix m, boolean ignoreProblems) {
boolean good = true;
- for(Vertex p = this; p != null; p = (p.bound_to==this)?null:p.bound_to)
+
+ for(Vertex p : (Iterable<Vertex>)getBoundPeers())
good &= p.transform(m.times(p.p), ignoreProblems);
- for(Vertex p = this; p != null; p = (p.bound_to==this)?null:p.bound_to)
+
+ for(Vertex p : (Iterable<Vertex>)getBoundPeers())
if (good || ignoreProblems) p.reComputeErrorAround();
- else p.transform(p.oldp, true);
+ else p.transform(p.oldp, true);
+
return good;
}
return norm.norm();
}
- public boolean isBoundTo(Vertex p) {
- for(Vertex px = p; px!=null; px=(px.bound_to==p?null:px.bound_to))
- if (px==this)
- return true;
- return false;
- }
-
- public void unbind() { bound_to = this; binding = Matrix.ONE; }
- public void bind(Vertex p) { bind(p, Matrix.ONE); }
- public void bind(Vertex p, Matrix binding) {
- if (isBoundTo(p)) return;
- Vertex temp_bound_to = p.bound_to;
- Matrix temp_binding = p.binding;
- p.bound_to = this.bound_to;
- p.binding = binding.times(this.binding); // FIXME: may have order wrong here
- this.bound_to = temp_bound_to;
- this.binding = temp_binding.times(temp_binding); // FIXME: may have order wrong here
- }
+ public void bindTo(Vertex p) { bindTo(Matrix.ONE, p); }
}
public class BindingGroup {
}
public void dobind(E e) {
for(E ebound : set) {
- e.p1.bind(ebound.p2);
- e.p2.bind(ebound.p1);
+ e.p1.bindTo(Matrix.ONE, ebound.p2);
+ e.p2.bindTo(Matrix.ONE, ebound.p1);
}
}
public void shatter(BindingGroup bg1, BindingGroup bg2, boolean triangles) {
public void reinsert() { triangles.remove(this); triangles.add(this); }
public boolean shouldBeDrawn() {
+ if (e1().bind_to==null) return false;
+ if (e2().bind_to==null) return false;
+ if (e3().bind_to==null) return false;
if (e1().bind_to.set.size() == 0) return false;
if (e2().bind_to.set.size() == 0) return false;
if (e3().bind_to.set.size() == 0) return false;
import javax.media.opengl.*;
import java.util.*;
-public class BindingGroup<T extends HasBindingGroup> {
+public class BindingGroup<T extends HasBindingGroup> implements Iterable<T> {
private T master = null;
private HashMap<T,Matrix> matrices = new HashMap<T,Matrix>();
public T getMaster() { return master; }
public Matrix getMatrix(T t) { return matrices.get(t); }
- // t1 = getMatrix(t1) * master
- // getMatrix(t2)^-1 * t2 = master
- // t1 = getMatrix(t1) * getMatrix(t2)^-1 * t2
+ public Iterator<T> iterator() { return matrices.keySet().iterator(); }
+
/** t1 = getMatrix(t1, t2) * t2 */
public Matrix getMatrix(T t1, T t2) {
+ // t1 = getMatrix(t1) * master
+ // getMatrix(t2)^-1 * t2 = master
+ // t1 = getMatrix(t1) * getMatrix(t2)^-1 * t2
return getMatrix(t1).times(getMatrix(t2).inverse());
}
+ public void unbind(T trem) {
+ if (trem != master) {
+ matrices.remove(trem);
+ return;
+ }
+ if (matrices.size()==1) {
+ master = null;
+ matrices.remove(trem);
+ return;
+ }
+ Iterator<T> it = iterator();
+ T newmaster = it.next();
+ if (newmaster==trem) newmaster = it.next();
+ if (newmaster==trem) throw new Error();
+ HashMap<T,Matrix> newmatrices = new HashMap<T,Matrix>();
+ for(T t : matrices.keySet()) {
+ if (t==trem) continue;
+ newmatrices.put(t, getMatrix(t, newmaster));
+ }
+ master = newmaster;
+ matrices = newmatrices;
+ }
+
+ public boolean contains(HasBindingGroup t) {
+ return matrices.get((T)t) != null;
+ }
}
// want: self = bindingMatrix * other
// therefore: master = bindingGroup[self]^-1 * bindingMatrix * other
// therefore: = bindingGroup[self]^-1 * bindingMatrix * other.bindingGroup[other] * other.bindingGroup.master
- public void bindTo(HasBindingGroup other, Matrix bindingMatrix) {
- if (other.bindingGroup == this.bindingGroup)
- throw new Error("rebind attempt");
+ public void bindTo(Matrix bindingMatrix, HasBindingGroup other) {
+ if (bindingGroup == null) bindingGroup = new BindingGroup(this);
+ if (other.bindingGroup == null) other.bindingGroup = new BindingGroup(other);
+
+ if (other.bindingGroup == this.bindingGroup) {
+ if (bindingGroup.getMatrix(other).equals(Matrix.ONE)) return;
+ throw new Error("rebind attempt with " + bindingGroup.getMatrix(other));
+ }
bindingMatrix =
getBindingMatrix()
}
public Matrix getBindingMatrix() {
+ if (bindingGroup==null) return Matrix.ONE;
return bindingGroup.getMatrix(this);
}
public HasBindingGroup getMaster() {
+ if (bindingGroup==null) return this;
return bindingGroup.getMaster();
}
+ public void unbind() {
+ if (bindingGroup==null) return;
+ bindingGroup.unbind(this);
+ bindingGroup = null;
+ }
+
+ public boolean isBoundTo(HasBindingGroup t) {
+ return bindingGroup.contains(t);
+ }
+
+ public Iterable getBoundPeers() { return bindingGroup; }
}
import javax.media.opengl.*;
/** any object associated with a specific point in 3D space */
-public abstract class HasPoint implements HasBoundingBox {
+public abstract class HasPoint extends HasBindingGroup implements HasBoundingBox {
public abstract Point getPoint();
public float getMaxX() { return getPoint().getMaxX(); }
public float getMinX() { return getPoint().getMinX(); }
.times(1/determinant);
}
+ public String toString() {
+ return
+ "\n [ " + a + "\t" + b + "\t" + c + "\t" + d + "\t" + "]" +
+ "\n [ " + e + "\t" + f + "\t" + g + "\t" + h + "\t" + "]" +
+ "\n [ " + i + "\t" + j + "\t" + k + "\t" + l + "\t" + "]" +
+ "\n [ " + m + "\t" + n + "\t" + o + "\t" + p + "\t" + "]\n";
+ }
+
+ public boolean equals(Object oo) {
+ if (oo==null) return false;
+ if (!(oo instanceof Matrix)) return false;
+ Matrix z = (Matrix)oo;
+ return
+ a==z.a &&
+ b==z.b &&
+ c==z.c &&
+ d==z.d &&
+ e==z.e &&
+ f==z.f &&
+ g==z.g &&
+ h==z.h &&
+ i==z.i &&
+ j==z.j &&
+ k==z.k &&
+ l==z.l &&
+ m==z.m &&
+ n==z.n &&
+ o==z.o &&
+ p==z.p;
+ }
+
+ public int hashCode() {
+ return
+ Float.floatToIntBits(a) ^
+ Float.floatToIntBits(b) ^
+ Float.floatToIntBits(c) ^
+ Float.floatToIntBits(d) ^
+ Float.floatToIntBits(e) ^
+ Float.floatToIntBits(f) ^
+ Float.floatToIntBits(g) ^
+ Float.floatToIntBits(h) ^
+ Float.floatToIntBits(i) ^
+ Float.floatToIntBits(j) ^
+ Float.floatToIntBits(k) ^
+ Float.floatToIntBits(l) ^
+ Float.floatToIntBits(m) ^
+ Float.floatToIntBits(n) ^
+ Float.floatToIntBits(o) ^
+ Float.floatToIntBits(p);
+ }
}