P p1 = e1.shared(e2);
P p2 = e2.shared(e3);
P p3 = e3.shared(e1);
- // FEATURE: colinearity check?
V norm2 = p2.minus(p1).cross(p3.minus(p1));
float dot = norm.dot(norm2);
if (Math.abs(dot) < EPSILON) throw new Error("dot products within epsilon of each other: "+norm+" "+norm2);
public final class E {
public final P p1, p2;
T t1, t2;
- public E(P p1, P p2) { this.p1 = p1; this.p2 = p2; }
+ public E(P p1, P p2) {
+ if (p1==p2) throw new Error("attempt to create edge with single vertex: " + p1);
+ this.p1 = p1;
+ this.p2 = p2;
+ }
public int hashCode() { return p1.hashCode() ^ p2.hashCode(); }
public float length() { return p1.minus(p2).mag(); }
public boolean equals(Object o) {
/** [UNIQUE] a triangle (face) */
public final class T {
public final E e1, e2, e3;
- public V norm() {
- P p1 = e1.shared(e2);
- P p2 = e2.shared(e3);
- P p3 = e3.shared(e1);
- return p2.minus(p1).cross(p3.minus(p1)).norm();
- }
T(E e1, E e2, E e3) {
if (e1.p1.t==null) e1.p1.t = this;
if (e1.p2.t==null) e1.p2.t = this;
if (e2.p2.t==null) e2.p2.t = this;
if (e3.p1.t==null) e3.p1.t = this;
if (e3.p2.t==null) e3.p2.t = this;
+ if (e1==e2) throw new Error("attempt to create triangle with duplicate edge: " + e1);
+ if (e2==e3) throw new Error("attempt to create triangle with duplicate edge: " + e2);
+ if (e3==e1) throw new Error("attempt to create triangle with duplicate edge: " + e3);
+ // check that each pair of edges shares a vertex
+ e1.shared(e2);
+ e2.shared(e3);
+ e3.shared(e1);
this.e1 = e1;
this.e2 = e2;
this.e3 = e3;
+ // FEATURE: colinearity/sliverness check?
if (e1.t1 == null) e1.t1 = this; else if (e1.t2 == null) e1.t2 = this; else throw new Error("non-manifold surface");
if (e2.t1 == null) e2.t1 = this; else if (e2.t2 == null) e2.t2 = this; else throw new Error("non-manifold surface");
if (e3.t1 == null) e3.t1 = this; else if (e3.t2 == null) e3.t2 = this; else throw new Error("non-manifold surface");
+ // FIXME: check that triangles we share an edge with agree on the direction of the normal vector
+ // FIXME: check for sealed/watertight surface once construction is complete (an infer normal(s)?)
+ }
+ public V norm() {
+ P p1 = e1.shared(e2);
+ P p2 = e2.shared(e3);
+ P p3 = e3.shared(e1);
+ return p2.minus(p1).cross(p3.minus(p1)).norm();
}
public boolean hasE(E e) { return e1==e || e2==e || e3==e; }
public void glVertices(GL gl) {