Bezier curve package

Is there an Elm package with a function to calculate the bounding box of a bezier curve?

1 Like

Generally elm-geometry would be your best bet for this kind of question. And indeed:

https://package.elm-lang.org/packages/ianmackenzie/elm-geometry/latest/QuadraticSpline2d#boundingBox

1 Like

That function is too imprecise for me (i’m using the cubic one). In this example (https://ellie-app.com/fCvf5wmXfMca1), it gives a bounding box that is way too big.

image

Is there an existing package with a function that can calculate the size of only the black area?

If you are using a cubic spline, you should use the bounding box for the cubic one (CubicSpline2d - elm-geometry 3.9.1).

But in any case, as you noted, those bounding boxes are computed based on the control points to be more efficient, even though that results in bigger boxes.

If you want to have a solution closer to the actual curve, one simple way is to sample points along the curve, with for example the pointOn function CubicSpline2d - elm-geometry 3.9.1. Then you can take the min and max coordinates that you obtained. Beware though that with this approach you’ll get the reverse of earlier, i.e. a bounding box that may be slightly to small if your sampling didn’t get points on some extremum positions.

Last option, which may be the most rewarding is to go the math way, by computing the derivatives of your curve in order to find its extremum points analytically. Here is a SO post that seems to explain the computations correctly (I didn’t check): math - Calculating the bounding box of cubic bezier curve - Stack Overflow

2 Likes

I worked with Bezier curves 4 years ago or so (not in Elm though), and needed to find the bounding box. I found this very helpful: A Primer on BĂ©zier Curves. Just leaving it here in case it helps.

1 Like

I implemented Beziers in two separate applications but the second was thirty years ago, so this will be a little bit hand-waving…

Cubic Beziers are parametric curves in which both the x and y coordinates are cubic polynomials of the parameter t. This means that the derivatives with respect to t are quadratics. Which means that the zeros can be found via the quadratic formula. So, for a given Beziers segment, compute the derivatives in each dimension, find the zeros, discard the zeros outside of the 0 to 1 parameter range, and find the points at the remaining zeros. Together with the start and end points these are all of the points you need to consider in finding the bounding box.

For a multi-segment curve, you do this work for each segment.

That said, you could skip the effort if the bounding box of the control points for a new segment lies within the accumulated bounding box since the accurate bounding box for the segment will be contained within the control bounding box. Whether this pays off often enough in practice to justify the extra logic, I can’t say.

Unrelated to Elm but related to BĂ©zier Curves, this is a beautiful introduction:

4 Likes

I did this

https://ellie-app.com/fJdz9J26GzPa1

Sampling points appears to be good enough for this case. Of course this cannot be generalized since it will entirely depend on the actual curves. But yeah, this is a simplicity trade off. And the validity of this trade off depends on your requirements.

For what it’s worth, I do plan on improving elm-geometry to compute tight bounding boxes for quadratic and cubic splines at some point - I created an issue for this a while back =)

The sampling approach should certainly work if you’re OK with some small amount of approximation error; note that you can control the amount of approximation error (e.g. to guarantee the bounding box is accurate to within half a pixel or something) using CubicSpline2d.approximate instead of choosing an arbitrary number of points to evaluate at.

2 Likes

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.