checkpoint i think it works!
[anneal.git] / src / edu / berkeley / qfat / geom / BindingGroup.java
index ca07312..5f6bf2b 100644 (file)
@@ -2,7 +2,7 @@ package edu.berkeley.qfat.geom;
 import javax.media.opengl.*;
 import java.util.*;
 
-public class BindingGroup<T extends HasBindingGroup> {
+public class BindingGroup<T extends HasBindingGroup> implements Iterable<T> {
 
     private T                  master   = null;
     private HashMap<T,Matrix>  matrices = new HashMap<T,Matrix>();
@@ -12,11 +12,16 @@ public class BindingGroup<T extends HasBindingGroup> {
         matrices.put(master, Matrix.ONE);
     }
 
+    public int size() { return matrices.size(); }
+
     public void merge(BindingGroup<T> bg, Matrix m) {
+        if (bg==this) throw new Error();
         for(HasBindingGroup hbg : bg.matrices.keySet()) {
             matrices.put((T)hbg, bg.matrices.get(hbg).times(m));
             hbg.bindingGroup = this;
         }
+        for(HasBindingGroup hbg : bg.matrices.keySet())
+            hbg.bindingGroupChanged(this);
         bg.matrices.clear();
         bg.master = null;
     }
@@ -24,12 +29,40 @@ public class BindingGroup<T extends HasBindingGroup> {
     public T getMaster() { return master; }
     public Matrix getMatrix(T t) { return matrices.get(t); }
 
-    //                    t1 = getMatrix(t1) * master
-    // getMatrix(t2)^-1 * t2 =                 master
-    //                    t1 = getMatrix(t1) * getMatrix(t2)^-1 * t2
+    public Iterator<T> 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 void unbind(T trem) {
+        if (trem != master) {
+            matrices.remove(trem);
+            return;
+        }
+        if (matrices.size()==1) {
+            master = null;
+            matrices.remove(trem);
+            return;
+        }
+        Iterator<T> it = iterator();
+        T newmaster = it.next();
+        if (newmaster==trem) newmaster = it.next();
+        if (newmaster==trem) throw new Error();
+        HashMap<T,Matrix> newmatrices = new HashMap<T,Matrix>();
+        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;
+    }
 }