Reputation: 145
I wrote a function that "draws" a circle into a coordinate system (a 2d array/list):
def drawCircle(x,y,r,steps, draw=True):
coords = []
for n in range(steps):
coords.append(((round(x + r * math.cos(2 * math.pi * (n / steps)))),round(y + r * math.sin(2 * math.pi * (n / steps)))))
if draw:
for n in range(len(coords)):
self.drawPixel(coords[n][0],coords[n][1])
return list(set(coords))
It returns how many points are actually visible, because it overdraws some points.
My question:
(How) can I determine steps
from r
. That would make the function more efficient.
If I run
print(len(drawCircle(10, 10, r, 200)))
it gives me the answer I'm searching for.
for r in range(5,30):
print(len(drawCircle(10, 10, r, 200)))
40
40
56
56
72
80
80
88
96
96
112
112
128
136
120
128
152
152
176
152
176
168
160
176
192
I can't see any pattern. The
drawPixel(x,y)
just does list[y][x] = "#"
Upvotes: 0
Views: 70
Reputation: 71
I am new to this, but if I understand correctly, is this what you are looking for
import sympy as sy # a symbolic math module in numpy stack
import sympy.geometry as gm # a geometry module in sympy
import numpy as np # you might know this
unit=3 # the units of your field
#List of circles from 5 to 30
circles=[gm.Circle(gm.Point(10,10),r) for r in range(5,30)]
# list of circle perimeters
perimeters=[i.circumference for i in circles]
#number of units for each radius step
num_of_units=[i//unit for i in perimeters]
print(num_of_units)
Upvotes: 1
Reputation: 80187
Instead of using trigonometry, exploit effective Bresenham circle drawing algorithm.
It produces only distinct points.
Upvotes: 1
Reputation: 788
You might be missing that the number of coordinates/pixels you function returns depends on both the r
and step
variables. If steps
is sufficiently large, the number the number of pixels wont increase with even bigger steps
.
consider this:
for steps in range(200, 5000, 200):
print(len(drawCircle(10, 10, 40, steps, draw=False)))
Out [1]:
200
280
288
304
288
312
320
320
312
320
320
320
312
320
320
320
320
320
320
320
320
320
320
320
So you might want to get the smallest number of steps
that gets you the largest possible number of coorditates/pixels.
That is a bit more challenging, and I can't think of a very straightforward way to calculate this. A "bruteforce" solution could be this
def drawCircle(x,y,r, draw=True):
steps = 500
n_pixels = 0
n_pixels_prev = -1
while n_pixels_prev < n_pixels:
coords = []
for n in range(steps):
x_pix = round( x + r * math.cos(2 * math.pi * (n / steps)) )
y_pix = round( y + r * math.sin(2 * math.pi * (n / steps)) )
coords.append( (x_pix, y_pix) )
n_pixels_prev = n_pixels
n_pixels = len(set(coords))
steps += 1000
if draw:
for n in range(len(coords)):
self.drawPixel(coords[n][0],coords[n][1])
return list(set(coords))
What it does is choose increasingly bigger values for step
until it the number of pixels does not increase any more. The function then returns those coordinates. But this is not ideal as you can imagine.
Upvotes: 1