From: adam Date: Sun, 6 Jul 2008 23:11:17 +0000 (-0700) Subject: checkpoint X-Git-Url: http://git.megacz.com/?p=anneal.git;a=commitdiff_plain;h=de2400d58116bd995e73baf7a429e22def1e4067 checkpoint darcs-hash:20080706231117-5007d-de586d390c28106ebfa766feead15a7914f83723.gz --- diff --git a/src/edu/berkeley/qfat/Main.java b/src/edu/berkeley/qfat/Main.java index 8683a75..ac40acc 100644 --- a/src/edu/berkeley/qfat/Main.java +++ b/src/edu/berkeley/qfat/Main.java @@ -97,7 +97,7 @@ public class Main extends InteractiveMeshViewer { if (v.mag() < 0.0001) continue; v = v.times(-1); v = v.times(0.5f); - Point p = Point.ORIGIN.plus(v); + Point p = Point.ZERO.plus(v); v = v.times(-1); //System.out.println(v); @@ -784,7 +784,7 @@ public class Main extends InteractiveMeshViewer { //Matrix m = Matrix.scale(1f, 2.1f, 1f); tile.transform(m); for(int i=0; i { float minangle = (float)(Math.PI * 0.8); //nerror += ((ang / Math.PI)*(ang/Math.PI)) * e.length() * 0.05; - nerror += (1-e.t.quality())*0.0001; + //nerror += (1-e.t.quality())*0.0001; if (ang > minangle) nerror += (ang - minangle); //System.out.println(((ang / Math.PI)*(ang/Math.PI)) * 0.000001); @@ -399,11 +399,13 @@ public class Mesh implements Iterable { // t1 = t1.getMatrix(t2) * t2 // M * t1 = M * t1.getMatrix(t2) * t2 + /* if (bindingGroup!=null && this != bindingGroup.getMaster()) { Matrix m2 = getBindingMatrix(bindingGroup.getMaster()); Vec v2 = m2.times(vv.plus(getPoint())).minus(m2.times(getPoint())); return ((Vertex)bindingGroup.getMaster()).move(v2, ignoreProblems); } + */ Point op = this.p; Point pp = vv.plus(getPoint()); @@ -621,7 +623,7 @@ public class Mesh implements Iterable { edu.berkeley.qfat.geom.BindingGroup newBindingGroup = (edu.berkeley.qfat.geom.BindingGroup)newBindingGroup_; if (newBindingGroup==null) return; - if (this==newBindingGroup.getMaster()) return; + //if (this==newBindingGroup.getMaster()) return; HashSet nbg = new HashSet(); for(E eother : (Iterable)newBindingGroup) nbg.add(eother); for(E eother : nbg) { @@ -697,8 +699,10 @@ public class Mesh implements Iterable { if (e==this) continue; v1.bindTo(getBindingMatrix(e), e.v1); v2.bindTo(getBindingMatrix(e), e.v2); + /* e.v1.setConstraint(getConstraint()); e.v2.setConstraint(getConstraint()); + */ } } diff --git a/src/edu/berkeley/qfat/geom/BindingGroup.java b/src/edu/berkeley/qfat/geom/BindingGroup.java index 0c3049f..4c2d114 100644 --- a/src/edu/berkeley/qfat/geom/BindingGroup.java +++ b/src/edu/berkeley/qfat/geom/BindingGroup.java @@ -2,6 +2,7 @@ package 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 { public Matrix krank = Matrix.ONE; @@ -36,7 +37,6 @@ public class BindingGroup implements Iterable { hbg.bindingGroupChanged(this); } - public T getMaster() { return master; } public Matrix getMatrix(T t) { return matrices.get(t); } public Iterator iterator() { return matrices.keySet().iterator(); } diff --git a/src/edu/berkeley/qfat/geom/HalfSpace.java b/src/edu/berkeley/qfat/geom/HalfSpace.java index ebbd796..a48a22c 100644 --- a/src/edu/berkeley/qfat/geom/HalfSpace.java +++ b/src/edu/berkeley/qfat/geom/HalfSpace.java @@ -5,32 +5,8 @@ public final class HalfSpace extends Plane { public HalfSpace(Point p, Vec norm) { super(p, norm); } - /* - public Segment clip(Segment s) { - // FIXME: return null if segment is entirely excluded - throw new Error(); + public boolean contains(Point p, float epsilon) { + return p.x*norm.x+p.y*norm.y+p.z*norm.z + dvalue <= epsilon; } - - public Point intersect(Segment s) { - } - - public HalfPlane intersect(Plane p) { - if (norm.minus(hs.norm).mag() < 0.001) - throw new Error("half-spaces are nearly parallel"); - - } - */ - - public boolean contains(Point p) { - float checker = p.x*norm.x+p.y*norm.y+p.z*norm.z + dvalue; - //System.out.println(norm+" "+dvalue+" contains " + p + " => " + checker); - return checker <= 0.00001; - } - - public boolean contains(HalfSpace hs) { - // FIXME - return false; - } - } diff --git a/src/edu/berkeley/qfat/geom/HasBindingGroup.java b/src/edu/berkeley/qfat/geom/HasBindingGroup.java index 65d581f..ecc4f1c 100644 --- a/src/edu/berkeley/qfat/geom/HasBindingGroup.java +++ b/src/edu/berkeley/qfat/geom/HasBindingGroup.java @@ -17,27 +17,11 @@ public abstract class HasBindingGroup { if (other.bindingGroup == null) other.bindingGroup = new BindingGroup(other); if (other.bindingGroup == this.bindingGroup) { - if (getBindingMatrix(other).equals(bindingMatrix)) + if (getBindingMatrix(other).equalsModuloEpsilon(bindingMatrix, 0.001f)) return; - /* - if (this instanceof Mesh.E) - throw new Error("rebind attempt: "+this+" and "+other+" with " - + bindingMatrix - + "; expected " - + getBindingMatrix(other)); - */ - setConstraint(bindingMatrix); - /* - System.err.println("WARNING: discarding rebind attempt: "+this+" and "+other+m); - */ - //" with " - //+ bindingMatrix - //+ "; expected " - //+ getBindingMatrix(other)); return; } - bindingMatrix = getBindingMatrix().inverse() .times(bindingMatrix) @@ -61,22 +45,6 @@ public abstract class HasBindingGroup { return bindingGroup.getMatrix(this, other); } - public HasBindingGroup getMaster() { - if (bindingGroup==null) return this; - return bindingGroup.getMaster(); - } - - public Matrix getConstraint() { - if (bindingGroup==null) return Matrix.ONE; - Matrix v = getBindingMatrix(getMaster()); - return v.inverse().times(bindingGroup.krank).times(v); - } - public void setConstraint(Matrix m) { - if (bindingGroup==null) bindingGroup = new BindingGroup(this); - Matrix v = getBindingMatrix(getMaster()); - bindingGroup.krank = bindingGroup.krank.times(v.inverse().times(m).times(v)); - } - public void unbind() { if (bindingGroup==null) return; bindingGroup.unbind(this); diff --git a/src/edu/berkeley/qfat/geom/Line.java b/src/edu/berkeley/qfat/geom/Line.java new file mode 100644 index 0000000..7fb9b86 --- /dev/null +++ b/src/edu/berkeley/qfat/geom/Line.java @@ -0,0 +1,55 @@ +package edu.berkeley.qfat.geom; +import javax.media.opengl.*; + +/** an infinitely long line in 3-space */ +public class Line { + + // y=mx+c + // z=nx+d + public final float m, n, c, d; + + /** the line passing through two points */ + public Line(Point p1, Point p2) { + 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; + } + + public int hashCode() { + return + Float.floatToIntBits(m) ^ + Float.floatToIntBits(n) ^ + Float.floatToIntBits(c) ^ + Float.floatToIntBits(d); + } + public boolean equals(Object o) { + if (o==null || !(o instanceof Line)) return false; + Line line = (Line)o; + return line.m==m && line.n==n && line.c==c && line.d==d; + } + + public String toString() { + return "[line: y="+m+"x+"+c+" z="+n+"x+"+d+"]"; + } + + public double distance(Point p) { return projection(p).distance(p); } + + /** returns the point on this line which is closest to p */ + public Point projection(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())); + */ + throw new RuntimeException("test this before using; may not be correct"); + } + + public Vec getUnit() { + Point p1 = new Point(0, c, d); + Point p2 = new Point(1, m+c, n+d); + return p2.minus(p1).norm(); + } + +} diff --git a/src/edu/berkeley/qfat/geom/Matrix.java b/src/edu/berkeley/qfat/geom/Matrix.java index e52b895..dda8285 100644 --- a/src/edu/berkeley/qfat/geom/Matrix.java +++ b/src/edu/berkeley/qfat/geom/Matrix.java @@ -80,6 +80,7 @@ public class Matrix { 0, 0, 0, 1); } + /** a reflection matrix across the plane passing through the origin with the specified normal */ public static Matrix reflect(Vec v) { Vec reflectionPlaneNormal = v.norm(); float a = reflectionPlaneNormal.x; @@ -92,9 +93,8 @@ public class Matrix { 0, 0, 0, 1); } - public Vec getTranslationalComponent() { - return new Vec(d, h, l); - } + /** returns the translational component of this matrix */ + public Vec getTranslationalComponent() { return this.times(Point.ZERO).minus(Point.ZERO); } public Matrix plus(Matrix x) { return new Matrix(a+x.a, b+x.b, c+x.c, d+x.d, e+x.e, f+x.f, g+x.g, h+x.h, i+x.i, j+x.j, k+x.k, l+x.l, m+x.m, n+x.n, o+x.o, p+x.p); @@ -116,9 +116,7 @@ public class Matrix { return ret; } - /** discards bottom row */ public Point times(Point p) { - // discards bottom row double x = a*p.x + b*p.y + c*p.z + d; double y = e*p.x + f*p.y + g*p.z + h; double z = i*p.x + j*p.y + k*p.z + l; @@ -126,19 +124,8 @@ public class Matrix { return new Point(x/q, y/q, z/q); } - /** discards bottom row */ public Vec times(Vec p) { - return new Vec(a*p.x + b*p.y + c*p.z + d, - e*p.x + f*p.y + g*p.z + h, - i*p.x + j*p.y + k*p.z + l); - } - - public Matrix preMultiplyTranslationalComponentBy(Matrix mm) { - Vec v = mm.times(getTranslationalComponent()); - return new Matrix(a, b, c, v.x, - e, f, g, v.y, - i, j, k, v.z, - m, n, o, 1); + return this.times(Matrix.translate(p)).getTranslationalComponent(); } /** multiply by another matrix */ @@ -273,25 +260,43 @@ public class Matrix { if (!(oo instanceof Matrix)) return false; Matrix z = (Matrix)oo; return - near(a,z.a) && - near(b,z.b) && - near(c,z.c) && - near(d,z.d) && - near(e,z.e) && - near(f,z.f) && - near(g,z.g) && - near(h,z.h) && - near(i,z.i) && - near(j,z.j) && - near(k,z.k) && - near(l,z.l) && - near(m,z.m) && - near(n,z.n) && - near(o,z.o) && - near(p,z.p); + (a==z.a) && + (b==z.b) && + (c==z.c) && + (d==z.d) && + (e==z.e) && + (f==z.f) && + (g==z.g) && + (h==z.h) && + (i==z.i) && + (j==z.j) && + (k==z.k) && + (l==z.l) && + (m==z.m) && + (n==z.n) && + (o==z.o) && + (p==z.p); + } + + public boolean equalsModuloEpsilon(Matrix z, float epsilon) { + return + Math.abs(a-z.a) implements Iterable { return rtree.nearest(p, vis); } - // FEATURE: compute incrementally? public Vec diagonal() { float min_x = Float.MAX_VALUE; float min_y = Float.MAX_VALUE; diff --git a/src/edu/berkeley/qfat/geom/Polygon.java b/src/edu/berkeley/qfat/geom/Polygon.java index ff75939..2afa144 100644 --- a/src/edu/berkeley/qfat/geom/Polygon.java +++ b/src/edu/berkeley/qfat/geom/Polygon.java @@ -45,7 +45,7 @@ public final class Polygon { for(int k=0; k= 3) for(Segment s : segments) { diff --git a/src/edu/berkeley/qfat/geom/Segment.java b/src/edu/berkeley/qfat/geom/Segment.java index 5f46051..fa303d1 100644 --- a/src/edu/berkeley/qfat/geom/Segment.java +++ b/src/edu/berkeley/qfat/geom/Segment.java @@ -25,8 +25,18 @@ public class Segment implements HasBoundingBox { public float getMaxZ() { return Math.max(p1.z, p2.z); } public float getMinZ() { return Math.min(p1.z, p2.z); } + /** the line passing through both endpoints of this segment */ + public Line getLine() { return new Line(p1, p2); } + + public float length() { return p1.distance(p2); } + public double distance(Point p) { - throw new RuntimeException("not yet implemented"); + Line line = getLine(); + Point proj = line.projection(p); + if (proj.distance(p1)+proj.distance(p2) > length()) + return Math.min(p1.distance(p), + p2.distance(p)); + return proj.distance(p); } } diff --git a/src/edu/berkeley/qfat/geom/Triangle.java b/src/edu/berkeley/qfat/geom/Triangle.java index 9db806b..ddeae34 100644 --- a/src/edu/berkeley/qfat/geom/Triangle.java +++ b/src/edu/berkeley/qfat/geom/Triangle.java @@ -24,17 +24,10 @@ public abstract class Triangle implements HasBoundingBox { /** issue gl.glVertex() for each of the triangle's points */ public void glVertices(GL gl, Matrix m) { - if (m==null) { - norm().glNormal(gl); - p1().glVertex(gl); - p2().glVertex(gl); - p3().glVertex(gl); - } else { - m.times(norm()).glNormal(gl); - m.times(p1()).glVertex(gl); - m.times(p2()).glVertex(gl); - m.times(p3()).glVertex(gl); - } + (m==null ? norm() : m.times(norm())).glNormal(gl); + (m==null ? p1() : m.times(p1())).glVertex(gl); + (m==null ? p2() : m.times(p2())).glVertex(gl); + (m==null ? p3() : m.times(p3())).glVertex(gl); } /** the triangle's centroid */ @@ -53,22 +46,24 @@ public abstract class Triangle implements HasBoundingBox { return 1/(1+area()/(max*max)); } */ - + /* public float circumcircleRadius() { double a = p1().distance(p2()); double b = p2().distance(p3()); double c = p3().distance(p1()); return (float)((a*b*c)/Math.sqrt((a+b+c)*(b+c-a)*(c+a-b)*(a+b-c))); } - + */ + /* public float shortestEdgeLength() { float a = p1().distance(p2()); float b = p2().distance(p3()); float c = p3().distance(p1()); return Math.min(a, Math.min(b,c)); } - + */ /** a number ranging from 0..1 with 0 being lower quality */ + /* public float quality() { float d = shortestEdgeLength(); float r = circumcircleRadius(); @@ -77,6 +72,7 @@ public abstract class Triangle implements HasBoundingBox { if (ret < 0 || ret > 1) throw new Error("ret="+ret); return ret; } + */ // FIXME: I stole this off the net, and I need to credit whoever wrote it /** decide if the segment from p1-p2 intersects this triangle */