ArrayList<Vertex> set = new ArrayList<Vertex>();
for(Vertex v : vertices) set.add(v);
for(Vertex v : set) v.transform(m.times(v.p), true, null);
ArrayList<Vertex> set = new ArrayList<Vertex>();
for(Vertex v : vertices) set.add(v);
for(Vertex v : set) v.transform(m.times(v.p), true, null);
public Point getPoint() { return p; }
public float error() { return olderror; }
private Vertex(Point p) {
this.p = p;
this.goodp = p;
public Point getPoint() { return p; }
public float error() { return olderror; }
private Vertex(Point p) {
this.p = p;
this.goodp = p;
+ /*
+ public Vertex hack(GL gl, Point mouse) {
+ double dist = Double.MAX_VALUE;
+ Vertex cur = null;
+ for(E e = this.e; e!=null; e=e.pair.next==this.e?null:e.pair.next) {
+ Vertex v = e.getOther(this);
+ double dist2 = v.getPoint().glProject(gl).distance(mouse);
+ if ((cur==null || dist2 < dist) && v.visible) {
+ dist = dist2;
+ cur = v;
+ }
+ }
+ return cur;
+ }
+ */
+
- if (!immutableVertices && quadric_count == 0)
- nerror *= 2;
-
+ if (!immutableVertices && quadric_count == 0) {
+ //nerror = Math.max(nerror, 0.4f);
+ //nerror *= 2;
+ }
+ //System.out.println(nerror);
+ */
+ }
+ if (!immutableVertices) {
+ Vertex n = (Vertex)nearest();
+ float d = norm().dot(n.norm());
+ if (d > 1 || d < -1) throw new Error();
+ if (d >= 0) {
+ nerror *= (2.0f - d);
+ } else {
+ nerror += 0.0003 * (2.0f + d);
+ nerror *= (2.0f + d);
+ }
// t2' = t2.getMatrix(t1) * M * t1
// t1 = t1.getMatrix(t2) * t2
// M * t1 = M * t1.getMatrix(t2) * t2
// 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 && this != bindingGroup.getMaster()) {
Matrix v = getBindingMatrix(bindingGroup.getMaster());
return ((Vertex)bindingGroup.getMaster()).move(v.inverse().times(m).times(v), ignoreProblems);
throw new Error(v.p+" "+pt2+"\n"+op+" "+pt+"\n"+v.getBindingMatrix(this));
if (Math.abs( v.p.minus(pt2).mag() / pt.minus(op).mag() ) < 1/5) throw new Error();
*/
throw new Error(v.p+" "+pt2+"\n"+op+" "+pt+"\n"+v.getBindingMatrix(this));
if (Math.abs( v.p.minus(pt2).mag() / pt.minus(op).mag() ) < 1/5) throw new Error();
*/
- good &= v.transform(pt2,
- ignoreProblems, v.getBindingMatrix(this));
+ good &= v.transform(pt2, ignoreProblems, v.getBindingMatrix(this));
+ }
+
+ if (!good && !ignoreProblems) {
+ for(Vertex v : (Iterable<Vertex>)getBoundPeers())
+ v.transform(v.oldp, true, null);
/** does NOT update bound pairs! */
private boolean transform(Point newp, boolean ignoreProblems, Matrix yes) {
/** does NOT update bound pairs! */
private boolean transform(Point newp, boolean ignoreProblems, Matrix yes) {
for(E e = this.e; e!=null; e=e.pair.next==this.e?null:e.pair.next) {
if (Math.abs(e.dihedralAngle()) > (Math.PI * 0.9) ||
Math.abs(e.next.dihedralAngle()) > (Math.PI * 0.9)) illegal = true;
if (e.t.aspect() < 0.2) illegal = true;
}
for(E e = this.e; e!=null; e=e.pair.next==this.e?null:e.pair.next) {
if (Math.abs(e.dihedralAngle()) > (Math.PI * 0.9) ||
Math.abs(e.next.dihedralAngle()) > (Math.PI * 0.9)) illegal = true;
if (e.t.aspect() < 0.2) illegal = true;
}
public E getFreeIncident() {
E ret = getFreeIncident(e, e);
if (ret != null) return ret;
public E getFreeIncident() {
E ret = getFreeIncident(e, e);
if (ret != null) return ret;
public void bindingGroupChanged(edu.berkeley.qfat.geom.BindingGroup newBindingGroup_) {
edu.berkeley.qfat.geom.BindingGroup<E> newBindingGroup =
public void bindingGroupChanged(edu.berkeley.qfat.geom.BindingGroup newBindingGroup_) {
edu.berkeley.qfat.geom.BindingGroup<E> newBindingGroup =
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.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.prev) && !prev.isBoundTo(eother.next))
+ prev.bindTo(next.getBindingMatrix(eother.prev), eother.next);
+ if (!next.isBoundTo(eother.prev) && prev.isBoundTo(eother.next))
+ next.bindTo(prev.getBindingMatrix(eother.next), eother.prev);
+ */
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))
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))
System.out.println(" " + p1.p + " " + m.times(e.p1.p));
System.out.println(" " + p2.p + " " + m.times(e.p2.p));
*/
System.out.println(" " + p1.p + " " + m.times(e.p1.p));
System.out.println(" " + p2.p + " " + m.times(e.p2.p));
*/
if (m.times(e.p1.p).minus(p1.p).mag() > EPSILON) throw new Error();
if (m.times(e.p2.p).minus(p2.p).mag() > EPSILON) throw new Error();
if (m.times(e.p1.p).minus(p1.p).mag() > EPSILON) throw new Error();
if (m.times(e.p2.p).minus(p2.p).mag() > EPSILON) throw new Error();
if (e==this) continue;
p1.bindTo(getBindingMatrix(e), e.p1);
p2.bindTo(getBindingMatrix(e), e.p2);
if (e==this) continue;
p1.bindTo(getBindingMatrix(e), e.p1);
p2.bindTo(getBindingMatrix(e), e.p2);
- e.destroy();
- e.pair.destroy();
- newT(r.p, e.p1.p, mid, null, 0);
- newT(r.p, mid, e.p2.p, null, 0);
- newT(l.p, mid, e.p1.p, null, 0);
- newT(l.p, e.p2.p, mid, null, 0);
+ if (!e.destroyed) {
+ e.destroy();
+ e.pair.destroy();
+ newT(r.p, e.p1.p, mid, null, 0);
+ newT(r.p, mid, e.p2.p, null, 0);
+ newT(l.p, mid, e.p1.p, null, 0);
+ newT(l.p, e.p2.p, mid, null, 0);
+ }
e.p2.getE(mid).pair. bindTo(e.getBindingMatrix(firste), firstq);
e.p2.getE(mid).pair.pair.bindTo(e.getBindingMatrix(firste), firstq.pair);
}
e.p2.getE(mid).pair. bindTo(e.getBindingMatrix(firste), firstq);
e.p2.getE(mid).pair.pair.bindTo(e.getBindingMatrix(firste), firstq.pair);
}
public double dihedralAngle() {
Vec v1 = t.norm().times(-1);
Vec v2 = pair.t.norm().times(-1);
public double dihedralAngle() {
Vec v1 = t.norm().times(-1);
Vec v2 = pair.t.norm().times(-1);
- return Math.acos(v1.norm().dot(v2.norm()));
+ double prod = v1.norm().dot(v2.norm());
+ prod = Math.min(1,prod);
+ prod = Math.max(-1,prod);
+ double ret = Math.acos(prod);
+ if (Double.isNaN(ret)) throw new Error("nan! " + prod);
+ return ret;
public void makeAdjacent(E e) {
if (this.next == e) return;
if (p2 != e.p1) throw new Error("cannot make adjacent -- no shared vertex");
public void makeAdjacent(E e) {
if (this.next == e) return;
if (p2 != e.p1) throw new Error("cannot make adjacent -- no shared vertex");
/** [UNIQUE] a triangle (face) */
public final class T extends Triangle {
public final E e1;
public final int color;
public final int colorclass;
/** [UNIQUE] a triangle (face) */
public final class T extends Triangle {
public final E e1;
public final int color;
public final int colorclass;