+ pair.destroy();
+ T t1 = newT(v1, v2, this.v2);
+ T t2 = newT(v2, v1, this.v1);
+ t1.e1().sanity();
+ t1.e2().sanity();
+ t1.e3().sanity();
+ t2.e1().sanity();
+ t2.e2().sanity();
+ t2.e3().sanity();
+
+ for (E e : (Iterable<E>)getBoundPeers()) {
+ if (e==this) continue;
+ if (e.destroyed) continue;
+ Vertex v1e = e.t.getOtherVertex(e);
+ Vertex v2e = e.pair.t.getOtherVertex(e.pair);
+ e.destroy();
+ e.pair.destroy();
+ if (v1e.getE(v2e)!=null) throw new RuntimeException();
+ newT(v1e, v2e, e.v2).red = true;
+ newT(v2e, v1e, e.v1).red = true;
+ v2e.getE(v1e).bindTo(e.getBindingMatrix(this), v1.getE(v2));
+ v1e.getE(v2e).bindTo(e.pair.getBindingMatrix(this.pair), v2.getE(v1));
+ }
+
+ }
+
+ public void bindingGroupChanged() {
+ HashSet<E> nbg = new HashSet<E>();
+ for(E eother : (Iterable<E>)getBoundPeers()) nbg.add(eother);
+ for(E eother : nbg) {
+ if (next==null || prev==null) continue;
+ if (eother.next==null || eother.prev==null) continue;
+
+ Matrix m = getBindingMatrix(eother);
+ if (next.isBoundTo(eother.pair.prev.pair) &&
+ !prev.isBoundTo(eother.pair.next.pair) &&
+ m.equalsModuloEpsilon(next.getBindingMatrix(eother.pair.prev.pair), EPSILON))
+ prev.bindEdge(next.getBindingMatrix(eother.pair.prev.pair), eother.pair.next.pair);
+ if (!next.isBoundTo(eother.pair.prev.pair) &&
+ prev.isBoundTo(eother.pair.next.pair) &&
+ m.equalsModuloEpsilon(prev.getBindingMatrix(eother.pair.next.pair), EPSILON))
+ next.bindEdge(prev.getBindingMatrix(eother.pair.next.pair), eother.pair.prev.pair);
+
+ //if (next.isBoundTo(eother.prev) && !prev.isBoundTo(eother.next))
+ //prev.bindTo(next.getBindingMatrix(eother.prev), eother.next);
+ //if (!next.isBoundTo(eother.prev) && prev.isBoundTo(eother.next))
+ //next.bindTo(prev.getBindingMatrix(eother.next), eother.prev);
+
+ if (next.isBoundTo(eother.next) &&
+ !prev.isBoundTo(eother.prev) &&
+ m.equalsModuloEpsilon(next.getBindingMatrix(eother.next), EPSILON))
+ prev.bindEdge(next.getBindingMatrix(eother.next), eother.prev);
+ if (!next.isBoundTo(eother.next) &&
+ prev.isBoundTo(eother.prev) &&
+ m.equalsModuloEpsilon(prev.getBindingMatrix(eother.prev), EPSILON))
+ next.bindEdge(prev.getBindingMatrix(eother.prev), eother.next);
+
+ }
+
+ }
+
+ public float stretchRatio() {
+ Vertex nearest = error_against.nearest(midpoint());
+ float nearest_distance = midpoint().distance(nearest.p);
+ float other_distance =
+ (v1.p.distance(error_against.nearest(v1.p).p)+
+ v2.p.distance(error_against.nearest(v2.p).p))/2;
+ return nearest_distance/other_distance;
+ }
+ public float comparator() {
+ return length();
+ }
+ public int compareTo(E e) {
+ return e.comparator() > comparator() ? 1 : -1;
+ }
+ public void bindEdge(Matrix m, E e) {
+ bindEdge(e, m);
+ }
+ public void bindEdge(E e, Matrix m) {
+ /*
+ for(E e_ : (Iterable<E>)e.getBoundPeers()) {
+ if (e.v1.getPoint().distance((e.getBindingMatrix(e_).times(e_.v1.getPoint()))) > 0.01f)
+ throw new RuntimeException("blah! " + e.v1.getPoint() + " " + e.getBindingMatrix(e_).times(e_.v1.getPoint()));
+ if (e.v2.getPoint().distance((e.getBindingMatrix(e_).times(e_.v2.getPoint()))) > 0.01f)
+ throw new RuntimeException("blah! " + e.v2.getPoint() + " " + e.getBindingMatrix(e_).times(e_.v2.getPoint()));
+ if (v1.getPoint().distance(m.times(e.getBindingMatrix(e_).times(e_.v1.getPoint()))) > 0.01f)
+ throw new RuntimeException("blah! " + v1.getPoint() + " " + m.times(e_.v1.getPoint()));
+ if (v2.getPoint().distance(m.times(e.getBindingMatrix(e_).times(e_.v2.getPoint()))) > 0.01f)
+ throw new RuntimeException("blah! " + v2.getPoint() + " " + m.times(e_.v2.getPoint()));
+ }
+ */
+ this.bindTo(m, e, EPSILON);
+ this.pair.bindTo(m, e.pair, EPSILON);
+ }
+
+ public void dobind() {
+ for(E e : (Iterable<E>)getBoundPeers()) {
+ if (e==this) continue;
+ v1.bindTo(getBindingMatrix(e), e.v1);
+ v2.bindTo(getBindingMatrix(e), e.v2);
+ }
+ }