From 8530c7d2fc35bf7ed1edb112c8672a7b0e665e2c Mon Sep 17 00:00:00 2001 From: Simen Svale Skogsrud Date: Tue, 27 Jan 2009 10:56:47 +0100 Subject: [PATCH] added testbed for the arc interpolator i will be using --- arc_algorithm/arc.rb | 184 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 arc_algorithm/arc.rb diff --git a/arc_algorithm/arc.rb b/arc_algorithm/arc.rb new file mode 100644 index 0000000..062707d --- /dev/null +++ b/arc_algorithm/arc.rb @@ -0,0 +1,184 @@ +require "pp" +# A tiny ruby script to design and test the implementation of the arc-support + +class Numeric + # -1 if the number < 0, 1 if number >= 0 + def sign + return 0 if self == 0 + (self < 0) ? -1 : 1 + end +end + +class CircleTest + include Math + + def init + @pixels = [] + @tool_position = [14,14] + 30.times { @pixels << '.'*30 } + end + + def plot_pixel(x,y, c) + return if x<0 || y<0 || x>29 || y > 29 + @pixels[y] = @pixels[y][0..x][0..-2]+c+@pixels[y][(x+1)..-1] + end + + def show + @pixels.each do |line| + puts line.gsub('.','. ').gsub('0','0 ').gsub('1','1 ').gsub('2','2 ').gsub('X','X ').gsub('o','o ') + end + end + + # dP[x+1,y]: 1 + 2 x + # dP[x-1,y]: 1 - 2 x + # dP[x, y+1]: 1 + 2 y + # dP[x, y-1]: 1 - 2 y + + # dP[x+1, y+1]: 2 (1 + x + y) + # dP[x+1, y-1]: 2 (1 + x - y) + # dP[x-1, y-1]: 2 (1 - x - y) + # dP[x-1, y+1]: 2 (1 - x + y) + + # dP[x+a, y+b]: |dx| - 2*dx*x + |dy| + 2*dy*y + + # Algorithm from the wikipedia aricle on the Midpoint circle algorithm. + def raster_circle(radius) + f = 1-radius + ddF_x = 1 + ddF_y = -2*radius + x = 0 + y = radius + while x<=y + if f>0 + y -= 1 + ddF_y += 2 + f += ddF_y + end + x += 1 + ddF_x += 2 + f += ddF_x + plot_pixel(x+14,-y+14,'X') + end + x += 1 + ddF_x += 2 + f += ddF_x + while y>0 + if f<0 + x += 1 + ddF_x += 2 + f += ddF_x + end + y -= 1 + ddF_y += 2 + f += ddF_y + plot_pixel(x+14,-y+14,'o') + end + + end + + # An "ideal" arc. Computationally expensive, but always pure + def pure_arc(theta, segment, angular_direction, radius) + var = [(sin(theta)*(radius)), (cos(theta)*(radius))] + error_sum = 0.0 + error_count = 0.0 + max_error = 0.0 + (PI*2*radius).ceil.times do + if var[0].abs 0 + plot_pixel(x+14, -y+14, "012"[i%3].chr) + else + plot_pixel(x+14, -y+14, "X") + end + + dx = (y==0) ? angular_direction : y.sign*angular_direction + dy = (x==0) ? angular_direction : -x.sign*angular_direction + + if x.abs=tx.abs) && (y.abs>=ty.abs) + i += 1 + end + puts "Target #{[tx,ty].inspect}" + plot_pixel(tx+14, -ty+14, "o") + + pp [x,y] + + puts "Diameter: #{max_x-min_x}" + end + + +end + +test = CircleTest.new +test.init + +test.arc_clean(0, -Math::PI, 5) + +test.show