Created
February 12, 2012 15:53
-
-
Save RKushnir/1809173 to your computer and use it in GitHub Desktop.
Circle drawing algorithm
This file contains hidden or 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 | |
| @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