Pomax / bezierjs

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

Q: PolyBezier surface calculation #217

Open ShaMan123 opened 1 week ago

ShaMan123 commented 1 week ago

I am looking into calculating the surface of a given PolyBezier.

  let points, d;

  const bez = new Bezier(points);
  const poly = bez.outline(d);

I read a bit of the great guide https://pomax.github.io/bezierinfo.

At the beginning I thought of using integral calculus to do that. The challenge of this approach is correctly subtracting the curves from each other, i.e splitting into x-axis segments. This becomes much more complex when the outline is self intersecting.

Then I thought of using calculus theory instead of practice: bez.length() * d * 2 should yield the correct result. This is much simpler but still doesn't manage to include self intersecting outline cases.

Suggestions would be appreciated, thanks!

Pomax commented 1 week ago

It probably also depends on what you intend to do: are you trying to find individual points on the surface, are you trying to approximate the surface as a mesh for rendering purposes, etc.

ShaMan123 commented 1 week ago

In fact I need to calculate the value itself for printing purposes, then I can infer material usage, costs etc.

Pomax commented 1 week ago

But what is "the value"? A surface has infinitely many values, so what are you actually trying to find?

ShaMan123 commented 1 week ago

It is the fill of the PolyBezier.

ShaMan123 commented 1 week ago

Currently I am using pixel counting

Pomax commented 1 week ago

Are you implementing your own graphics (sub)system? Because most programming languages already come with shape fill solutions =)

ShaMan123 commented 1 week ago

no, I am not.

Because most programming languages already come with shape fill solutions =)

Please elaborate. I am using plain web vanilla js.

Pomax commented 1 week ago

The web stack has SVG: creating a <path d="...." stroke="none" fill="red"/> generally does the job for you. And Canvas2D will happily draw an SVG image wherever you need it using the .image function, too, if you're working in bitmap context rather than DOM context.

But of course the best solution will require knowing more about what you're actually working on and how you're implementing that atm.

ShaMan123 commented 1 week ago

I am building an app that prints letters using CNC The requirements are to know the surface of each letter (=fill of letter) and the outline. The machine will cut according to the outline and the cost is derived by the surface, the amount of material used. PolyBezier has made it easy to figure out the outline. Pixel counting is an easy workaround to obtain the fill value. I thought it might need a pure math solution... so I posted this issue. Regardless I think it is useful to be able to calculate the value using pure math if it isn't too complicated.

Thanks for the help so far!

Pomax commented 1 week ago

I think we're running into term confusion here: you're not talking about surfaces in relation to Bezier curves, which are a property of 3D curve sets. You're talking about actual physical material surfaces, so: be aware of the fact that the same term in different context can mean a wildly different thing. Don't talk about "bezier surfaces" when you're not talking about 3D surface math, you're just going to confuse math folks =)

So: you looking for a way to efficiently run a CnC bit along a path that will clear the interior of a closed shape. You absolutely don't want to use pixel counting for that, you want to know the dimensions of the CnC bit so that you can trace a path for that bit with minimal overlap. For that, you can just inset the polybezier: if your bit is Xmm, and you want a 10% cut overlap, and you have an initial outline, your first pass will be "that outline, offset by Xmm on the inside", and that's the first cutting pass. Then every subsequent pass is another (X*0.9mm) internal offset.

(i.e. take advantage of the fact that you have parallel contours)

ShaMan123 commented 6 days ago

take advantage of the fact that you have parallel contours

This is correct most of the time and means that to calculate the fill amount w/o pixel counting I need to split all the contours into segments by the x axis for integral calculation. Can be done but I hoped to avoid it with some clever math.

Thanks for your response and great work

ShaMan123 commented 6 days ago

If I do that would you be interested in a contribution exposing a method on PolyBezier? If so please provide a name for it ;)

Pomax commented 6 days ago

it depends a little on what it does, specifically, but something like sweep might make sense.