Created
February 12, 2012 15:53
-
-
Save RKushnir/1809173 to your computer and use it in GitHub Desktop.
Circle drawing algorithm
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
class Circle | |
def initialize(radius) | |
@radius = radius | |
end | |
def draw | |
unless @canvas | |
diameter = 2 * @radius | |
@canvas = Array.new(diameter + 1){ ' ' * (2 * (diameter + 1)) } | |
key_points.each do |kx, ky| | |
[kx, diameter - kx].product([ky, diameter - ky]).each do |x, y| | |
@canvas[x][2 * y] = @canvas[y][2 * x] = '*' | |
end | |
end | |
end | |
puts @canvas.join "\n" | |
end | |
private | |
def key_points | |
q = (1 - 0.5 * (2 ** 0.5)) * @radius # (1 - cos45) * radius | |
[*q.floor..@radius].product([*0..q.ceil]).select{|x, y| lies_on_circle? x, y } | |
end | |
# Detects if point is closest to the circle edge by checking the devitaion of points above and below | |
def lies_on_circle?(x, y) | |
cx, cy = @radius, @radius # central point | |
dx2, r2 = (x - cx) ** 2, @radius ** 2 | |
[y - 1, y, y + 1].min_by {|y| (dx2 + (y - cy) ** 2 - r2) ** 2 } == y | |
end | |
end | |
Circle.new(ARGV[0].to_i).draw | |
# ruby circle.rb 7 | |
# * * * * * | |
# * * * * | |
# * * | |
# * * | |
# * * | |
# * * | |
# * * | |
# * * | |
# * * | |
# * * | |
# * * | |
# * * | |
# * * | |
# * * * * | |
# * * * * * |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment