From 83dc47375f67a32b4e19b7df401226142129849b Mon Sep 17 00:00:00 2001 From: Mike Reed Date: Mon, 16 Apr 2018 17:07:07 -0400 Subject: show cubic error-vectors anchored on pt(s) of max deviation Bug: skia: Change-Id: I59a6a218ddbf46bc5d7ebea6303701b5182eafa7 Reviewed-on: https://skia-review.googlesource.com/121427 Reviewed-by: Mike Reed Commit-Queue: Mike Reed --- samplecode/SamplePath.cpp | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) (limited to 'samplecode') diff --git a/samplecode/SamplePath.cpp b/samplecode/SamplePath.cpp index f523fe6ef3..61098d2cad 100644 --- a/samplecode/SamplePath.cpp +++ b/samplecode/SamplePath.cpp @@ -581,6 +581,21 @@ static SkPoint lerp(SkPoint a, SkPoint b, float t) { return a * (1 - t) + b * t; } +static int find_max_deviation_cubic(const SkPoint src[4], SkScalar ts[2]) { + // deviation = F' x (d - a) == 0, solve for t(s) + // F = At^3 + Bt^2 + Ct + D + // F' = 3At^2 + 2Bt + C + // Z = d - a + // F' x Z = 3(A x Z)t^2 + 2(B x Z)t + (C x Z) + // + SkVector A = src[3] + (src[1] - src[2]) * 3 - src[0]; + SkVector B = (src[2] - src[1] - src[1] + src[0]) * 3; + SkVector C = (src[1] - src[0]) * 3; + SkVector Z = src[3] - src[0]; + // now forumlate the quadratic coefficients we need to solve for t : F' x Z + return SkFindUnitQuadRoots(3 * A.cross(Z), 2 * B.cross(Z), C.cross(Z), ts); +} + class CubicCurve2 : public SampleView { public: enum { @@ -591,6 +606,7 @@ public: SkScalar fT = 0.5f; bool fShowSub = false; bool fShowFlatness = false; + SkScalar fScale = 0.75; CubicCurve2() { fPts[0] = { 90, 300 }; @@ -663,12 +679,23 @@ protected: pts[1] = (fQuad[0] + fQuad[2]) * 0.5; canvas->drawLine(pts[0], pts[1], paint); - SkVector v = fPts[0] - fPts[1] - fPts[1] + fPts[2]; - v = v * 0.75; - canvas->drawLine(fPts[1], fPts[1] + v, paint); - v = fPts[1] - fPts[2] - fPts[2] + fPts[3]; - v = v * 0.75; - canvas->drawLine(fPts[2], fPts[2] + v, paint); + // cubic + + SkVector v0 = (fPts[0] - fPts[1] - fPts[1] + fPts[2]) * fScale; + SkVector v1 = (fPts[1] - fPts[2] - fPts[2] + fPts[3]) * fScale; + + SkPoint anchor; + SkScalar ts[2]; + int n = find_max_deviation_cubic(fPts, ts); + if (n > 0) { + SkEvalCubicAt(fPts, ts[0], &anchor, nullptr, nullptr); + canvas->drawLine(anchor, anchor + v0, paint); + if (n == 2) { + SkEvalCubicAt(fPts, ts[1], &anchor, nullptr, nullptr); + } + canvas->drawLine(anchor, anchor + v1, paint); + } + // not sure we can get here } void onDrawContent(SkCanvas* canvas) override { -- cgit v1.2.3