// rescale to match volume
float factor = (float)Math.pow(tile.volume() / goal.volume(), 1.0/3.0);
- goal.transform(new Matrix(factor));
+ goal.transform(Matrix.scale(factor));
// translate to match centroid
goal.transform(new Matrix(tile.centroid().minus(goal.centroid())));
Matrix quadric = Matrix.ZERO;
Vert bound_to = this;
- Matrix binding = new Matrix();
+ Matrix binding = Matrix.ONE;
float oldscore = 0;
boolean quadricStale = false;
} while(px != p);
return false;
}
- public void unbind() { bound_to = this; binding = new Matrix(); }
- public void bind(Vert p) { bind(p, new Matrix()); }
+ public void unbind() { bound_to = this; binding = Matrix.ONE; }
+ public void bind(Vert p) { bind(p, Matrix.ONE); }
public void bind(Vert p, Matrix binding) {
if (isBoundTo(p)) return;
Vert temp_bound_to = p.bound_to;
package edu.berkeley.qfat.geom;
import javax.media.opengl.*;
+/** objects which have a bounding region in 3-space */
public interface HasBoundingBox {
public float getMaxX();
public float getMinX();
package edu.berkeley.qfat.geom;
-/** affine matrix; immutable */
+/** an affine matrix; immutable */
public class Matrix {
+ /**
+ * <pre>
+ * [ a b c d ] [ x ]
+ * [ e f g h ] [ y ]
+ * [ i j k l ] [ z ]
+ * [ m n o p ] [ 1 ]
+ * </pre>
+ */
+ public final float a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p;
+
public static final Matrix ZERO = new Matrix(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+ public static final Matrix ONE = new Matrix(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);
+
+ public static Matrix scale(float scale) { return new Matrix(scale, 0, 0, 0, 0, scale, 0, 0, 0, 0, scale, 0, 0, 0, 0, 1); }
- //
- // [ a b c d ] [ x ]
- // [ e f g h ] [ y ]
- // [ i j k l ] [ z ]
- // [ m n o p ] [ 1 ]
- //
- public final float a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p;
- public Matrix() { this(1); }
- public Matrix(float scale) {
- a = f = k = scale;
- l = h = d = e = b = i = c = j = g = 0;
- m = n = o = 0;
- p = 1;
- }
public Matrix(float scalex, float scaley, float scalez) {
a = scalex;
f = scaley;
public final float x, y, z;
public Point(double x, double y, double z) { this((float)x, (float)y, (float)z); }
public Point(float x, float y, float z) { this.x = x; this.y = y; this.z = z; }
- public float distance(Point p) { return distance(p.x, p.y, p.z); }
- public float distance(float ox, float oy, float oz) { return (float)Math.sqrt((x-ox)*(x-ox)+(y-oy)*(y-oy)+(z-oz)*(z-oz)); }
+
+ public float distance(Point p) { return (float)Math.sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y)+(z-p.z)*(z-p.z)); }
+
public Point times(Matrix m) { return m.times(this); }
public Vec minus(Point p) { return new Vec(x-p.x, y-p.y, z-p.z); }
public Point plus(Vec v) { return new Point(x+v.x, y+v.y, z+v.z); }
- public boolean equals(Object o) { return o!=null && (o instanceof Point) && ((Point)o).x==x && ((Point)o).y==y && ((Point)o).z==z; }
- public void glVertex(GL gl) { _glVertex(gl); }
- private void _glVertex(GL gl) { gl.glVertex3f(x, y, z); }
+
+ public void glVertex(GL gl) { gl.glVertex3f(x, y, z); }
+
public String toString() { return "("+x+","+y+","+z+")"; }
+
+ public boolean equals(Object o) { return o!=null && (o instanceof Point) && ((Point)o).x==x && ((Point)o).y==y && ((Point)o).z==z; }
public int hashCode() { return Float.floatToIntBits(x) ^ Float.floatToIntBits(y) ^ Float.floatToIntBits(z); }
public float getMaxX() { return x; }
public float getMaxZ() { return z; }
public float getMinZ() { return z; }
}
+
--- /dev/null
+package edu.berkeley.qfat.geom;
+import javax.media.opengl.*;
+
+/** a line segment defined by two points in space */
+public class Segment implements HasBoundingBox {
+
+ public final Point p1;
+ public final Point p2;
+
+ public Segment(Point p1, Point p2) { this.p1 = p1; this.p2 = p2; }
+
+ public float getMaxX() { return Math.max(p1.x, p2.x); }
+ public float getMinX() { return Math.min(p1.x, p2.x); }
+ public float getMaxY() { return Math.max(p1.y, p2.y); }
+ public float getMinY() { return Math.min(p1.y, p2.y); }
+ public float getMaxZ() { return Math.max(p1.z, p2.z); }
+ public float getMinZ() { return Math.min(p1.z, p2.z); }
+
+}
package edu.berkeley.qfat.geom;
import javax.media.opengl.*;
+/**
+ * an oriented triangle, defined by three points in clockwise order.
+ */
public abstract class Triangle implements HasBoundingBox {
public abstract Point p1();
public abstract Point p2();
public abstract Point p3();
+ /** the face normal vector */
public Vec norm() {
return p2().minus(p1()).cross(p3().minus(p1())).norm();
}
+
+ /** the area of the triangle */
public float area() {
return
(float)Math.abs(0.5*p1().distance(p2())
* new Vec(p1(), p2()).norm().dot(new Vec(p2(), p3())));
}
+
+ /** issue gl.glVertex() for each of the triangle's points */
public void glVertices(GL gl) {
p1().glVertex(gl);
p2().glVertex(gl);
p3().glVertex(gl);
}
+
+ /** the triangle's centroid */
public Point centroid() {
return new Point((p1().x+p2().x+p3().x)/3,
(p1().y+p2().y+p3().y)/3,
(p1().z+p2().z+p3().z)/3);
}
- public float diameter() {
- // FIXME: what is this supposed to be?
- return Math.max(Math.max(p1().distance(p2()),
- p2().distance(p3())),
- p3().distance(p1())) / 2;
- }
+ /** ratio of the area of the triangle to that of the square formed from its longest edge */
public float aspect() {
float max = Math.max(Math.max(p1().distance(p2()),
p2().distance(p3())),
p3().distance(p1())) / 2;
return 1/(1+area()/(max*max));
}
- public float aspect0() {
- float max = Math.max(Math.max(p1().distance(p2()),
- p2().distance(p3())),
- p3().distance(p1())) / 2;
- return (area()/(max*max));
- }
public float getMaxX() { return Math.max(p1().x, Math.max(p2().x, p3().x)); }
public float getMinX() { return Math.min(p1().x, Math.min(p2().x, p3().x)); }
--- /dev/null
+package edu.berkeley.qfat.geom;
+
+public interface Visitor<V> {
+ public void visit(V v);
+}