分離面判定法による回転した矩形の衝突判定

Cで実装しようと思ったが難しいのでとりあえずRubyで作ってみた。
これを作るためにDXRubyFrameworkにMatrixとVectorを追加した。
こういうことをするなら無いとやってられない。
あとはこれをCで書いて組み込むだけだが、正直なところ大変だ。
時間かかりそうだからこのロジックを作る前にDXRubyFramework0.0.3をリリースしておきたいと思う。
以下、DXRubyFramework0.0.3(未公開)用。
(追記)
分離軸判定だった。

require 'dxruby'
require 'dxrubyfw'

# 分離面判定法による回転した矩形の衝突判定
def check(obj1, obj2)
  2.times do
    # obj2の判定範囲を自身の画像回転にあわせて回転する
    col2 = obj2.collision
    mat = Matrix.create_translation(-obj2.image.width / 2.0, -obj2.image.height / 2.0) *
          Matrix.create_rotation(obj2.image_angle) *
          Matrix.create_translation(obj2.image.width / 2.0, obj2.image.height / 2.0)
    p1 = Vector.new(col2[0], col2[1], 1) * mat # 左上
    p2 = Vector.new(col2[2], col2[1], 1) * mat # 右上
    p3 = Vector.new(col2[2], col2[3], 1) * mat # 右下
    p4 = Vector.new(col2[0], col2[3], 1) * mat # 左下

    # obj1の回転原点
    center_x = obj1.image.width / 2.0
    center_y = obj1.image.height / 2.0

    # obj1の回転原点をベースにobj2の4点を回転する行列
    mat = Matrix.create_translation(obj2.x - obj1.x - center_x, obj2.y - obj1.y - center_y) *
          Matrix.create_rotation(-obj1.image_angle) *
          Matrix.create_translation(center_x, center_y)

    # obj2の回転&矩形境界ボリューム作成
    p1 *= mat
    x1 = x2 = p1.x
    y1 = y2 = p1.y
    [p2, p3, p4].each do |point|
     point *= mat
     x1 = point.x if x1 > point.x
     x2 = point.x if x2 < point.x
     y1 = point.y if y1 > point.y
     y2 = point.y if y2 < point.y
    end

    # 重なっていなければfalseで終了
    col1 = obj1.collision
    return false unless (x1 < col1[2] and y1 < col1[3] and x2 > col1[0] and y2 > col1[1])

    # 入れ替えてもう1回
    obj1, obj2 = obj2, obj1
  end

  return true
end

s1 = Sprite.new
s1.image = Image.new(100,100,[255,255,255])
s1.x = 100
s1.y = 100
s1.collision = [0, 0, 99, 99]
s1.image_angle = 45

s2 = Sprite.new
s2.image = Image.new(100,100,[255,255,255])
s2.x = 100
s2.y = 100
s2.collision = [0, 0, 99, 99]
s2.image_angle = 0

font = Font.new(32)
Window.loop do 
  s2.x, s2.y = Input.mousePosX, Input.mousePosY
  s1.image_angle += 1
  s2.image_angle -= 1
  Window.drawSprite(s1)
  Window.drawSprite(s2)
  Window.drawFont(0, 0, "hit", font) if check(s1, s2)
end