X-Git-Url: http://git.megacz.com/?p=anneal.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fqfat%2Fbind%2FBindingGroup.java;h=6b06b47b44fcee8f213e20871e155ce5977b944c;hp=0882fa500bb7d65d2b59ce62f55d13712d372001;hb=HEAD;hpb=f018c9f76356b71ee3560595f6d236a76a7d13eb diff --git a/src/edu/berkeley/qfat/bind/BindingGroup.java b/src/edu/berkeley/qfat/bind/BindingGroup.java index 0882fa5..6b06b47 100644 --- a/src/edu/berkeley/qfat/bind/BindingGroup.java +++ b/src/edu/berkeley/qfat/bind/BindingGroup.java @@ -1,64 +1,82 @@ package edu.berkeley.qfat.bind; import edu.berkeley.qfat.geom.*; -import javax.media.opengl.*; import java.util.*; -/** tracks an equivalence class of geometric objects which are related to each other by transformation matrices */ -public class BindingGroup implements Iterable { +/** + * An equivalence class of geometric objects whose positions are + * related by affine transformation matrices and are constrained by + * an affine constraint. + */ +class BindingGroup implements Iterable { + /** the arbitrarily-chosen master of the binding group */ private T master = null; - private AffineConstraint constraint = new AffineConstraint.All(); + + /** the affine constraint, in master coordinates, of this binding group */ + private AffineConstraint constraint = AffineConstraint.ALL; + + /** + * For each member of the binding group, the matrix which must be + * multiplied by the master to get the member's position + */ private HashMap matrices = new HashMap(); - public BindingGroup(T master) { + BindingGroup(T master) { this.master = master; matrices.put(master, Matrix.ONE); } - public int size() { return matrices.size(); } + /** the size of this binding group */ + int size() { return matrices.size(); } - public void merge(BindingGroup bg, Matrix m) { + /** merge another binding group into this one */ + void merge(BindingGroup bg, Matrix m, float epsilon) { if (bg==this) { - if (m.equalsModuloEpsilon(Matrix.ONE, 0.001f)) return; - constraint = constraint.intersect(m.getAffineConstraint(0.001f), 0.001f); + if (m.equalsModuloEpsilon(Matrix.ONE, epsilon)) return; + /* + if (master instanceof edu.berkeley.qfat.Mesh.Vertex) + System.err.println(m.times(m)); + */ + // FIXME: what if points do not fall on the merged constraint-line? + constraint = constraint.intersect(m.getAffineConstraint(epsilon), epsilon); return; } - for(HasBindingGroup hbg : bg.matrices.keySet()) { - matrices.put((T)hbg, bg.matrices.get(hbg).times(m)); + // bg.master = m * master + // hbg = bg.getMatrix(hbg) * bg.master + // hbg = bg.getMatrix(hbg) * m * master + for(HasBindingGroup hbg : bg) { + matrices.put((T)hbg, bg.getMatrix((T)hbg).times(m)); hbg.bindingGroup = this; } // FIXME: what if points do not fall on the merged constraint-line? AffineConstraint ac = bg.constraint.multiply(getMatrix(master, bg.master)); - constraint = constraint.intersect(ac, 0.001f); + constraint = constraint.intersect(ac, epsilon); - HashSet stuff = new HashSet(); - for(HasBindingGroup hbg : bg.matrices.keySet()) - stuff.add(hbg); - bg.matrices.clear(); bg.master = null; - for(HasBindingGroup hbg : stuff) - hbg.bindingGroupChanged(this); + for(HasBindingGroup hbg : bg) hbg.bindingGroupChanged(); + bg.matrices.clear(); + bg.matrices = null; } - public Matrix getMatrix(T t) { return matrices.get(t); } + Matrix getMatrix(T t) { return matrices.get(t); } public Iterator iterator() { return matrices.keySet().iterator(); } /** t1 = getMatrix(t1, t2) * t2 */ - public Matrix getMatrix(T t1, T t2) { + 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 AffineConstraint getConstraint(T t) { + AffineConstraint getAffineConstraint(T t) { return constraint.multiply(matrices.get(t)); } - public void unbind(T trem) { + void unbind(T trem) { if (trem != master) { matrices.remove(trem); return; @@ -71,7 +89,11 @@ public class BindingGroup implements Iterable { Iterator it = iterator(); T newmaster = it.next(); if (newmaster==trem) newmaster = it.next(); - if (newmaster==trem) throw new Error(); + if (newmaster==trem) throw new Error("impossible"); + + // FIXME: is this correct? + constraint = constraint.multiply(getMatrix(newmaster, master)); + HashMap newmatrices = new HashMap(); for(T t : matrices.keySet()) { if (t==trem) continue; @@ -81,7 +103,7 @@ public class BindingGroup implements Iterable { matrices = newmatrices; } - public boolean contains(HasBindingGroup t) { + boolean contains(HasBindingGroup t) { return matrices.get((T)t) != null; } }