分離面判定法による回転した矩形の衝突判定
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