Make CalculateNormal() more robust draft
authorMiko Mynttinen <mikokm@gmail.com>
Mon, 08 Aug 2016 12:52:25 -0700
changeset 398883 d3f6d9f6f82b8a5c22acf75e5d82ec7bad817da5
parent 398882 7ad98fcaddb933da1e08e8d2f87e2a85678f7deb
child 398884 299fba5dfcbfe561ef85bbe923a2917af58fb2e3
push id25668
push userbmo:mikokm@gmail.com
push dateTue, 09 Aug 2016 23:22:28 +0000
milestone51.0a1
Make CalculateNormal() more robust MozReview-Commit-ID: 8lQKKTeQ81A
gfx/2d/Polygon.h
--- a/gfx/2d/Polygon.h
+++ b/gfx/2d/Polygon.h
@@ -52,23 +52,31 @@ private:
   // The resulting normal vector will point towards the viewer when the polygon
   // has a counter-clockwise winding order from the perspective of the viewer.
   void CalculateNormal()
   {
     MOZ_ASSERT(mPoints.Length() >= 3);
 
     // This normal calculation method works only for planar polygons.
     mNormal = (mPoints[1] - mPoints[0]).CrossProduct(mPoints[2] - mPoints[0]);
+
+    const float epsilon = 0.001;
+    if (mNormal.Length() < epsilon) {
+      // The first three points were too close.
+      // Use more points for better accuracy.
+      for (size_t i = 2; i < mPoints.Length() - 1; ++i) {
+        mNormal += (mPoints[i] - mPoints[0]).CrossProduct(mPoints[i + 1] - mPoints[0]);
+      }
+    }
+
     mNormal.Normalize();
 
     #ifdef DEBUG
     // Ensure that the polygon is planar.
     // http://mathworld.wolfram.com/Point-PlaneDistance.html
-    const float epsilon = 0.001;
-
     for (const gfx::Point3DTyped<Units>& point : mPoints) {
       float d = mNormal.DotProduct(point - mPoints[0]);
       MOZ_ASSERT(std::abs(d) < epsilon);
     }
     #endif
   }
 
   nsTArray<Point3DTyped<Units>> mPoints;