Class: AsciiParadise::Circle
- Inherits:
-
Object
- Object
- AsciiParadise::Circle
- Defined in:
- lib/ascii_paradise/static_ascii/circle.rb
Overview
AsciiParadise::Circle
Instance Attribute Summary collapse
-
#cx ⇒ Object
readonly
# cx, cy are the coordinates of the circle’s center.
-
#cy ⇒ Object
readonly
Returns the value of attribute cy.
-
#h ⇒ Object
readonly
# w, h are width and height of the canvas ========================================================================= #.
-
#radius ⇒ Object
readonly
Returns the value of attribute radius.
-
#w ⇒ Object
readonly
# w, h are width and height of the canvas ========================================================================= #.
Instance Method Summary collapse
-
#canvas? ⇒ Boolean
(also: #canvas)
# === canvas?.
-
#draw_ellipse(a, b) ⇒ Object
# === draw_ellipse.
-
#draw_first_set(a, b, a_square, b_square) ⇒ Object
# === draw_first_set.
-
#draw_second_set(a, b, a_square, b_square) ⇒ Object
# === draw_second_set.
-
#initialize(radius, aspect_ratio = 1.0, char = '#') ⇒ Circle
constructor
# === initialize.
-
#output ⇒ Object
(also: #display)
# === output ========================================================================= #.
-
#plot_four_points(x, y) ⇒ Object
# === plot_four_points.
-
#point(x, y) ⇒ Object
# === point.
-
#to_s ⇒ Object
# === to_s.
Constructor Details
#initialize(radius, aspect_ratio = 1.0, char = '#') ⇒ Circle
#
initialize
Initialize a Circle object passing a value for radius, aspect ratio and drawing character.
#
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# 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 |
Instance Attribute Details
#cx ⇒ Object (readonly)
#
cx, cy are the coordinates of the circle’s center.
#
38 39 40 |
# File 'lib/ascii_paradise/static_ascii/circle.rb', line 38 def cx @cx end |
#cy ⇒ Object (readonly)
Returns the value of attribute cy.
39 40 41 |
# File 'lib/ascii_paradise/static_ascii/circle.rb', line 39 def cy @cy end |
#h ⇒ Object (readonly)
#
w, h are width and height of the canvas
#
44 45 46 |
# File 'lib/ascii_paradise/static_ascii/circle.rb', line 44 def h @h end |
#radius ⇒ Object (readonly)
Returns the value of attribute radius.
40 41 42 |
# File 'lib/ascii_paradise/static_ascii/circle.rb', line 40 def radius @radius end |
#w ⇒ Object (readonly)
#
w, h are width and height of the canvas
#
44 45 46 |
# File 'lib/ascii_paradise/static_ascii/circle.rb', line 44 def w @w end |
Instance Method Details
#canvas? ⇒ Boolean Also known as: canvas
#
canvas?
#
218 219 220 |
# File 'lib/ascii_paradise/static_ascii/circle.rb', line 218 def canvas? @canvas end |
#draw_ellipse(a, b) ⇒ Object
#
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.
#
128 129 130 131 132 133 |
# 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(a, b, a_square, b_square) ⇒ Object
#
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.
#
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# 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(a, b, a_square, b_square) ⇒ Object
#
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.
#
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# 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 ⇒ Object Also known as: display
#
output
#
209 210 211 |
# File 'lib/ascii_paradise/static_ascii/circle.rb', line 209 def output print to_s end |
#plot_four_points(x, y) ⇒ Object
#
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.
#
106 107 108 109 110 111 |
# 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 |
#point(x, y) ⇒ Object
#
point
Draw the given character on canvas to the given coordinates.
#
95 96 97 |
# File 'lib/ascii_paradise/static_ascii/circle.rb', line 95 def point(x, y) @canvas[y * @w + x] = @char end |
#to_s ⇒ Object
#
to_s
Return the circle-data on as a String.
#
198 199 200 201 202 203 204 |
# File 'lib/ascii_paradise/static_ascii/circle.rb', line 198 def to_s result = ''.dup (0..@h - 1).each { |line| result << @canvas[line * @w..line * @w + @w - 1].join << "\n" } result end |