Ruby/SDLで計算幾何(1)GeoBaseを作る
アルゴリズムC第二巻amazon:4764902567のお勉強を、Rubyで始めてみます。
とっかかりのアイデアはid:technohippyさんの過去日記 http://d.hatena.ne.jp/technohippy/20070719#1184868435 から頂きます。ありがとうございます。
ベースのクラスを作成します。ほぼid:technohippyさんのコピーですが、多角形Polygonに関してのみ追加しています。
class GeoBase attr_accessor :screen class Point attr_accessor :x, :y def initialize(x, y); @x, @y = x, y end def to_s; "(#{x}, #{y})" end def inspect; to_s end def ==(p1); x == p1.x and y == p1.y; end end class Line attr_accessor :p1, :p2 def initialize(p1, p2); @p1, @p2 = p1, p2 end def to_s; "[#{p1.to_s}, #{p2.to_s}]" end def inspect; to_s end def ==(l1); p1 == l1.p1 and p2 == l1.p2; end end # 多角形 class Polygon attr_accessor :vertices def initialize(vertices) @vertices = vertices.push vertices[0], vertices[1] end def to_s; "#{vertices}" end def inspect; to_s end def ==(poly1); vertices == poly1.vertices; end end def default_color; [255, 255, 255] end def point(x, y) Point.new x, y end alias p point def line(x1, y1, x2=nil, y2=nil) if x2 x1 = p x1, y1 y1 = p x2, y2 end Line.new x1, y1 end alias l line # 多角形を点の座標、または配列で作成 def polygon(x1, *arg) if arg if arg.size % 2 == 0 raise ArgumentError, 'num of coodinates is odd.' else arg.unshift x1 vertices = [] (0..(arg.size/2)).each do |i| vertices << p(arg[i], arg[i+1]) end end else vertices = x1 end Polygon.new vertices end alias poly polygon def draw_point(p1) @screen.drawCircle p1.x, p1.y, 3, default_color, true end def draw_line(x1, y1=nil, x2=nil, y2=nil) if x2 x1 = l x1, y1, x2, y2 elsif y1 x1 = l x1, y1 end @screen.drawLine x1.p1.x, x1.p1.y, x1.p2.x, x1.p2.y, default_color end # 多角形を描画 def draw_polygon(poly1) poly1.vertices.inject do |s,n| draw l(s, n); n end end def draw(*targets) targets.each do |target| case target when Point draw_point target when Line draw_line target when Polygon draw_polygon target end end end def start raise 'subclass responsibility' end def update @screen.updateRect 0, 0, 0, 0 end def self.wait loop do while event = SDL::Event2.poll case event when SDL::Event2::Quit, SDL::Event2::KeyDown exit end end end end def self.start SDL.init SDL::INIT_VIDEO geo = self.new geo.screen = SDL.setVideoMode 640, 480, 16, SDL::SWSURFACE geo.start geo.update wait end end
次回は、二つの直線が交差するかどうかを判定するメソッドを作成します。
module関数にするか、Lineクラスのmethodにするか、まだ決めていません。