Pomax / bezierjs

A nodejs and client-side library for (cubic) Bezier curve work
MIT License
1.73k stars 233 forks source link

Why get(t = 0.5) point is not the middle point of the curve? #194

Closed AJLoveChina closed 1 year ago

AJLoveChina commented 1 year ago

Thanks for this library, and I am wondering why get(t=0.5) point is not located at the middle of the curve? (the left part's length is not the same as the right part)

image

Test on http://pomax.github.io/bezierjs/

justvanrossum commented 1 year ago

These sections from "the book" provide some insights:

Pomax commented 1 year ago

tldr version: because t is the curve's computational input parameter, unrelated to distance along the curve.

AJLoveChina commented 1 year ago

thanks @justvanrossum @Pomax

AJLoveChina commented 1 year ago

hi @justvanrossum @Pomax , one more question : which api can get the middle point (by distance), I tried but can't find this function.

Thanks :_)

Pomax commented 1 year ago

You'd need the arc-length reparameterized version of the curve, which is extremely not trivial, so the usual approach is to just binary search your way to victory: get the length of your curve, and set your target distance to half that. Then start with t=0.5 and compute the arc length. If it's too high, pick t -= 1/4, if it's too low, pick t += 1/4. If those are too high, repeat but pick t -= 1/8, and if it's too low, pick t += 1/8. And then you keep repeating that with 1/16, 1/32, 1/64 etc. etc. until you're "close enough to your target distance".

Or, alternatively, you generate a LUT with an approximated curve length (based on pixel distance rather than true arc length) and then you find the two points in that LUT that are closes to the total length divided by 2 and use a t value that's an interpolation of those two points.