+ pair.destroy();
+ newT(v1, v2, p2).red = true;
+ newT(v2, v1, p1).red = true;
+ for (E e : (Iterable<E>)getBoundPeers()) {
+ 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.p2).red = true;
+ newT(v2e, v1e, e.p1).red = true;
+ makeE(v1.getPoint(),
+ v2.getPoint()).bindTo(this.getBindingMatrix(e), makeE(v1e.getPoint(), v2e.getPoint()));
+ makeE(v2.getPoint(),
+ v1.getPoint()).bindTo(pair.getBindingMatrix(e.pair), makeE(v2e.getPoint(), v1e.getPoint()));
+
+ }
+ }
+
+ public void bindingGroupChanged(edu.berkeley.qfat.geom.BindingGroup newBindingGroup_) {
+
+ edu.berkeley.qfat.geom.BindingGroup<E> newBindingGroup =
+ (edu.berkeley.qfat.geom.BindingGroup<E>)newBindingGroup_;
+ if (newBindingGroup==null) return;
+ if (this==newBindingGroup.getMaster()) return;
+ HashSet<E> nbg = new HashSet<E>();
+ for(E eother : (Iterable<E>)newBindingGroup) nbg.add(eother);
+ for(E eother : nbg) {
+ if (next==null || prev==null) continue;
+ if (eother.next==null || eother.prev==null) continue;
+
+ if (next.isBoundTo(eother.pair.prev.pair) && !prev.isBoundTo(eother.pair.next.pair))
+ prev.bindTo(next.getBindingMatrix(eother.pair.prev.pair), eother.pair.next.pair);
+ if (!next.isBoundTo(eother.pair.prev.pair) && prev.isBoundTo(eother.pair.next.pair))
+ next.bindTo(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))
+ prev.bindTo(next.getBindingMatrix(eother.next), eother.prev);
+ if (!next.isBoundTo(eother.next) && prev.isBoundTo(eother.prev))
+ next.bindTo(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 =
+ (p1.p.distance(error_against.nearest(p1.p).p)+
+ p2.p.distance(error_against.nearest(p2.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(E e, Matrix m) {
+ _bindEdge(e, m);
+ pair._bindEdge(e.pair, m);
+ }
+ public void _bindEdge(E e, Matrix m) {
+ e = e.pair;
+ /*
+ //assumes edges are identical length at binding time
+ 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() {
+ for(E e : (Iterable<E>)getBoundPeers()) {
+ if (e==this) continue;
+ p1.bindTo(getBindingMatrix(e), e.p1);
+ p2.bindTo(getBindingMatrix(e), e.p2);
+ e.p1.setConstraint(getConstraint());
+ e.p2.setConstraint(getConstraint());
+ }
+ }