diff options
author | Chris Dalton <csmartdalton@google.com> | 2017-04-13 14:26:00 -0600 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-04-14 15:14:11 +0000 |
commit | 4343654bc4a93812cba168a665deef0de2ebcfdd (patch) | |
tree | bee82de71d4671febf21ba1c13c2f312cbd2f8de /src/pathops | |
parent | 028c3d77ea0e49982e92c6c9614cf59d687f4370 (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.cpp | 20 |
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]; |