processing
Ruby-Processing

点が三角形の内側にあるか

More than 1 year has passed since last update.

キャンバスに回転する三角形を表示します。
マウスカーソルがその三角形の内側にあるときのみ、その三角形を塗りつぶすサンプルです。

環境

  • OS X 10.10.4
  • Ruby-Processing version 2.6.13

サンプルコード

point-in-triangle.rb
# 2 次元ベクトル
class Vec2
  attr_reader :x, :y

  def initialize(x, y)
    @x = x
    @y = y
  end

  def subtract(v)
    Vec2.new(@x - v.x, @y - v.y)
  end

  def -(v)
    subtract(v)
  end

  def rotate!(deg)
    rad = deg.radians
    x = @x
    y = @y
    @x = x * cos(rad) - y * sin(rad)
    @y = x * sin(rad) + y * cos(rad)
  end
end

def setup
  size 400, 400

  $a = Vec2.new 100, 0
  $a.rotate! 0
  $b = Vec2.new 100, 0
  $b.rotate! 120
  $c = Vec2.new 100, 0
  $c.rotate! 240
end

def draw
  background 255

  # 三角形の 3 点を回転
  $a.rotate! 1
  $b.rotate! 1
  $c.rotate! 1

  pushMatrix()
  translate(width/2, height/2)

  a, b, c = $a, $b, $c
  ellipse(a.x, a.y, 10, 10)
  ellipse(b.x, b.y, 10, 10)
  ellipse(c.x, c.y, 10, 10)

  p = Vec2.new(mouseX - width/2, mouseY - height/2)
  ab = b - a
  bp = p - b

  bc = c - b
  cp = p - c

  ca = a - c
  ap = p - a

  c1 = ab.x * bp.y - ab.y * bp.x
  c2 = bc.x * cp.y - bc.y * cp.x
  c3 = ca.x * ap.y - ca.y * ap.x

  if (c1 > 0 && c2 > 0 && c3 > 0) || (c1 < 0 && c2 < 0 && c3 < 0)
    # 3 点の内部にある
    fill(120, 120, 120)
  else
    noFill
  end
  triangle(a.x, a.y, b.x, b.y, c.x, c.y)

  popMatrix()
end

コマンドラインから以下のように実行します。

$ rp5 --nojruby watch point-in-triangle.rb

疑問:ソースコードにあるコメントを書いたら、Java の例外が生成される => 最新の Java SE を入れたら解決

ソースコードに「# あ」とコメントを書くと、Java の例外が生成されます。「# ああ」というコメントだと、例外は生成されません。特定のコメント文字列だと例外が生成されるのか、よく分かっていません。ソースコードは UTF-8 で書いています。

例外が生成されるコード(UTF-8)
def setup
  # あ
end

RubyRegexp.java で例外が生成されています。

生成される例外
Exception occured while running sketch a.rb...
Backtrace:
    org/jruby/RubyRegexp.java:1680:in `match'
    org/jruby/RubyString.java:1747:in `match'
    /usr/local/lib/ruby/gems/2.2.0/gems/ruby-processing-2.6.13/lib/ruby-processing/runners/base.rb:31:in `load_and_run_sketch'
    /usr/local/lib/ruby/gems/2.2.0/gems/ruby-processing-2.6.13/lib/ruby-processing/runners/watch.rb:47:in `start_runner'
    /usr/local/lib/ruby/gems/2.2.0/gems/ruby-processing-2.6.13/lib/ruby-processing/runners/watch.rb:35:in `report_errors'
    /usr/local/lib/ruby/gems/2.2.0/gems/ruby-processing-2.6.13/lib/ruby-processing/runners/watch.rb:46:in `start_runner'
reloading sketch...

(追記:解決しました) 最新の Java SE (JDK 8u51)をインストールしたら上記のエラーは再現しなくなりました。

参考