From de0600e1e2a0fa4e666e7c49c772379a29ffeba9 Mon Sep 17 00:00:00 2001 From: treeform Date: Wed, 29 Jun 2022 22:49:28 -0700 Subject: [PATCH] Cubic tangent error. --- src/pixie/paths.nim | 25 ++++++++++++++++++++----- tests/test_path2.nim | 12 ++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 tests/test_path2.nim diff --git a/src/pixie/paths.nim b/src/pixie/paths.nim index 4cb2fa5..9739a2f 100644 --- a/src/pixie/paths.nim +++ b/src/pixie/paths.nim @@ -675,10 +675,21 @@ proc commandsToShapes( proc addCubic(shape: var Polygon, at, ctrl1, ctrl2, to: Vec2) = ## Adds cubic segments to shape. proc compute(at, ctrl1, ctrl2, to: Vec2, t: float32): Vec2 {.inline.} = - pow(1 - t, 3) * at + - pow(1 - t, 2) * 3 * t * ctrl1 + - (1 - t) * 3 * pow(t, 2) * ctrl2 + - pow(t, 3) * to + let + t2 = t*t + t3 = t2*t + at * (-t3 + 3*t2 - 3*t + 1) + + ctrl1 * (3*t3 - 6*t2 + 3*t) + + ctrl2 * (-3*t3 + 3*t2) + + to * (t3) + + proc computeDerv(at, ctrl1, ctrl2, to: Vec2, t: float32): Vec2 {.inline.} = + let + t2 = t*t + at * (-3*t2 + 6*t - 3) + + ctrl1 * (9*t2 - 12*t + 3) + + ctrl2 * (-9*t2 + 6*t) + + to * (3 * t2) var t: float32 # Where we are at on the curve from [0, 1] @@ -691,7 +702,11 @@ proc commandsToShapes( raise newException(PixieError, "Unable to discretize cubic") let midpoint = (prev + next) / 2 - error = (midpoint - halfway).lengthSq + lineTangent = midpoint - prev + curveTangent = computeDerv(at, ctrl1, ctrl2, to, t + step / 2) + curveTangentScaled = curveTangent.normalize() * lineTangent.length() + error = (midpoint - halfway).lengthSq + + (lineTangent - curveTangentScaled).lengthSq if error > errorMarginSq: next = halfway halfway = compute(at, ctrl1, ctrl2, to, t + step / 4) diff --git a/tests/test_path2.nim b/tests/test_path2.nim new file mode 100644 index 0000000..bc6f70a --- /dev/null +++ b/tests/test_path2.nim @@ -0,0 +1,12 @@ +import chroma, pixie, pixie/fileformats/png, strformat + +block: + let + image = newImage(100, 100) + pathStr = """ + M 40 40 L 40 80 L 80 80 L 80 40 C 80 -20 40 100 40 40 + """ + color = rgba(0, 0, 0, 255) + image.fill(rgba(255, 255, 255, 255)) + image.fillPath(pathStr, color) + image.writeFile("tests/paths/pathSwish.png")