LoginSignup
1
1

More than 5 years have passed since last update.

Ruby-Processing 回転する矩形の中に点があるか

Posted at

点(マウスカーソル)が、回転する矩形の中にあるかを判定するプログラムを Ruby-Processing で書いてみました。

point-in-rotate-rect.gif

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

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1