Skip to content

Instantly share code, notes, and snippets.

@RKushnir
Created February 12, 2012 15:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RKushnir/1809173 to your computer and use it in GitHub Desktop.
Save RKushnir/1809173 to your computer and use it in GitHub Desktop.
Circle drawing algorithm
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