class AsciiParadise::Circle
Attributes
Public Class Methods
#¶ ↑
initialize¶ ↑
Initialize a Circle
object passing a value for radius, aspect ratio and drawing character.
#¶ ↑
# File lib/ascii_paradise/static_ascii/circle.rb, line 52 def initialize( radius, aspect_ratio = 1.0, char = '#' ) @radius = radius.to_i @aspect_ratio = aspect_ratio.to_f @char = char @radius = 10 if @radius <= 0 fail 'Error: aspect ratio must be > 0' if @aspect_ratio <= 0 # ======================================================================= # # a is the semimajor axis of the ellipse and is equal to the given # radius # ======================================================================= # @a = @radius # ======================================================================= # # b is the semiminor axis of the ellipse and is calculated from a # and the given aspect ratio # ======================================================================= # @b = (@a / @aspect_ratio).round # ======================================================================= # # calculate the size of the canvas # ======================================================================= # @w, @h = @a * 2 + 1, @b * 2 + 1 # ======================================================================= # # The center coordinates correspond to the size of semiaxis. # ======================================================================= # @cx, @cy = @a, @b # ======================================================================= # # initialize the canvas with spaces # ======================================================================= # @canvas = Array.new(@w * @h, ' ') # ======================================================================= # # draw ellipse on the canvas # ======================================================================= # draw_ellipse(@a, @b) end
Public Instance Methods
#¶ ↑
canvas?¶ ↑
@canvas is a linear Array that is initially filled with spaces.
#¶ ↑
# File lib/ascii_paradise/static_ascii/circle.rb, line 218 def canvas? @canvas end
#¶ ↑
draw_ellipse
¶ ↑
Draw an ellipse on canvas. This method implements a Bresenham based algorithm by John Kennedy:
http://homepage.smc.edu/kennedy_john/BELIPSE.PDF
The method calculates two set of points in the first quadrant.
The first set starts on the positive x axis and wraps in a counterclockwise direction until the tangent line slope is equal to -1. The second set starts on the positive y axis and wraps in a clockwise direction until the tangent line slope is equal to -1.
#¶ ↑
# File lib/ascii_paradise/static_ascii/circle.rb, line 128 def draw_ellipse(a, b) a_square = 2 * a ** 2 b_square = 2 * b ** 2 draw_first_set( a, b, a_square, b_square) draw_second_set(a, b, a_square, b_square) end
#¶ ↑
draw_first_set
¶ ↑
The method increments y and decides when to decrement x testing the sign of a function. In this case, the decision function is (2*ellipse_error+x_change) and its value is calculated iteratively.
#¶ ↑
# File lib/ascii_paradise/static_ascii/circle.rb, line 143 def draw_first_set(a, b, a_square, b_square) x, y = a, 0 x_change, y_change = b_square / 2 * (1 - 2 * a), a_square / 2 stopping_x, stopping_y = b_square * a, 0 ellipse_error = 0 while (stopping_x >= stopping_y) do plot_four_points(x, y) y += 1 stopping_y += a_square ellipse_error += y_change y_change += a_square if (2 * ellipse_error + x_change) > 0 x -= 1 stopping_x -= b_square ellipse_error += x_change x_change += b_square end end end
#¶ ↑
draw_second_set
¶ ↑
The method increments x and decides when to decrement y testing the sign of a function. In this case, the decision function is (2*ellipse_error+y_change) and its value is calculated iteratively.
#¶ ↑
# File lib/ascii_paradise/static_ascii/circle.rb, line 172 def draw_second_set(a, b, a_square, b_square) x, y = 0, b x_change, y_change = b_square / 2, a_square / 2 * (1 - 2 * b) stopping_x, stopping_y = 0, a_square * b ellipse_error = 0 while (stopping_x <= stopping_y) do plot_four_points(x, y) x += 1 stopping_x += b_square ellipse_error += x_change x_change += b_square if (2 * ellipse_error + y_change) > 0 y -= 1 stopping_y -= a_square ellipse_error += y_change y_change += a_square end end end
#¶ ↑
output¶ ↑
#¶ ↑
# File lib/ascii_paradise/static_ascii/circle.rb, line 209 def output print to_s end
#¶ ↑
plot_four_points
¶ ↑
Translates and mirrors point (x, y) in the quadrants taking advantage of the simmetries in the ellipse. Thus, for a given point (x, y) the method plot three other points in the remaining quadrants.
#¶ ↑
# File lib/ascii_paradise/static_ascii/circle.rb, line 106 def plot_four_points(x, y) point(@cx + x, @cy + y) point(@cx - x, @cy + y) point(@cx + x, @cy - y) point(@cx - x, @cy - y) end