+ }
+
+ 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);
+ }
+ }
+
+ public Vertex shatter() {
+ if (shattered || destroyed) return nearest(midpoint());
+ shattered = true;
+ E first = null;
+ E firste = null;
+ E firstx = null;
+ E firstq = null;
+ for(E e : (Iterable<E>)getBoundPeers()) {
+ E enext = e.next;
+ E eprev = e.prev;
+ E pnext = e.pair.next;
+ E pprev = e.pair.prev;
+ Point mid = e.midpoint();
+ Vertex r = e.next.v2;
+ Vertex l = e.pair.next.v2;
+ if (!e.destroyed) {
+ e.destroy();
+ e.pair.destroy();
+ newT(r.p, e.v1.p, mid, null, 0);
+ newT(r.p, mid, e.v2.p, null, 0);
+ newT(l.p, mid, e.v1.p, null, 0);
+ newT(l.p, e.v2.p, mid, null, 0);
+ }
+ }
+ for(E e : (Iterable<E>)getBoundPeers()) {
+ Point mid = e.midpoint();
+ if (first==null) {
+ first = e.v1.getE(mid);
+ firste = e;
+ firstx = e.pair;
+ firstq = e.v2.getE(mid).pair;
+ continue;
+ }
+ e.v1.getE(mid). bindTo(e.getBindingMatrix(firste), first);
+ e.v1.getE(mid).pair. bindTo(e.getBindingMatrix(firste), first.pair);
+ e.v2.getE(mid).pair. bindTo(e.getBindingMatrix(firste), firstq);
+ e.v2.getE(mid).pair.pair.bindTo(e.getBindingMatrix(firste), firstq.pair);
+ }
+ /*
+ first.setConstraint(firste.getAffineConstraint());
+ firstq.setConstraint(firste.getAffineConstraint());
+ */
+ return nearest(midpoint());