点(マウスカーソル)が、回転する矩形の中にあるかを判定するプログラムを Ruby-Processing で書いてみました。
point-in-rotate-rect.rb
load_library :vecmath
# XY 軸に平行ではない矩形に点が含まれるかを判定するサンプル
# Y 軸上方向を正とする(描画時に符号反転させる)
# a ----- d
# | |
# | |
# b ----- c
def setup
size 400, 400
# 長方形を構成する 4 つのベクトル
@a = Vec2D.new(-100, 50)
@b = Vec2D.new(-100, -50)
@c = Vec2D.new(100, -50)
@d = Vec2D.new(100, 50)
end
def draw
background 255
translate width/2, height/2
# XY 軸
stroke 0xE0, 0xE0, 0xE0
line -width, 0, width, 0
line 0, -height, 0, height
stroke 0
p = Vec2D.new(mouse_x - width/2, -(mouse_y - height/2))
if point_in_rectangle?(p, @a, @b, @c, @d)
fill 100
else
no_fill
end
draw_rectangle @a, @b, @c, @d
# 矩形を回転させる
t = 1.radians * 0.6
@a.rotate! t
@b.rotate! t
@c.rotate! t
@d.rotate! t
end
# 長方形を描く
def draw_rectangle(a, b, c, d)
begin_shape
vertex a.x, -a.y
vertex b.x, -b.y
vertex c.x, -c.y
vertex d.x, -d.y
end_shape CLOSE
end
# ベクトル a とベクトル b のなす角度を求める
# 0 ~ 2pi の範囲で返す
def calc_angle(a, b)
angle = Math.atan2(b.x * a.y - a.x * b.y, a.x * b.x + a.y * b.y)
angle += 2 * PI if angle < 0
angle
end
# 点 p が長方形(点 a, b, c, d)の中にあるか
def point_in_rectangle?(p, a, b, c, d)
# 角 abr と、角 cdr がいずれも 90 度以下であれば、点は長方形の内部にある
ba = a - b # ベクトル ba
bp = p - b
dc = c - d
dp = p - d
angle1 = calc_angle(ba, bp)
angle2 = calc_angle(dc, dp)
angle1.degrees <= 90 && angle2.degrees <= 90
end
コマンドラインから次のように実行します。
$ rp5 run point-in-rotate-rect.rb