Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

simplifying a curve? #67

Closed
mbutterick opened this issue Sep 4, 2020 · 2 comments
Closed

simplifying a curve? #67

mbutterick opened this issue Sep 4, 2020 · 2 comments

Comments

@mbutterick
Copy link

Suppose I delete the marked point on the glyph below. Currently I get the glyph in the second pic, which is not wrong. But it would be more useful to get something closer to the glyph in the third pic (where the remaining Bézier handles have been adjusted to approximate the curve that existed before.).

The question: is there a way to accomplish this in BezierKit? I’m not sure how to characterize this operation. I suppose it would be a sort of curve simplification, where the remaining BCPs are adjusted to produce the curve that’s the closest fit to the one that was there before.

Screen Shot 2020-09-04 at Sep 04  4 43 09 PM

Screen Shot 2020-09-04 at Sep 04  4 43 14 PM

Screen Shot 2020-09-04 at Sep 04  4 43 33 PM

@hfutrell
Copy link
Owner

hfutrell commented Sep 5, 2020

@mbutterick what I believe is going on here is that in the the second image the tangent lines / derivatives match, but I think what you want is to scale those tangent lines so that the curvatures match at the endpoints.

The curvature is given by the first and second derivatives

k = | x' y'' - y' x'' | / (x'^2 + y'^2)^(3/2)

https://en.wikipedia.org/wiki/Curvature#Curvature_from_arc_and_chord_length

BezierKit doesn't have explicit support for this, and only has support for getting the first derivative. The second derivative for a cubic curve is linear, which can be obtained by taking the difference between the control points twice. Something like this

let d0 = curve.p1 - curve.p0
let d1 = curve.p2 - curve.p1
let d2 = curve.p3 - curve.p2
let dd0 = d1 - d0
let dd1 = d2 - d1
let secondDerivative = LineSegment(p0: 1.0 / 6.0 * dd0, p1: 1.0 / 6.0 * dd1)

A simpler approach that may work well enough would be to scale the length of the tangent lines by the ratio of the length of the new vs old curves. That way if the new curve is larger as in your example, it would get longer tangent lines. You could do that by comparing curve.length()

@mbutterick
Copy link
Author

length is a good idea. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants