As you've asked so nicely, I'll try to explain it. Even though I'm really bad at drawing in Gimp.
I usually thought of cutting width (as a proportion of the tool diameter) instead of cutting angle. Then the cutting width multiplied by the cutting length equals the cutting area, because the circular curve at the start and end of the area is the same. So you are calculating the same thing, but in a more complicated way.
It's okay for the cutting width to vary within a tolerance. You can probe with a straight line segment from the circle of the cutter a small distance in from the point of engagement pointing in the direction of travel, and find where it enters uncut stock. This is where you must have your the next sample.
This protects from over-cutting the stock. But you also need to take smaller steps (and turn to the right) when it is undercutting stock, but this is not so important. You are free to control the turning radius when going to the right, because in high speed machining it's better to undercut the stock than to make a sharp change in direction. Playing these two factors together, it's possible for it to nearly always pick the optimal step at each point and rarely have to resample.
We should talk about C++ and python and stuff, and maybe you can call me sometime if you like. I developed this algorithm for about 10 years on and off, so we can discuss how to future-proof its structure, with toolpath reordering, etc. You seem to have got ahead on the linking part, as we had a very difficult time working without any model of the cleared area (we could probe it with circles and lines, but didn't have an area model). See here for how much trouble we had: https://www.freesteel.co.uk/wpblog/2014 ... g-motions/
I'll see if I can set up Visual Studio, but I don't think I want to do C++ for pleasure after 20 years at it. I am pretty sure, like all heavy CAM algorithms, it should run outside the main process. Most commercial CAM algorithms are run by saving the triangles and boundaries to a file and starting up a separate process. It can communicate progress and results through the stdout or a socket stream. This means they don't bring down the whole CAD system when they crash, and are easier to test and debug in isolation. And for future proofing, it meant it could be distributed to the cloud and potentially run instantaneously if separated well enough. It's too difficult to develop code like this when it is behind a huge UI that needs to be booted up at every iteration.