Index: src/pathops/SkPathOpsTriangle.cpp |
diff --git a/src/pathops/SkPathOpsTriangle.cpp b/src/pathops/SkPathOpsTriangle.cpp |
index 49391667ac6b3abd2b3404c2b6c5a62ea7cf0ca3..003968ddba67ec55cd7b14d0504c243b80363f97 100644 |
--- a/src/pathops/SkPathOpsTriangle.cpp |
+++ b/src/pathops/SkPathOpsTriangle.cpp |
@@ -8,6 +8,7 @@ |
#include "SkPathOpsTriangle.h" |
// http://www.blackpawn.com/texts/pointinpoly/default.html |
+// return true if pt is inside triangle; false if outside or on the line |
bool SkDTriangle::contains(const SkDPoint& pt) const { |
// Compute vectors |
SkDVector v0 = fPts[2] - fPts[0]; |
@@ -21,11 +22,30 @@ bool SkDTriangle::contains(const SkDPoint& pt) const { |
double dot11 = v1.dot(v1); |
double dot12 = v1.dot(v2); |
+// original code doesn't handle degenerate input; isn't symmetric with inclusion of corner pts; |
+// introduces necessary error with divide; doesn't short circuit on early answer |
+#if 0 |
// Compute barycentric coordinates |
double invDenom = 1 / (dot00 * dot11 - dot01 * dot01); |
double u = (dot11 * dot02 - dot01 * dot12) * invDenom; |
double v = (dot00 * dot12 - dot01 * dot02) * invDenom; |
// Check if point is in triangle |
- return (u >= 0) && (v >= 0) && (u + v < 1); |
+ return (u >= 0) && (v >= 0) && (u + v <= 1); |
+#else |
+ double w = dot00 * dot11 - dot01 * dot01; |
+ if (w == 0) { |
+ return false; |
+ } |
+ double wSign = w < 0 ? -1 : 1; |
+ double u = (dot11 * dot02 - dot01 * dot12) * wSign; |
+ if (u <= 0) { |
+ return false; |
+ } |
+ double v = (dot00 * dot12 - dot01 * dot02) * wSign; |
+ if (v <= 0) { |
+ return false; |
+ } |
+ return u + v < w * wSign; |
+#endif |
} |