Last active
December 16, 2015 10:08
-
-
Save jsundram/5417389 to your computer and use it in GitHub Desktop.
Port of Pavel Sountsov's DrawCircle to python. Basic idea -- avoid using sin/cos a lot (like a naive implementation) when drawing a circle.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import math | |
def estimate_segments(radius, segment_length=0.25): | |
""" Basically want segments that are about the size of .25 pixel for the given radius. | |
Derive as follows: | |
segment_length as a function of theta: | |
segment_length = (1 - cos(theta)) * radius | |
Solving for theta given segment_length: | |
theta = math.acos(1 - (float(segment_length) / radius)) | |
""" | |
# How many thetas in a circle? | |
return 2*math.pi / math.acos(1 - (float(segment_length) / radius)) | |
def fast_estimate_segments(radius): | |
"""From P. Sountsov. Approximates the more precise result without resorting to acos""" | |
return 10 * math.sqrt(radius) | |
def circle_points(cx, cy, r, segments, theta_start=0): | |
"""from here: http://slabode.exofire.net/circle_draw.shtml""" | |
theta = 2 * pi / segments | |
# precalculate sin/cos | |
c = cos(theta) | |
s = sin(theta) | |
# If we don't need to accept theta_start, hardcoding | |
# to x = 0, y = r would be faster. | |
x = r*cos(theta_start) | |
y = r*sin(theta_start) | |
pts = [None] * (segments + 1) | |
for i in xrange(segments+1): | |
pts[i] = (cx + x, cy + y) | |
# apply the rotation matrix | |
x, y = (c * x - s * y, s * x + c * y) | |
return pts |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment