人気ブログランキング | 話題のタグを見る

アフィン変換って?

Cairo::Matrixが、ずっと気になってた。
アフィン変換をするものらしい。
平面を斜めから見た状態に図形を変形するみたい。
行列を使うみたい。
わかりやすいプログラムを書くのに配列や入れ子構造を多用してきたけど、
行列は、よくわからない。
高校の時に習ったけど、一生使う機会がないと思ってた。
だけど、ここにきて使い道を見つけた。
色々調べたら、弾幕にも使えるみたい。
とりあえず、Cairo::Matrixのアフィン変換を試してみた。

#!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::TEAL)
c.rectangle(0, 0, @w, @h)
c.fill
end
end

class Image
def initialize
url = "http://mechanics.civil.tohoku.ac.jp/soft/i-gif/magick1.gif"
@x,@y = 100,100
IO.popen("wget -q -O - #{url} | convert - png:-") do |io|
@surface = Cairo::ImageSurface.from_png(io)
@d = 0
end
end

def update(c)
@d += 15
rd= @d * Math::PI / 180
c.transform(Cairo::Matrix.new(1, 0.5 * Math.sin(rd), -0.5 * Math.cos(rd), 1, 0, 0))
c.set_source(@surface,@x,@y)
c.paint
end
end


class Phase
def initialize(w,h)
SDL.init(SDL::INIT_VIDEO)
@w,@h = w,h
@screen = SDL::Screen.open(@w, @h, SDL::Screen.info.bpp, SDL::SWSURFACE)
@surface = Cairo::ImageSurface.new(@w,@h)
@item = []
@item << BackGround.new(@w,@h)
@item << Image.new
end

def update
@context = Cairo::Context.new(@surface)
@item.each {|x| x.update(@context)}
SDL::Surface.new_from(@surface.data, @w, @h, 32, @surface.stride, 0, 0, 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
@screen.put(self.update, 0, 0)
@screen.flip
SDL.delay(100)
end
end
end

Phase.new(350, 350).run
by gaziya | 2011-05-04 12:09