+
+ // FIXME: ambiguity firstEdge or secondEdge?
+ /** returns the next triangle walking "around" shared vertex p */
+ public T next(P p) { return secondEdge(p).other(this); }
+
+ public E firstEdge(P p) {
+ if (p == e1.shared(e2)) return e1;
+ else if (p == e2.shared(e3)) return e2;
+ else if (p == e3.shared(e1)) return e3;
+ else throw new Error("triangle " + this + " does not own point " + p);
+ }
+
+ public E secondEdge(P p) {
+ if (p == e1.shared(e2)) return e2;
+ else if (p == e2.shared(e3)) return e3;
+ else if (p == e3.shared(e1)) return e1;
+ else throw new Error("triangle " + this + " does not own point " + p);
+ }
+
+ /** returns the angle at point p */
+ public double angle(P p) {
+ V v1 = firstEdge(p).other(p).minus(p);
+ V v2 = secondEdge(p).other(p).minus(p);
+ return Math.acos(v1.norm().dot(v2.norm()));
+ }
+