X-Git-Url: http://git.megacz.com/?p=anneal.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fqfat%2Fbind%2FBindingGroup.java;fp=src%2Fedu%2Fberkeley%2Fqfat%2Fbind%2FBindingGroup.java;h=0882fa500bb7d65d2b59ce62f55d13712d372001;hp=0000000000000000000000000000000000000000;hb=f018c9f76356b71ee3560595f6d236a76a7d13eb;hpb=eabe4f7acd947415f183290dc3269b2502a25a1c diff --git a/src/edu/berkeley/qfat/bind/BindingGroup.java b/src/edu/berkeley/qfat/bind/BindingGroup.java new file mode 100644 index 0000000..0882fa5 --- /dev/null +++ b/src/edu/berkeley/qfat/bind/BindingGroup.java @@ -0,0 +1,87 @@ +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 { + + private T master = null; + private AffineConstraint constraint = new AffineConstraint.All(); + private HashMap matrices = new HashMap(); + + public BindingGroup(T master) { + this.master = master; + matrices.put(master, Matrix.ONE); + } + + public int size() { return matrices.size(); } + + public void merge(BindingGroup bg, Matrix m) { + if (bg==this) { + if (m.equalsModuloEpsilon(Matrix.ONE, 0.001f)) return; + constraint = constraint.intersect(m.getAffineConstraint(0.001f), 0.001f); + return; + } + + for(HasBindingGroup hbg : bg.matrices.keySet()) { + matrices.put((T)hbg, bg.matrices.get(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); + + 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); + } + + public 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) { + // 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) { + return constraint.multiply(matrices.get(t)); + } + + public void unbind(T trem) { + if (trem != master) { + matrices.remove(trem); + return; + } + if (matrices.size()==1) { + master = null; + matrices.remove(trem); + return; + } + Iterator it = iterator(); + T newmaster = it.next(); + if (newmaster==trem) newmaster = it.next(); + if (newmaster==trem) throw new Error(); + HashMap newmatrices = new HashMap(); + for(T t : matrices.keySet()) { + if (t==trem) continue; + newmatrices.put(t, getMatrix(t, newmaster)); + } + master = newmaster; + matrices = newmatrices; + } + + public boolean contains(HasBindingGroup t) { + return matrices.get((T)t) != null; + } +}