checkpoint
[anneal.git] / src / edu / berkeley / qfat / geom / Triangle.java
index 3620f71..9db806b 100644 (file)
@@ -2,7 +2,7 @@ package edu.berkeley.qfat.geom;
 import javax.media.opengl.*;
 
 /**
- *  An oriented triangle, defined by three points in clockwise order;
+ *  An oriented triangle, defined by three points in order;
  *  note that the Point objects returned by p1/p2/p3 may vary over time.
  */
 public abstract class Triangle implements HasBoundingBox {
@@ -23,10 +23,18 @@ public abstract class Triangle implements HasBoundingBox {
     }
 
     /** issue gl.glVertex() for each of the triangle's points */
-    public void glVertices(GL gl) {
-        p1().glVertex(gl);
-        p2().glVertex(gl);
-        p3().glVertex(gl);
+    public void glVertices(GL gl, Matrix m) {
+        if (m==null) {
+            norm().glNormal(gl);
+            p1().glVertex(gl);
+            p2().glVertex(gl);
+            p3().glVertex(gl);
+        } else {
+            m.times(norm()).glNormal(gl);
+            m.times(p1()).glVertex(gl);
+            m.times(p2()).glVertex(gl);
+            m.times(p3()).glVertex(gl);
+        }
     }
 
     /** the triangle's centroid */
@@ -37,13 +45,40 @@ public abstract class Triangle implements HasBoundingBox {
     }
 
     /** 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 circumcircleRadius() {
+        double a = p1().distance(p2());
+        double b = p2().distance(p3());
+        double c = p3().distance(p1());
+        return (float)((a*b*c)/Math.sqrt((a+b+c)*(b+c-a)*(c+a-b)*(a+b-c)));
+    }
+
+    public float shortestEdgeLength() {
+        float a = p1().distance(p2());
+        float b = p2().distance(p3());
+        float c = p3().distance(p1());
+        return Math.min(a, Math.min(b,c));
+    }
+
+    /** a number ranging from 0..1 with 0 being lower quality */
+    public float quality() {
+        float d = shortestEdgeLength();
+        float r = circumcircleRadius();
+        if (r==0) throw new Error();
+        float ret = (float)((d*Math.cos(Math.PI/6))/(r*2));
+        if (ret < 0 || ret > 1) throw new Error("ret="+ret);
+        return ret;
+    }
+
+    // FIXME: I stole this off the net, and I need to credit whoever wrote it
     /** decide if the segment from p1-p2 intersects this triangle */
     public boolean intersects(Point p1, Point p2) {
         double A0=p1().x, A1=p1().y, A2=p1().z;