float halfup = 0;
translations = new Matrix[] {
-
Matrix.translate(new Vec(lshift, depth, halfup)),
+ /*
Matrix.translate(new Vec(rshift, depth, halfup)),
Matrix.translate(new Vec(lshift, -depth, halfup)),
Matrix.translate(new Vec(rshift, -depth, halfup)),
+ */
/*
Matrix.translate(new Vec(0, depth, halfup)),
Matrix.translate(new Vec(0, -depth, halfup)),
*/
-
+ /*
Matrix.translate(new Vec(lshift, 0, height)),
Matrix.translate(new Vec(rshift, 0, height)),
Matrix.translate(new Vec(lshift, 0, -height)),
Matrix.translate(new Vec( width, 0, 0)),
Matrix.translate(new Vec(-width, 0, 0)),
-
+ */
};
//
if ((t1.v1().p.times(m).minus(t2.v1().p).mag() < Mesh.EPSILON) &&
(t1.v2().p.times(m).minus(t2.v3().p).mag() < Mesh.EPSILON) &&
(t1.v3().p.times(m).minus(t2.v2().p).mag() < Mesh.EPSILON)) {
- t1.e1().bindEdge(t2.e3());
- t1.e2().bindEdge(t2.e2());
- t1.e3().bindEdge(t2.e1());
+ t2.e3().bindEdge(t1.e1(), m);
+ t2.e2().bindEdge(t1.e2(), m);
+ t2.e1().bindEdge(t1.e3(), m);
}
if ((t1.v2().p.times(m).minus(t2.v1().p).mag() < Mesh.EPSILON) &&
(t1.v3().p.times(m).minus(t2.v3().p).mag() < Mesh.EPSILON) &&
(t1.v1().p.times(m).minus(t2.v2().p).mag() < Mesh.EPSILON)) {
- t1.e2().bindEdge(t2.e3());
- t1.e3().bindEdge(t2.e2());
- t1.e1().bindEdge(t2.e1());
+ t2.e3().bindEdge(t1.e2(), m);
+ t2.e2().bindEdge(t1.e3(), m);
+ t2.e1().bindEdge(t1.e1(), m);
}
if ((t1.v3().p.times(m).minus(t2.v1().p).mag() < Mesh.EPSILON) &&
(t1.v1().p.times(m).minus(t2.v3().p).mag() < Mesh.EPSILON) &&
(t1.v2().p.times(m).minus(t2.v2().p).mag() < Mesh.EPSILON)) {
- t1.e3().bindEdge(t2.e3());
- t1.e1().bindEdge(t2.e2());
- t1.e2().bindEdge(t2.e1());
+ t2.e3().bindEdge(t1.e3(), m);
+ t2.e2().bindEdge(t1.e1(), m);
+ t2.e1().bindEdge(t1.e2(), m);
}
}
verts++;
//System.out.println("shatter " + e);
//e.shatter(e.midpoint(), null, null, true, true);
- e.shatter(e.midpoint(), null, null, true, false);
+
+ //e.shatter(e.midpoint(), null, null, true, false);
Thread.yield();
repaint();
}
if (t.aspect() < 0.1 && e.length()>e.next.length() && e.length()>e.prev.length()) es.add(e);
}
}
-
+ /*
for(int i=0; i<5; i++) {
Mesh.E e = es.poll();
if (e==null) break;
e.shatter();
}
+ */
tile.rebindPoints();
System.out.println("temp="+temp + " ratio="+(Math.ceil(acceptance*100)) + " " +
t.e2().dobind();
t.e3().dobind();
}
+ System.out.println("rebound!");
}
public void transform(Matrix m) {
public boolean move(Matrix m, boolean ignoreProblems) {
boolean good = true;
- for(Vertex p : (Iterable<Vertex>)getBoundPeers())
- good &= p.transform(m.times(p.p), ignoreProblems);
+ // t1' = M * t1
+ // t2' = t2.getMatrix(t1) * t1'
+ // t2' = t2.getMatrix(t1) * M * t1
+ // t1 = t1.getMatrix(t2) * t2
+ // M * t1 = M * t1.getMatrix(t2) * t2
+ for(Vertex v : (Iterable<Vertex>)getBoundPeers())
+ good &= v.transform(v.getBindingMatrix(this).times(m).times(this.p),
+ ignoreProblems);
- for(Vertex p : (Iterable<Vertex>)getBoundPeers())
- if (good || ignoreProblems) p.reComputeErrorAround();
- else p.transform(p.oldp, true);
+ for(Vertex v : (Iterable<Vertex>)getBoundPeers())
+ if (good || ignoreProblems) v.reComputeErrorAround();
+ else v.transform(v.oldp, true);
return good;
}
e.bind_to = bind_others;
for (E epeer : e_bind_peers.set) add(epeer);
for (E eother : e_bind_to.set) bind_others.add(eother);
-
+ /*
for(E eother : bind_others.set) {
if (e.next.bind_to.set.contains(eother.prev)) {
e.next.next.bindEdge(eother.prev.prev);
e.prev.prev.bindEdge(eother.next.next);
}
}
-
+ */
}
public void dobind(E e) {
for(E ebound : set) {
public boolean intersects(T t) { return t.intersects(p1.p, p2.p); }
public void bindingGroupChanged(edu.berkeley.qfat.geom.BindingGroup newBindingGroup_) {
- edu.berkeley.qfat.geom.BindingGroup<E> newBindingGroup = (edu.berkeley.qfat.geom.BindingGroup<E>)newBindingGroup_;
+ edu.berkeley.qfat.geom.BindingGroup<E> newBindingGroup =
+ (edu.berkeley.qfat.geom.BindingGroup<E>)newBindingGroup_;
if (newBindingGroup==null) return;
if (this==newBindingGroup.getMaster()) return;
+ /*
for(E eother : (Iterable<E>)newBindingGroup) {
this.next.bindTo(newBindingGroup.getMatrix(eother), eother.next);
this.prev.bindTo(newBindingGroup.getMatrix(eother), eother.prev);
}
+ */
}
public float stretchRatio() {
public int compareTo(E e) {
return e.comparator() > comparator() ? 1 : -1;
}
- public void bindEdge(E e) { bind_to.add(e); }
- public void dobind() { bind_to.dobind(this); }
+ public void bindEdge(E e, Matrix m) {
+ //bind_to.add(e);
+
+ //assumes edges are identical length at binding time
+ e = e.pair;
+ Vec reflectionPlaneNormal = e.p2.p.minus(e.p1.p).norm();
+ float a = reflectionPlaneNormal.x;
+ float b = reflectionPlaneNormal.y;
+ float c = reflectionPlaneNormal.z;
+ Matrix reflectionMatrix =
+ new Matrix( 1-2*a*a, -2*a*b, -2*a*c, 0,
+ -2*a*b, 1-2*b*b, -2*b*c, 0,
+ -2*a*c, -2*b*c, 1-2*c*c, 0,
+ 0, 0, 0, 1);
+ /*
+ m = m.times(Matrix.translate(e.midpoint().minus(Point.ORIGIN))
+ .times(reflectionMatrix)
+ .times(Matrix.translate(Point.ORIGIN.minus(e.midpoint()))));
+ */
+ System.out.println(reflectionPlaneNormal);
+ System.out.println(" " + p1.p + " " + m.times(e.p1.p));
+ System.out.println(" " + p2.p + " " + m.times(e.p2.p));
+ if (m.times(e.p1.p).minus(p1.p).mag() > EPSILON) throw new Error();
+ if (m.times(e.p2.p).minus(p2.p).mag() > EPSILON) throw new Error();
+ this.bindTo(m, e);
+ }
+
+ public void dobind() {
+ //bind_to.dobind(this);
+ for(E e : (Iterable<E>)getBoundPeers()) {
+ if (e==this) continue;
+ p1.bindTo(getBindingMatrix(e), e.p1);
+ p2.bindTo(getBindingMatrix(e), e.p2);
+ }
+ }
public Point shatter() { return shatter(true); }
public Point shatter(boolean triangles) { return shatter(midpoint(), null, null, 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;
+ */
return true;
}
for(Matrix m : translations) {
//if (v1.z==0 && v1.y==0) continue;
i++;
- if (i!=2&&i!=5) continue;
+ //if (i!=2&&i!=5) 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, safeTriangles);
+ draw(gl, false, safeTriangles);
gl.glTranslatef(-v.x, -v.y, -v.z);
}
//gl.glEnable(GL.GL_DEPTH_TEST);
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));
+ if (getBindingMatrix(other).equals(bindingMatrix)) return;
+ throw new Error("rebind attempt: "+this+" and "+other+" with "
+ + bindingMatrix
+ + "; expected "
+ + getBindingMatrix(other));
}
bindingMatrix =
return bindingGroup.getMatrix(this);
}
+ public Matrix getBindingMatrix(HasBindingGroup other) {
+ return bindingGroup.getMatrix(this, other);
+ }
+
public HasBindingGroup getMaster() {
if (bindingGroup==null) return this;
return bindingGroup.getMaster();
return bindingGroup.contains(t);
}
- public Iterable getBoundPeers() { return bindingGroup; }
+ public Iterable getBoundPeers() {
+ if (bindingGroup==null) bindingGroup = new BindingGroup(this);
+ return bindingGroup;
+ }
public void bindingGroupChanged(BindingGroup newBindingGroup) { }
}
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;
+ near(a,z.a) &&
+ near(b,z.b) &&
+ near(c,z.c) &&
+ near(d,z.d) &&
+ near(e,z.e) &&
+ near(f,z.f) &&
+ near(g,z.g) &&
+ near(h,z.h) &&
+ near(i,z.i) &&
+ near(j,z.j) &&
+ near(k,z.k) &&
+ near(l,z.l) &&
+ near(m,z.m) &&
+ near(n,z.n) &&
+ near(o,z.o) &&
+ near(p,z.p);
}
+ private static final float EPSILON = 0.001f;
+ private static boolean near(float a, float b) { return a==b; }
public int hashCode() {
return
public Point(double x, double y, double z) { this((float)x, (float)y, (float)z); }
public Point(float x, float y, float z) { this.x = x; this.y = y; this.z = z; }
+ public static final Point ORIGIN = new Point(0,0,0);
+
public float distance(Point p) { return (float)Math.sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y)+(z-p.z)*(z-p.z)); }
+ // FIXME: this should be eliminated; wrong order
public Point times(Matrix m) { return m.times(this); }
+
public Vec minus(Point p) { return new Vec(x-p.x, y-p.y, z-p.z); }
public Point plus(Vec v) { return new Point(x+v.x, y+v.y, z+v.z); }