-
Notifications
You must be signed in to change notification settings - Fork 6
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
Offset gets really lumpy at large offset deltas. #8
Comments
Lerping the handles toward the control points by 1. - min(start_offset, end_offset) / max(start_offset, end_offset) does work in getting rid of the lumpiness but it comes with a ton of problems of it's own that make it an unsuitable patch for this. I knew it was a bit naive, but I figured I'd report that I attempted it anyway. |
It looks like the scaling algorithm starts to break down the larger the difference in offsets: I think there's probably a critical ratio between the start and the end points where the control points start to overlap too much and this effect starts to show up. I suspect it's fixable but I'm going to need to spend some time on it. In the meantime, though, I've just pushed a new offsetting routine I've been thinking of including for a while that uses the least-mean-squared curve fitting algorithm instead. This makes it possible to use any function for the offset and will always produce really good approximations, but is much slower than the scaling algorithm, and has a slight tendency to produce straight lines if you don't use enough subdivisions. It's called like this:
(We can use large values for max_error here I think as we expect the points to already roughly lie on a bezier curve) Here's a side-by side comparison, old offset in green, new in red, slightly different offsets to make the differences more clear: |
All that said, I just realised I was using the wrong scale factors for the control points when the offsets were changing. I've fixed this issue too, so the error of that algorithm is now much less. Here's the LMS and the newly fixed scaling algorithm overlaid on top of each other: I had much less pronounced 'lumpiness' in the example curve I chose, but you can see it has been eliminated here. The issue was the routine was using the wrong scale factors for moving the control point - they should be scaled with the offsets at t=1/3 and t=2/3 rather than at the start and end of the curve. |
This is an update not to poorly describe another bug (lumpy is not exactly a technical term), but to thank you. The new offset_lms is absolutely fantastic, performant, and it's outputs are more stable as points change. Flo_curves is an awesome library and you are an awesome maintainer. You've replied to every one of my issues. I plan to move as much of my existing math code over to using flo_curve's primitives as they're higher quality than mine. You mentioned it being slower than the other offset code, but on my system in release mode it takes <1ms to offset a piecewise collection of curves. The addition of the closure to describe offsets over the curve allowed me to add cosine and cubic interpolation which seriously improves the output by removing discontinuities where the offsets meet. Here is your offset code + a bunch of code I wrote for our editor and stroking library in action: Modular.Font.Editor.K.Glyph.editor.C__Users_Matt_Documents_GitHub_QStroke_l.glif.2021-03-04.17-49-18.mp4The results are absolutely great, and the way the new offset handles cusps and strange curvature at control points is much better. |
On the topic of the new offset algorithm I'd definitely add a way to specify tangent offsets too. In my fork I simply made the closure return (f64, f64) and offset by the first along the normal, and the second along the tangent. |
Hi, I've now added a function that can do this: |
The purple ribs here represent the offsets. I didn't really notice this problem until I got editing going in real time. This is with modifications that correct the divide point to be 1/2 of length instead of 1/2 of t, but the results are approximately the same either way.
This is with the constant inside curve.rs set to like .9999 too. It seems like this just makes the lumpiness higher frequency.
You can see here it shows up in more reasonable examples too.
I wonder if reducing the curvature of the output beziers as you get further from the curve itself could work? I'm going to try to come up with some method of bringing the handles closer to the output curve as they get farther from the input curve.
It also seems linked more with a change from start -> finish than with the actual value of offset itself as well.
The text was updated successfully, but these errors were encountered: