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
fix(canvas): compute circle coordinates with Pyth thm #917
base: main
Are you sure you want to change the base?
Conversation
The original algorithm may cause holes when the circle is large
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #917 +/- ##
=====================================
Coverage 92.0% 92.0%
=====================================
Files 61 61
Lines 15493 15591 +98
=====================================
+ Hits 14259 14352 +93
- Misses 1234 1239 +5 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally for a circle, every point is either one across or one up (or both) from the previous point. The circles we end up drawing here tend to be too boxy as they're filling multiple points per grid point.
It needs to work entirely in terms of grid points, which I think this change does, but it needs to go one step further:
The algorithm you're looking for for this is this one - https://en.wikipedia.org/wiki/Midpoint_circle_algorithm (you might have heard people refer to Bresenhams algorithm).
Instead of iterating over all the points in the area, it's most performant (and leads to good looking results) to iterate over the points that are in the circle. Start at the top point, iterate while moving either to the right or downwards or both only until you hit 45º and then mirror all those points on the x/y axis.
I suspect this should be an concise but understandable ~25 LoC (which is a large difference from 159 LoC here).
The algorithm I am using here is, for each horizontal line (with the same The other 100 lines of change are related to the translation between world and screen coordinates, which is in the canvas.rs |
The algorithm I implemented computes the range of coordinates to be plotted on each line in constant time (except the use of |
Another possible motivation for computing the range of X pixels on each horizontal line is that the implementation in #920 would be simpler — non-filled circle draws |
The original algorithm may cause holes when the circle is large
discussed in https://github.com/SOF3/plotters-ratatui-backend/pull/2/files#r1461295810
The test case changes by one pixel, but the output was very approximate anyway