/** magnification factor */
private static final float MAG = 1;
- public static final float MATCHING_EPSILON = 0.0001f;
+ public static final float MATCHING_EPSILON = 0.001f;
+ private static boolean small(float f) { return Math.abs(f) < 0.001; }
public void generateTile(Matrix[] matrices, Mesh mesh) {
+ mesh.coalesce = true;
HashSet<HalfSpace> halfSpaces = new HashSet<HalfSpace>();
HashSet<Polygon> polygons = new HashSet<Polygon>();
for(Matrix m : matrices) {
if (v.mag() < 0.0001) continue;
v = v.times(0.5f);
Point p = Point.ORIGIN.plus(v);
- HalfSpace hs = new HalfSpace(p, Point.ORIGIN.minus(p).norm());
+ Vec v0 = v;
+ /*
+ if (small(v.x) && small(v.y)) v = new Vec(0,0,1);
+ else if (small(v.y) && small(v.z)) v = new Vec(1,0,0);
+ else if (small(v.z) && small(v.x)) v = new Vec(0,1,0);
+ else if (small(v.x)) v = new Vec(0,v.y,0).minus(new Vec(0,0,v.z)).cross(new Vec(1,0,0));
+ else if (small(v.y)) v = new Vec(0,0,v.z).minus(new Vec(v.x,0,0)).cross(new Vec(0,1,0));
+ else if (small(v.z)) v = new Vec(v.x,0,0).minus(new Vec(0,v.y,0)).cross(new Vec(0,0,1));
+ else {
+ Point v1 = new Point(v.x, 0, 0);
+ Point v2 = new Point(0, v.y, 0);
+ Point v3 = new Point(0, 0, v.z);
+ v = v3.minus(v2).cross(v1.minus(v2));
+ }
+ */
+ if (v.dot(Point.ORIGIN.minus(p)) < 0) v = v.times(-1);
+
+ System.out.println(v);
+ HalfSpace hs = new HalfSpace(p, v.norm());
halfSpaces.add(hs);
polygons.add(new Polygon(hs));
}
// rotate to align major axis -- this probably needs to be done by a human.
//goal.transform(Matrix.rotate(new Vec(0, 0, 1), (float)(Math.PI/2)));
- goal.transform(Matrix.rotate(new Vec(0, 1, 0), (float)(Math.PI/2)));
+
float goal_width = goal.diagonal().dot(new Vec(1, 0, 0));
float goal_height = goal.diagonal().dot(new Vec(0, 1, 0));
float depth = (float)0.3;
*/
- float width = (float)0.7;
+ float width = (float)0.8;
float depth = (float)0.08;
float height = (float)0.4;
float rshift = width/2;
float lshift = -(width/2);
-
- //float halfup = height/2;
float halfup = 0;
-
+ //float shift = height/2;
+ //width = (width*2)/3;
+ float shift = 0;
translations = new Matrix[] {
- //Matrix.translate(new Vec(lshift, depth, 0)),
- //Matrix.translate(new Vec(rshift, depth, 0)),
- //Matrix.translate(new Vec(lshift, -depth, 0)),
- //Matrix.translate(new Vec(rshift, -depth, 0)),
-
+ Matrix.translate(new Vec(lshift/2, depth, -shift)),
+ Matrix.translate(new Vec(rshift/2, depth, -shift)),
+ Matrix.translate(new Vec(lshift/2, -depth, -shift)),
+ Matrix.translate(new Vec(rshift/2, -depth, -shift)),
+
+ Matrix.translate(new Vec(lshift, depth/2, -shift)),
+ Matrix.translate(new Vec(rshift, depth/2, -shift)),
+ Matrix.translate(new Vec(lshift, -depth/2, -shift)),
+ Matrix.translate(new Vec(rshift, -depth/2, -shift)),
+
+
+ /*
+ Matrix.translate(new Vec(lshift, depth, -shift)),
+ Matrix.translate(new Vec(rshift, depth, -shift)),
+ Matrix.translate(new Vec(lshift, -depth, -shift)),
+ Matrix.translate(new Vec(rshift, -depth, -shift)),
+ */
+ /*
+ Matrix.translate(new Vec(lshift, depth, shift)),
+ Matrix.translate(new Vec(rshift, depth, shift)),
+ Matrix.translate(new Vec(lshift, -depth, shift)),
+ Matrix.translate(new Vec(rshift, -depth, shift)),
+ */
//Matrix.translate(new Vec(0, depth, 0)).times(Matrix.rotate(new Vec(0, 0, 1), (float)Math.PI)),
//Matrix.translate(new Vec(0, -depth, 0)).times(Matrix.rotate(new Vec(0, 0, 1), (float)Math.PI)),
//Matrix.translate(new Vec(0, 0, height)).times(Matrix.rotate(new Vec(0, 0, 1), (float)Math.PI)),
//Matrix.translate(new Vec(0, 0, -height)).times(Matrix.rotate(new Vec(0, 0, 1), (float)Math.PI)),
- Matrix.translate(new Vec(0, depth, 0)),
- Matrix.translate(new Vec(0, -depth, 0)),
+ //Matrix.translate(new Vec(0, depth, 0)),
+ //Matrix.translate(new Vec(0, -depth, 0)),
Matrix.translate(new Vec(0, 0, height)),
Matrix.translate(new Vec(0, 0, -height)),
Matrix.translate(new Vec( width, 0, 0)),
Matrix.translate(new Vec(-width, 0, 0)),
+ Matrix.ONE
+ };
+
+ float unit = 0.1f;
+ float r = unit/2;
+ float sin = (float)(unit * Math.sin(Math.PI/3));
+ float cos = (float)(unit * Math.cos(Math.PI/3));
+ float x = (float)(r*Math.tan(Math.PI/6));
+ float z = (float)(r/Math.cos(Math.PI/6));
+ height = 2*r*(float)Math.sqrt(2f/3f);
+
+
+ r *= 0.3f;
+ cos *= 0.3f;
+ unit *= 0.3f;
+
+
+ /*
+ sin *= 0.3f;
+ x *= 0.3f;
+ z *= 0.3f;
+ */
+ translations = new Matrix[] {
+ Matrix.translate(new Vec(-unit, 0, 0)),
+ Matrix.translate(new Vec( unit, 0, 0)),
+ Matrix.translate(new Vec(-cos, 0, sin)),
+ Matrix.translate(new Vec( cos, 0, sin)),
+ Matrix.translate(new Vec(-cos, 0, -sin)),
+ Matrix.translate(new Vec( cos, 0, -sin)),
+ Matrix.translate(new Vec( 0, height, z)),
+ Matrix.translate(new Vec(-r, height, -x)),
+ Matrix.translate(new Vec( r, height, -x)),
+ Matrix.translate(new Vec( 0, -height, -z)),
+ Matrix.translate(new Vec(-r, -height, x)),
+ Matrix.translate(new Vec( r, -height, x)),
};
- generateTile(translations, tile);
/*
translations = new Matrix[] {
Matrix.translate(new Vec(-width, 0, 0)),
};
-
+ */
//
+ //generateTile(translations, tile);
Point ltf = new Point(lshift, (depth/2), (height/2));
Point mtf = new Point( 0.0, (depth/2), (height/2));
mbn,
rbn
};
-
+ /*
// top
tile.newT(ltf, mtf, mtc, null, 1);
tile.newT(mbf, ltf, lbf, null, 6);
tile.newT(rtf, mtf, rbf, null, 6);
tile.newT(rbf, mtf, mbf, null, 6);
-
+*/
+ /*
HashSet<Mesh.E> es = new HashSet<Mesh.E>();
for(Mesh.T t : tile) {
es.add(t.e1());
}
*/
- /*
+
height = 4;
width = 4;
depth = 1;
new Point(-1, -1, 1),
new Point(-1, -1, -1));
- float factor = (float)Math.pow(tile.volume() / goal.volume(), 1.0/3.0);
- goal.transform(Matrix.scale(factor/2.4f));
- /*
- translations = new Matrix[] {
+ translations = new Matrix[] {
+ /*
Matrix.translate(new Vec(0, 0.2f,0))
.times(Matrix.rotate(new Vec(0,1,0), (float)( 1*Math.PI/2))),
Matrix.translate(new Vec(0,-0.2f,0))
.times(Matrix.rotate(new Vec(0,1,0), (float)(-1*Math.PI/2))),
- //Matrix.translate(new Vec( 0.2f,0,0))
- //.times(Matrix.rotate(new Vec(1,0,0), (float)( 1*Math.PI/2))),
- //Matrix.translate(new Vec(-0.2f,0,0))
- //.times(Matrix.rotate(new Vec(1,0,0), (float)(-1*Math.PI/2))),
+ Matrix.translate(new Vec( 0.2f,0,0))
+ .times(Matrix.rotate(new Vec(1,0,0), (float)( 1*Math.PI/2))),
+
+ Matrix.translate(new Vec(-0.2f,0,0))
+ .times(Matrix.rotate(new Vec(1,0,0), (float)(-1*Math.PI/2))),
+ */
+
+ /*
+ Matrix.rotate(new Vec(0,0,1), (float)(1*Math.PI/2)),
+ Matrix.rotate(new Vec(0,0,1), (float)(2*Math.PI/2)),
+ Matrix.rotate(new Vec(0,0,1), (float)(3*Math.PI/2)),
+ */
+ Matrix.rotate(new Vec(1,0,0), (float)(2*Math.PI/2)),
+
+ //Matrix.rotate(new Vec(0,0,1), (float)(2*Math.PI/2)),
+ //Matrix.scale(1,-1,1),
//Matrix.translate(new Vec( 0.2f, 0,0))
//.times(Matrix.rotate(new Vec(0,0,1), (float)( 1*Math.PI/2)))
Matrix.ONE,
};
- */
-
+
+
+
for(Matrix m1 : translations) {
for(Matrix m2 : translations) {
for(Mesh.T t1 : tile) {
t2.e1().bindEdge(t1.e2(), m);
}
+ if ((t1.v1().p.times(m).minus(t2.v1().p).mag() < MATCHING_EPSILON) &&
+ (t1.v2().p.times(m).minus(t2.v2().p).mag() < MATCHING_EPSILON) &&
+ (t1.v3().p.times(m).minus(t2.v3().p).mag() < MATCHING_EPSILON)) {
+ t2.e1().bindEdge(t1.e1().pair, m);
+ t2.e2().bindEdge(t1.e2().pair, m);
+ t2.e3().bindEdge(t1.e3().pair, m);
+ }
+ if ((t1.v2().p.times(m).minus(t2.v1().p).mag() < MATCHING_EPSILON) &&
+ (t1.v3().p.times(m).minus(t2.v2().p).mag() < MATCHING_EPSILON) &&
+ (t1.v1().p.times(m).minus(t2.v3().p).mag() < MATCHING_EPSILON)) {
+ t2.e2().bindEdge(t1.e1().pair, m);
+ t2.e3().bindEdge(t1.e2().pair, m);
+ t2.e1().bindEdge(t1.e3().pair, m);
+ }
+ if ((t1.v3().p.times(m).minus(t2.v1().p).mag() < MATCHING_EPSILON) &&
+ (t1.v1().p.times(m).minus(t2.v2().p).mag() < MATCHING_EPSILON) &&
+ (t1.v2().p.times(m).minus(t2.v3().p).mag() < MATCHING_EPSILON)) {
+ t2.e3().bindEdge(t1.e1().pair, m);
+ t2.e1().bindEdge(t1.e2().pair, m);
+ t2.e2().bindEdge(t1.e3().pair, m);
+ }
+
}
}
}
// rescale to match volume
+ float factor = (float)Math.pow(tile.volume() / goal.volume(), 1.0/3.0);
+ goal.transform(Matrix.scale(factor/2.4f));
+ goal.transform(Matrix.rotate(new Vec(0, 1, 0), (float)(Math.PI/2)));
// translate to match centroid
goal.transform(Matrix.translate(tile.centroid().minus(goal.centroid())));
// t2' = t2.getMatrix(t1) * M * t1
// t1 = t1.getMatrix(t2) * t2
// M * t1 = M * t1.getMatrix(t2) * t2
+ if (bindingGroup!=null && this != bindingGroup.getMaster()) {
+ Matrix v = getBindingMatrix(bindingGroup.getMaster());
+ return ((Vertex)bindingGroup.getMaster()).move(v.inverse().times(m).times(v), ignoreProblems);
+ }
+
+ if (bindingGroup != null) {
+ Matrix m2 = null;
+ for(int i=0; i<20 && !m.equals(m2); i++) {
+ m2 = m.times(bindingGroup.krank);
+ //System.out.println(m.minus(m2));
+ }
+ if (!m.equals(m2)) return true;
+ }
+
Point op = this.p;
Point pt = m.times(this.p);
for(Vertex v : (Iterable<Vertex>)getBoundPeers()) {
(edu.berkeley.qfat.geom.BindingGroup<E>)newBindingGroup_;
if (newBindingGroup==null) return;
if (this==newBindingGroup.getMaster()) return;
- for(E eother : (Iterable<E>)newBindingGroup) {
+ HashSet<E> nbg = new HashSet<E>();
+ for(E eother : (Iterable<E>)newBindingGroup) nbg.add(eother);
+ for(E eother : nbg) {
if (next==null || prev==null) continue;
if (eother.next==null || eother.prev==null) continue;
if (next.isBoundTo(eother.pair.prev.pair) && !prev.isBoundTo(eother.pair.next.pair))
prev.bindTo(next.getBindingMatrix(eother.pair.prev.pair), eother.pair.next.pair);
if (!next.isBoundTo(eother.pair.prev.pair) && prev.isBoundTo(eother.pair.next.pair))
next.bindTo(prev.getBindingMatrix(eother.pair.next.pair), eother.pair.prev.pair);
+
+ if (next.isBoundTo(eother.next) && !prev.isBoundTo(eother.prev))
+ prev.bindTo(next.getBindingMatrix(eother.next), eother.prev);
+ if (!next.isBoundTo(eother.next) && prev.isBoundTo(eother.prev))
+ next.bindTo(prev.getBindingMatrix(eother.prev), eother.next);
}
}
if (v2 != null) return new E(v2.getFreeIncident(), p1).pair;
return new E(p1, p2);
}
+ public boolean coalesce = false;
+ private static float round(float f) {
+ return Math.round(f*1000)/1000f;
+ }
public T newT(Point p1, Point p2, Point p3, Vec norm, int colorclass) {
+ if (coalesce) {
+
+ for(Vertex v : vertices) { if (p1.distance(v.p) < EPSILON) { p1 = v.p; break; } }
+ for(Vertex v : vertices) { if (p2.distance(v.p) < EPSILON) { p2 = v.p; break; } }
+ for(Vertex v : vertices) { if (p3.distance(v.p) < EPSILON) { p3 = v.p; break; } }
+ /*
+ p1 = new Point(round(p1.x), round(p1.y), round(p1.z));
+ p2 = new Point(round(p2.x), round(p2.y), round(p2.z));
+ p3 = new Point(round(p3.x), round(p3.y), round(p3.z));
+ */
+ }
if (norm != null) {
Vec norm2 = p3.minus(p1).cross(p2.minus(p1));
float dot = norm.dot(norm2);
public void reinsert() { triangles.remove(this); triangles.add(this); }
public boolean shouldBeDrawn() {
- /*
+
if (e1().bindingGroupSize() <= 1) return false;
if (e2().bindingGroupSize() <= 1) return false;
if (e3().bindingGroupSize() <= 1) return false;
- */
+
return true;
}
public boolean tilemeshon = false;
public boolean goalon = false;
public boolean anneal = false;
+ public boolean neighbors = false;
public int breaks = 0;
boolean alt = false;
case KeyEvent.VK_SPACE: breaks++; break;
case KeyEvent.VK_D: dump(); break;
case KeyEvent.VK_A: anneal = !anneal; break;
+ case KeyEvent.VK_N: neighbors = !neighbors; break;
case KeyEvent.VK_T: tileon = !tileon; break;
case KeyEvent.VK_G: goalon = !goalon; break;
case KeyEvent.VK_M: tilemeshon = !tilemeshon; break;
float mat_specular[] = { 0.5f, 0.5f, 0.5f, 0.5f };
float mat_shininess[] = { 50.0f };
gl.glShadeModel(GL.GL_SMOOTH);
- gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, mat_specular, 0);
+ //gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, mat_specular, 0);
//gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, mat_specular, 0);
- gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, new float[] { 0.3f, 0.3f, 0.3f, 0.3f }, 0);
+ //gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, new float[] { 0.3f, 0.3f, 0.3f, 0.3f }, 0);
//gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, mat_shininess, 0);
- gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { 1.0f, 4.0f, -10.0f, 0.0f }, 0);
- gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, new float[] { -10.0f, 10.0f, 10.0f, 0.0f }, 0);
- gl.glLightfv(GL.GL_LIGHT2, GL.GL_POSITION, new float[] { 10.0f, -10.0f, 10.0f, 0.0f }, 0);
- gl.glLightfv(GL.GL_LIGHT3, GL.GL_POSITION, new float[] { 10.0f, 10.0f, -10.0f, 0.0f }, 0);
- gl.glLightfv(GL.GL_LIGHT4, GL.GL_POSITION, new float[] { -10.0f, 10.0f, -10.0f, 0.0f }, 0);
- gl.glLightfv(GL.GL_LIGHT5, GL.GL_POSITION, new float[] { 10.0f, -10.0f, -10.0f, 0.0f }, 0);
+ gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { 1.0f, 4.0f, -10.0f, 0.0f }, 0);
+ gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, new float[] { -10.0f, 10.0f, 10.0f, 0.0f }, 0);
+ gl.glLightfv(GL.GL_LIGHT2, GL.GL_POSITION, new float[] { 10.0f, -10.0f, 10.0f, 0.0f }, 0);
+ gl.glLightfv(GL.GL_LIGHT3, GL.GL_POSITION, new float[] { 10.0f, 10.0f, -10.0f, 0.0f }, 0);
+ gl.glLightfv(GL.GL_LIGHT4, GL.GL_POSITION, new float[] { -10.0f, 10.0f, -10.0f, 0.0f }, 0);
+ gl.glLightfv(GL.GL_LIGHT5, GL.GL_POSITION, new float[] { 10.0f, -10.0f, -10.0f, 0.0f }, 0);
gl.glEnable(GL.GL_LIGHTING);
gl.glEnable(GL.GL_LIGHT0);
+ /*
gl.glEnable(GL.GL_LIGHT1);
gl.glEnable(GL.GL_LIGHT2);
gl.glEnable(GL.GL_LIGHT3);
gl.glEnable(GL.GL_LIGHT4);
gl.glEnable(GL.GL_LIGHT5);
-
+ */
gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT_AND_DIFFUSE);
gl.glEnable(GL.GL_COLOR_MATERIAL);
display(gld);
-
}
public int temps;
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glPointSize(5.0f);
gl.glLoadIdentity();
- glu.gluPerspective(50-tz, ((float)drawable.getWidth())/drawable.getHeight(), 0.5, 10);
- glu.gluLookAt(0, 0, -1, 0, 0, 0, 0, 1, 0);
- gl.glTranslatef(tx/(float)20, ty/(float)20, 0);
+ glu.gluPerspective(50, ((float)drawable.getWidth())/drawable.getHeight(), 0.5, 10);
+ glu.gluLookAt(0, 0, (tz/10)-1, 0, 0, 0, 0, 1, 0);
gl.glRotatef(anglex/3, 0, 1, 0);
gl.glRotatef(angley/3, 1, 0, 0);
gl.glColor4f(1,1,1,1);
for(Matrix m : translations) {
//if (v1.z==0 && v1.y==0) continue;
- //if (i>0) continue;
i++;
+ //if (i>4) continue;
/*
Point p = new Point(0, 0, 0).times(m);
Vec v = new Vec(p.x, p.y, p.z);
v = v.times((float)1.04);
gl.glTranslatef(v.x, v.y, v.z);
*/
- draw(gl, false, safeTriangles, m);
+ if (neighbors) draw(gl, false, safeTriangles, m);
/*
gl.glTranslatef(-v.x, -v.y, -v.z);
*/