せん断の行列

今回は
http://www.youtube.com/watch?v=83P8xRIG3eI
のイメージです。
これを作りたかったから、
無理やりなので位置関係が判りづらいです。
<追記>
http://blog.livedoor.jp/gaziya/archives/52157035.html
に書き直しました。

#!usr/bin/env ruby

require 'sdl'
require 'cairo'

class BackGround
def initialize(w, h)
@w, @h = w, h
end

def update(c)
c.set_source_color(Cairo::Color::BLACK)
c.rectangle(0, 0, @w, @h)
c.fill
end
end

class Man
def initialize(x, y , deg, rgb)
@gx, @gy = x, y
@r,@g,@b = rgb
@deg = deg
@w, @h = 50, 120
@x, @y = -@w / 2, -@h
end

def update(c)
@deg += 3
@deg = 0 if @deg > 359
rd = @deg * Math::PI / 180
c.matrix = Cairo::Matrix.new(1,0,0.25 * Math::cos(rd),0.75+ 0.25 * Math::sin(rd), 0, 0) * Cairo::Matrix.translate(@gx, @gy)
c.set_source_rgb(@r,@g,@b)
c.rectangle(@x, @y, @w, @h)
c.circle(0, -@h - 25, 25)
c.fill
end
end

class Phase
def initialize(screen)
@screen = screen
@w, @h = @screen.w, @screen.h
@image = Cairo::ImageSurface.new(@w, @h)
@bg = BackGround.new(@w, @h)
@men = []
(0 .. 179).step(30) do |deg|
r,g,b = rand / 2 + 0.5, rand / 2 + 0.5, rand / 2 + 0.5
@men << Man.new(@w / 2, @h - 12, deg, [r,g,b])
end
@deg = 0
end

def update
context = Cairo::Context.new(@image)
@bg.update(context)
@men.each do |obj|
obj.update(context)
end
surface = SDL::Surface.new_from(@image.data, @image.width, @image.height, 32, @image.stride, 0, 0, 0, 0)
@screen.put(surface, 0, 0)
end

def run
loop do
while e=SDL::Event.poll
exit if e.kind_of?(SDL::Event::Quit) || (e.kind_of?(SDL::Event::KeyDown) && e.sym == SDL::Key::ESCAPE)
end
self.update
@screen.flip
SDL.delay(20)
end
end
end

SDL.init(SDL::INIT_VIDEO)
@screen = SDL::Screen.open(250, 250, SDL::Screen.info.bpp, SDL::SWSURFACE)
Phase.new(@screen).run
[PR]
by gaziya | 2011-05-19 21:08