bezier.rb

30分プログラム、その39。ベジエ曲線

ごぞんじの通りベジエ曲線は、4つの制御点をもとに曲線を書くための手法。各制御点をそれぞれ、(x0,y0),(x1,y1),(x2,y2),(x3,y3)とすると

x = (1.0-t)^3x_0+3t(1.0-t)^2x_1+3t^2(1.0-t)x_2+t^3x_3
y = (1.0-t)^3y_0+3t(1.0-t)^2y_1+3t^2(1.0-t)y_2+t^3y_3

という式のtに0.0,0.1,...,1.0という値を代入して、得られる点を順にプロットしていけば、ベジエ曲線が得られる。

たまたま、るびまSDLについて解説していたので、SDLでやってみる。

require "sdl"
 
def bezier(t,p0,p1,p2,p3)
  (1.0-t)*p0 + 3*t*(1.0-t)**2*p1 + 3*t*t*(1.0-t)*p2 + t**3*p3
end
 
def bezier_points(counts,*points)
  (0..counts).map{|i|
    bezier(i.to_f/counts,*points)
  }
end
 
def draw(surface)
  xs= bezier_points(200,0,140,160,200)
  ys= bezier_points(200,0,40,60,200)
  red = surface.map_rgb 255,0,0
 
  surface.lock
  bx = by = 0
  xs.zip(ys){|x,y|
    surface[x,y] = red
  }
  surface.unlock
end
 
SDL.init(SDL::INIT_EVERYTHING)
screen = SDL.set_video_mode(200,200,16,SDL::SWSURFACE)
draw screen
screen.update_rect 0,0,0,0
loop{
  while event=SDL::Event2.poll do
    case event
    when SDL::Event2::Quit
      exit
    end
  end
}
  • いちおう解説もつけてみた
  • なんか、最近調子悪いなぁ