*/
Point op = this.p;
- Point pp = vv.plus(getPoint());
- if (bindingGroup != null) {
- /*
- for(int i=0; i<20 ; i++) {
- Point v2 = getConstraint().times(pp);
- pp = pp.midpoint(v2);
- //System.out.println(m.minus(m2));
- }
- */
- //pp = getConstraint().times(pp);
- }
- //pp = pp.minus(op).norm().times(vv.mag()).plus(op);
- ok = false;
- Point pt = pp;
+ Point pt = vv.plus(getPoint());
+ Point pp = pt;
+ pt = getBindingConstraint().getProjection(pp);
+ if (pt==null) return false;
+ System.out.println(pt.minus(pp).mag() + " " + getBindingConstraint());
+
for(Vertex v : (Iterable<Vertex>)getBoundPeers()) {
Point pt2 = v.getBindingMatrix(this).times(pt);
/*
public void merge(BindingGroup<T> bg, Matrix m) {
if (bg==this) {
if (m.equalsModuloEpsilon(Matrix.ONE, 0.001f)) return;
- System.err.println(m.getAffineConstraint(0.001f));
+ constraint = constraint.intersect(m.getAffineConstraint(0.001f), 0.001f);
return;
}
return bindingGroup.size();
}
+ public AffineConstraint getBindingConstraint() {
+ if (bindingGroup==null) return new AffineConstraint.All();
+ return bindingGroup.getConstraint(this);
+ }
public Matrix getBindingMatrix() {
if (bindingGroup==null) return Matrix.ONE;
/** the line passing through two points */
public Line(Point p1, Point p2) {
+ // FIXME: division by zero?
this.m = (p2.y-p1.y)/(p2.x-p1.x);
this.n = (p2.z-p1.z)/(p2.x-p1.x);
this.c = p1.y - m * p1.x;
this.d = p1.z - n * p1.x;
}
+ /** the line passing through p1 with direction v */
+ public Line(Point p1, Vec v) {
+ this(p1, v.plus(p1));
+ }
+
public int hashCode() {
return
Float.floatToIntBits(m) ^
/** returns the point on this line which is closest to p */
public Point getProjection(Point p) {
- /*
Point p1 = new Point(0, c, d);
Point p2 = new Point(1, m+c, n+d);
Vec w = p.minus(p1);
- return getUnit().times(w.dot(getUnit()));
- */
+ return p1.plus(getUnit().times(w.dot(getUnit())));
+ /*
throw new RuntimeException("test this before using; may not be correct");
+ */
}
public AffineConstraint intersect(AffineConstraint con, float epsilon) {
}
public AffineConstraint multiply(Matrix m) {
- throw new RuntimeException("not yet implemented");
+ // FIXME: ugly
+ Point p1 = new Point(0, c, d);
+ Point p2 = new Point(1, this.m+c, n+d);
+ return new Line(m.times(p1), m.times(p2));
}
}
public Vec norm() { return new Vec(a, b, c); }
public Plane(Point p, Vec norm) {
+ norm = norm.norm();
this.a = norm.x;
this.b = norm.y;
this.c = norm.z;
}
public AffineConstraint intersect(AffineConstraint c, float epsilon) {
- throw new RuntimeException("not implemented yet");
+ if (c instanceof Plane) {
+ Plane p = (Plane)c;
+
+ // same plane
+ if (Math.abs(p.a-this.a) <= epsilon &&
+ Math.abs(p.b-this.b) <= epsilon &&
+ Math.abs(p.c-this.c) <= epsilon &&
+ Math.abs(p.d-this.d) <= epsilon)
+ return this;
+
+ // parallel planes
+ if (Math.abs(p.norm().cross(norm()).mag()) <= epsilon)
+ return new AffineConstraint.Nothing();
+
+ Vec u = norm().cross(p.norm());
+ Point point = null;
+ if (Math.abs(u.z) >= Math.abs(u.y) && Math.abs(u.z) >= Math.abs(u.y)) {
+ point = new Point( (this.b*p.d - p.b*this.d)/(this.a*p.b - p.a*this.b),
+ (this.d*p.a - p.d*this.a)/(this.a*p.b - p.a*this.b),
+ 0);
+ } else if (Math.abs(u.y) >= Math.abs(u.z) && Math.abs(u.y) >= Math.abs(u.x)) {
+ point = new Point( (this.c*p.d - p.c*this.d)/(this.a*p.c - p.a*this.c),
+ 0,
+ (this.d*p.a - p.d*this.a)/(this.a*p.c - p.a*this.c));
+ } else {
+ point = new Point( 0,
+ (this.c*p.d - p.c*this.d)/(this.b*p.c - p.b*this.c),
+ (this.d*p.b - p.d*this.b)/(this.b*p.c - p.b*this.c));
+ }
+
+ return new Line(point, u);
+
+ } else if (c instanceof Line) {
+ Line l = (Line)c;
+ if ( Math.abs(a + b*l.m + this.c*l.n) <= epsilon &&
+ Math.abs(b * l.c + this.c * l.d + d) <= epsilon)
+ return l;
+ throw new RuntimeException("not yet implemented");
+
+ } else
+ return c.intersect(this, epsilon);
}
public AffineConstraint multiply(Matrix m) {
public Point getProjection(Point p) { return this; }
public AffineConstraint intersect(AffineConstraint c, float epsilon) {
if (c.getProjection(this).distance(this) <= epsilon) return this;
- return null;
+ System.err.println("off by: " + c.getProjection(this).distance(this));
+ return new AffineConstraint.Nothing();
}
public AffineConstraint multiply(Matrix m) { return m.times(this); }
}