polygons.add(new Polygon(hs));
}
for(Polygon p : polygons) {
- System.out.println(p.plane.norm + " " + p.plane.dvalue);
+ System.out.println(p.plane.norm() + " " + p.plane.d);
for(HalfSpace hs : halfSpaces) {
if (p.plane==hs) continue;
p = p.intersect(hs);
public Point getProjection(Point p);
public AffineConstraint intersect(AffineConstraint c, float epsilon);
+ public AffineConstraint multiply(Matrix m);
public static class All implements AffineConstraint {
public Point getProjection(Point p) { return p; }
public AffineConstraint intersect(AffineConstraint c, float epsilon) { return c; }
+ public AffineConstraint multiply(Matrix m) { return this; }
}
public static class Nothing implements AffineConstraint {
public Point getProjection(Point p) { return null; }
public AffineConstraint intersect(AffineConstraint c, float epsilon) { return this; }
+ public AffineConstraint multiply(Matrix m) { return this; }
}
}
/** tracks an equivalence class of geometric objects which are related to each other by transformation matrices */
public class BindingGroup<T extends HasBindingGroup> implements Iterable<T> {
- private T master = null;
- private HashMap<T,Matrix> matrices = new HashMap<T,Matrix>();
+ private T master = null;
+ private AffineConstraint constraint = new AffineConstraint.All();
+ private HashMap<T,Matrix> matrices = new HashMap<T,Matrix>();
public BindingGroup(T master) {
this.master = master;
public int size() { return matrices.size(); }
public void merge(BindingGroup<T> bg, Matrix m) {
- if (bg==this) throw new Error();
+ if (bg==this) {
+ if (m.equalsModuloEpsilon(Matrix.ONE, 0.001f)) return;
+ System.err.println(m.getAffineConstraint(0.001f));
+ return;
+ }
+
for(HasBindingGroup hbg : bg.matrices.keySet()) {
matrices.put((T)hbg, bg.matrices.get(hbg).times(m));
hbg.bindingGroup = this;
}
- Matrix v = getMatrix(bg.master, master);
+ // 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<HasBindingGroup> stuff = new HashSet<HasBindingGroup>();
for(HasBindingGroup hbg : bg.matrices.keySet())
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);
public HalfSpace(Point p, Vec norm) { super(p, norm); }
public boolean contains(Point p, float epsilon) {
- return p.x*norm.x+p.y*norm.y+p.z*norm.z + dvalue <= epsilon;
+ return p.x*norm().x+p.y*norm().y+p.z*norm().z + d <= epsilon;
}
}
if (bindingGroup == null) bindingGroup = new BindingGroup(this);
if (other.bindingGroup == null) other.bindingGroup = new BindingGroup(other);
- if (other.bindingGroup == this.bindingGroup) {
- if (getBindingMatrix(other).equalsModuloEpsilon(bindingMatrix, 0.001f))
- return;
- return;
- }
-
bindingMatrix =
getBindingMatrix().inverse()
.times(bindingMatrix)
return new Point(x, m*x+c, n*x+d);
}
+ public AffineConstraint multiply(Matrix m) {
+ throw new RuntimeException("not yet implemented");
+ }
+
}
}
/** returns the constraint-conjunction "(forall v)Mv=v" */
- public AffineConstraint getConstraint(float epsilon) {
+ public AffineConstraint getAffineConstraint(float epsilon) {
AffineConstraint c1 = getConstraint(a-1, b, c, d , epsilon);
AffineConstraint c2 = getConstraint(e, f-1, g, h , epsilon);
AffineConstraint c3 = getConstraint(i, j, k-1, l , epsilon);
public class Plane implements AffineConstraint {
- // FIXME: could be given by
// ax+by+cz=d
+ public final float a, b, c, d;
- public final Vec norm;
- public final float dvalue;
+ public Vec norm() { return new Vec(a, b, c); }
public Plane(Point p, Vec norm) {
- this.norm = norm.norm();
- this.dvalue = p.x*this.norm.x+p.y*this.norm.y+p.z*this.norm.z;
+ this.a = norm.x;
+ this.b = norm.y;
+ this.c = norm.z;
+ this.d = p.x*norm.x+p.y*norm.y+p.z*norm.z;
}
/** provided at least one of a,b,c is nonzero, return the Plane representing ax+by+cz=d */
public Plane(float a, float b, float c, float d) {
- throw new RuntimeException("not implemented yet");
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ this.d = d;
}
public Point intersect(Plane p1, Plane p2) {
+ Vec norm = norm();
Plane p3 = this;
- float z = p1.norm.dot(p2.norm.cross(p3.norm));
+ float z = p1.norm().dot(p2.norm().cross(p3.norm()));
if (Math.abs(z) < 0.0001) return null; // planes do not intersect at a point
- Vec v1 = p2.norm.cross(p3.norm).times(-1 * p1.dvalue);
- Vec v2 = p3.norm.cross(p1.norm).times(-1 * p2.dvalue);
- Vec v3 = p1.norm.cross(p2.norm).times(-1 * p3.dvalue);
+ Vec v1 = p2.norm().cross(p3.norm()).times(-1 * p1.d);
+ Vec v2 = p3.norm().cross(p1.norm()).times(-1 * p2.d);
+ Vec v3 = p1.norm().cross(p2.norm()).times(-1 * p3.d);
return Point.ZERO.plus(v1.plus(v2).plus(v3).times(1/z));
}
public AffineConstraint intersect(AffineConstraint c, float epsilon) {
throw new RuntimeException("not implemented yet");
}
+
+ public AffineConstraint multiply(Matrix m) {
+ throw new RuntimeException("not yet implemented");
+ }
}
if (c.getProjection(this).distance(this) <= epsilon) return this;
return null;
}
+ public AffineConstraint multiply(Matrix m) { return m.times(this); }
}
//centroid = new Point(round(centroid.x), round(centroid.y), round(centroid.z));
if (segments.size() >= 3)
for(Segment s : segments) {
- System.out.println("newt! " + s.p1 + " " + centroid + " " + s.p2 + " " + plane.norm.times(-1));
- mesh.newT(s.p1, centroid, s.p2, plane.norm.times(-1), 0);
+ System.out.println("newt! " + s.p1 + " " + centroid + " " + s.p2 + " " + plane.norm().times(-1));
+ mesh.newT(s.p1, centroid, s.p2, plane.norm().times(-1), 0);
}
System.out.println("done");
return null;