Reputation: 11929
I'd like to calculate all points in a circle. I already know I can calculate points using x = r * cos(theta) + x0
, y = r * sin(theta) + y0
- however I was wondering if there is a nice way to find an appropriate step size for theta, based on the resolution of my pixel canvas (or LCD for me) and the radius of the circle.
This is the code I already have (_arange()
is like range()
but also takes a floating value for step
):
def circle(x0, y0, r):
step = 2 * math.pi / 1000
for theta in _arange(0, 2 * math.pi, step):
x = x0 + r * math.cos(theta)
y = y0 + r * math.sin(theta)
set(round(x), round(y))
Upvotes: 2
Views: 755
Reputation: 72312
For a different approach, start with a square with vertices at (x0+-r,y0) and (x0,y0+-r) and recursively divide each edge at its midpoint and project it onto the circle. Stop recursion when an edge has length less than a pixel. Perhaps not the fastest algorithm but it does avoid trigonometry, though it requires square roots and divisions.
Here is some code in Lua that implements this strategy. As a bonus consequence of how the recursion is organized, it outputs points in correct circular order.
local tolerance=1e-2
local function explore(x0,y0,r,x1,y1,x2,y2)
local x=x1+x2
local y=y1+y2
local s=r/math.sqrt(x^2+y^2)
x=s*x
y=s*y
if math.sqrt((x1-x2)^2+(y1-y2)^2)<tolerance then
print(x+x0,y+x0)
else
explore(x0,y0,r,x1,y1,x,y)
explore(x0,y0,r,x,y,x2,y2)
end
end
local function circle(x0,y0,r)
explore(x0,y0,r,r,0,0,r)
explore(x0,y0,r,0,r,-r,0)
explore(x0,y0,r,-r,0,0,-r)
explore(x0,y0,r,0,-r,r,0)
end
circle(0,0,2)
Upvotes: 1
Reputation: 272217
It sounds like the midpoint circle algorithm may be more appropriate for what you want.
the midpoint circle algorithm is an algorithm used to determine the points needed for drawing a circle
Upvotes: 6