checkpoint
[anneal.git] / src / edu / berkeley / qfat / bind / HasBindingGroup.java
index ea97472..b9b85b8 100644 (file)
@@ -1,58 +1,65 @@
 package edu.berkeley.qfat.bind;
 import edu.berkeley.qfat.geom.*;
-import javax.media.opengl.*;
-import java.util.*;
-import edu.berkeley.qfat.Mesh;
 
 /**
  *  A member of an equivalence class of geometric objects whose
  *  positions are related by affine transformation matrices and are
  *  constrained by an affine constraint.
+ *
+ *  Every HasBindingGroup (henceforth, HBG) begins life as a member of
+ *  a singleton binding group consisting only of itself.
+ *
+ *  Invoking bindTo() upon a pair of HBG's that are not part of the
+ *  same BindingGroup will merge the two BG's.  Invoking bindTo() upon
+ *  a pair of HBG's that are already part of the same BG will result
+ *  in the imposition of an AffineConstraint on the BG.
  */
 public abstract class HasBindingGroup {
 
-    private BindingGroup bindingGroup;
+    BindingGroup bindingGroup;
 
-    // know:      self   = bindingGroup[self] * master
-    // know:      other  = other.bindingGroup[other] * other.bindingGroup.master
-    // want:      self   = bindingMatrix * other
-    // therefore: master = bindingGroup[self]^-1 * bindingMatrix * other
-    // therefore:        = bindingGroup[self]^-1 * bindingMatrix * other.bindingGroup[other] * other.bindingGroup.master
-    public void bindTo(Matrix bindingMatrix, HasBindingGroup other) {
-        // FIXME
-        bindTo(bindingMatrix, other, 0.001f);
-    }
+    /**
+     *  Merge the BGs of this and other, ensuring that
+     *  this==bindingMatrix*other, and treating differences of less
+     *  than epsilon as irrelevant for AffineConstraint purposes.
+     */
     public void bindTo(Matrix bindingMatrix, HasBindingGroup other, float epsilon) {
+        // know:      self   = bindingGroup[self] * master
+        // know:      other  = other.bindingGroup[other] * other.bindingGroup.master
+        // want:      self   = bindingMatrix * other
+        // therefore: master = bindingGroup[self]^-1 * bindingMatrix * other
+        // therefore:        = bindingGroup[self]^-1 * bindingMatrix * other.bindingGroup[other] * other.bindingGroup.master
         if (bindingGroup == null) bindingGroup = new BindingGroup(this);
         if (other.bindingGroup == null) other.bindingGroup = new BindingGroup(other);
 
+        Matrix bm = bindingGroup.getMatrix(this);
+        Matrix obm = other.bindingGroup.getMatrix(other);
         bindingMatrix =
-            getBindingMatrix().inverse()
+            bm.inverse()
             .times(bindingMatrix)
-            .times(other.getBindingMatrix());
+            .times(obm);
         other.bindingGroup.merge(bindingGroup, bindingMatrix, epsilon);
     }
 
+    /** number of distinct HBG's in the binding group */
     public int bindingGroupSize() {
         if (bindingGroup == null) return 1;
         return bindingGroup.size();
     }
 
+    /** returns the AffineConstraint of this BG, translated into this HBG's space */
     public AffineConstraint getBindingConstraint() {
         if (bindingGroup==null) return new AffineConstraint.All();
         return bindingGroup.getAffineConstraint(this);
     }
 
-    public Matrix getBindingMatrix() {
-        if (bindingGroup==null) return Matrix.ONE;
-        return bindingGroup.getMatrix(this);
-    }
-
+    /** return the matrix M which relates the position p2 of other to the position p1 of this; p1=M*p2 */
     public Matrix getBindingMatrix(HasBindingGroup other) {
         if (other==this) return Matrix.ONE;
         return bindingGroup.getMatrix(this, other);
     }
 
+    /** remove this HBG from its BG and place it in its own individual BG */
     public void unbind() {
         if (bindingGroup==null) return;
         bindingGroup.unbind(this);
@@ -60,13 +67,18 @@ public abstract class HasBindingGroup {
         bindingGroupChanged();
     }
 
+    /** true iff this HBG is in the same BG as the argument */
     public boolean isBoundTo(HasBindingGroup t) {
         return t==this || (bindingGroup!=null && bindingGroup.contains(t));
     }
 
+    /** enumerates all members of this HBG's BG, including this */
     public Iterable getBoundPeers() {
         if (bindingGroup==null) bindingGroup = new BindingGroup(this);
         return bindingGroup;
     }
-    public void bindingGroupChanged() { }
+
+    /** invoked after the binding group of this HBG has changed due to bindTo() or unbind() */
+    public void bindingGroupChanged() {
+    }
 }