aboutsummaryrefslogtreecommitdiffhomepage
path: root/samplecode
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2018-04-16 17:07:07 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-16 21:43:20 +0000
commit83dc47375f67a32b4e19b7df401226142129849b (patch)
treeddcaef64f1b3d62d903c724f0a75d2028500b322 /samplecode
parent840c66c58a149842f2416959f8e8118e9a86b56e (diff)
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 <reed@google.com> Commit-Queue: Mike Reed <reed@google.com>
Diffstat (limited to 'samplecode')
-rw-r--r--samplecode/SamplePath.cpp39
1 files changed, 33 insertions, 6 deletions
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 {