aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2017-04-13 14:26:00 -0600
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-04-14 15:14:11 +0000
commit4343654bc4a93812cba168a665deef0de2ebcfdd (patch)
treebee82de71d4671febf21ba1c13c2f312cbd2f8de /src/pathops
parent028c3d77ea0e49982e92c6c9614cf59d687f4370 (diff)
Improve accuracy of cubic classification
- Updates the logic to reflect the Loop-Blinn paper instead of the GPU gems website. - Removes the threshold for detecting local cusps. The serpentine codepath works for these cusps anyway, so what we really want to know is whether the discriminant is negative. - Makes sure to not scale the inflection function by 1/0. - Shifts the inflection function coefficients in d[] so they match the paper. - Stores the cubic discriminant in d[0]. Bug: skia: Change-Id: I909a522a0fd27c9c8dfbc27d968bc43eeb7a416f Reviewed-on: https://skia-review.googlesource.com/13304 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Chris Dalton <csmartdalton@google.com>
Diffstat (limited to 'src/pathops')
-rw-r--r--src/pathops/SkPathOpsCubic.cpp20
1 files changed, 11 insertions, 9 deletions
diff --git a/src/pathops/SkPathOpsCubic.cpp b/src/pathops/SkPathOpsCubic.cpp
index d842e2cc0c..1e74eb0afd 100644
--- a/src/pathops/SkPathOpsCubic.cpp
+++ b/src/pathops/SkPathOpsCubic.cpp
@@ -248,17 +248,18 @@ int SkDCubic::ComplexBreak(const SkPoint pointsPtr[4], SkScalar* t) {
if (cubic.monotonicInX() && cubic.monotonicInY()) {
return 0;
}
- SkScalar d[3];
+ SkScalar d[4];
SkCubicType cubicType = SkClassifyCubic(pointsPtr, d);
switch (cubicType) {
- case kLoop_SkCubicType: {
+ case SkCubicType::kLoop: {
// crib code from gpu path utils that finds t values where loop self-intersects
// use it to find mid of t values which should be a friendly place to chop
- SkScalar tempSqrt = SkScalarSqrt(4.f * d[0] * d[2] - 3.f * d[1] * d[1]);
- SkScalar ls = d[1] - tempSqrt;
- SkScalar lt = 2.f * d[0];
- SkScalar ms = d[1] + tempSqrt;
- SkScalar mt = 2.f * d[0];
+ SkASSERT(d[0] < 0);
+ SkScalar tempSqrt = SkScalarSqrt(-d[0]);
+ SkScalar ls = d[2] - tempSqrt;
+ SkScalar lt = 2.f * d[1];
+ SkScalar ms = d[2] + tempSqrt;
+ SkScalar mt = 2.f * d[1];
if (roughly_between(0, ls, lt) && roughly_between(0, ms, mt)) {
ls = ls / lt;
ms = ms / mt;
@@ -269,8 +270,9 @@ int SkDCubic::ComplexBreak(const SkPoint pointsPtr[4], SkScalar* t) {
}
}
// fall through if no t value found
- case kSerpentine_SkCubicType:
- case kCusp_SkCubicType: {
+ case SkCubicType::kSerpentine:
+ case SkCubicType::kLocalCusp:
+ case SkCubicType::kInfiniteCusp: {
double inflectionTs[2];
int infTCount = cubic.findInflections(inflectionTs);
double maxCurvature[3];