Skip to content

Instantly share code, notes, and snippets.

@RKushnir
Created February 12, 2012 15:53
Show Gist options
  • 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
@points = []
0.upto(radius) do |x|
0.upto(radius / 2) do |y|
@points << [x , y] if lies_on_circle?(x, y)
end
end
end
def draw
unless @canvas
@canvas = Array.new(diameter + 1){ Array.new(2 * (diameter + 1)){ ' ' } }
@points.each do |p|
set_symmetric_points(p[0], p[1])
end
end
puts @canvas.map(&:join).join "\n"
end
def diameter
@diameter ||= 2 * @radius
end
private
# 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
dx2, r2 = (x - cx) ** 2, @radius ** 2
[y - 1, y, y + 1].min_by {|y| (dx2 + (y - cy) ** 2 - r2) ** 2 } == y
end
# Sets 8 points symmetrically to circle center
def set_symmetric_points(x, y)
[x, diameter - x].product([y, diameter - y]).each do |p|
@canvas[p[0]][2 * p[1]] = @canvas[p[1]][2 * p[0]] = '*'
end
end
end
Circle.new(15).draw
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment