$リアルタイムCGの基礎+Android+レイトレ


・2つの直線の方程式を作る。

Q = V1*t1 + P1
Q = V2*t2 + P2

Q:交点
P1:線分1の始点
V1:線分1のベクトル
t1:線分1のPからQまでの距離
P2:線分2の始点
V2:線分2のベクトル
t2:線分2のPからQまでの距離


※t1もしくはt2を求めれば、交点Qを求められる。

・繋げてt1,t2の両方が存在する一つの式にする。

V1*t1 + P1 = V2*t2 + P2

V1*t1 - V2*t2 + P1 - P2 = 0

・ベクトルを展開し連立方程式にする。

V1.x*t1 - V2.x*t2 + P1.x - P2.x = 0
V1.y*t1 - V2.y*t2 + P1.y - P2.y = 0

・変数表記の簡略化

x:t1
y:t2
a:V1.x
b:V2.x
c:P1.x
d:P2.x
e:V1.y
f:V2.y
g:P1.y
h:P2.y

ax - by + c - d = 0 ..(1)
ex - fy + g - h = 0 ..(2)

A)加減法を使って連立方程式を解く。

・f,bをそれぞれの式にかける

fax - fby + fc - fd = 0
bex - fby + bg - bh = 0

fax - fby + fc - fd = bex - fby + bg - bh

fax + fc - fd = bex + bg - bh

fax - fd = bex + bg - bh - fc

fax = bex + bg - bh - fc + fd

fax - bex = bg - bh - fc + fd

(fa - be)x = bg - bh - fc + fd

x = ( bg - bh - fc + fd ) / (fa - be)

x = ( b(g - h) - f(c - d) ) / (fa - be)

・変数表記を戻す

t1 = ( V2.x*(P1.y - P2.y) - V2.y*(P1.x - P2.x) ) / (V2.y*V1.x - V2.x*V1.y)



B)代入法を使って連立方程式を解く。

・(1)式をyについての式に変形

ax - by + c - d = 0 ..(1)

- by + c - d = -ax

- by - d = -ax - c

- by = -ax - c + d

y = (-ax - c + d) / (-b)

y = (ax + c - d) / b

y = ax/b + c/b - d/b

・(2)式に代入

ex - fy + g - h = 0 ..(2)

ex - f(ax/b + c/b - d/b) + g - h = 0

ex - fax/b - fc/b + fd/b + g - h = 0

ex - fax/b + fd/b + g - h = fc/b

ex - fax/b + g - h = fc/b - fd/b

ex - fax/b - h = fc/b - fd/b - g

ex - fax/b = fc/b - fd/b - g + h

ex - fax/b = f(c - d)/b - g + h

(e - fa/b)x = f(c - d)/b - g + h

x =(f(c - d)/b - g + h) / (e - fa/b)


・変数表記を戻す

t1 = ( V2.y*(P1.x - P2.x)/V2.x - P1.y + P2.y ) / (V1.y -V2.y*V1.x/V2.x)


■まとめ

加減法で求めた式
t1 = ( V2.x*(P1.y - P2.y) - V2.y*(P1.x - P2.x) ) / (V2.y*V1.x - V2.x*V1.y)

代入法で求めた式
t1 = ( V2.y*(P1.x - P2.x)/V2.x - P1.y + P2.y ) / (V1.y -V2.y*V1.x/V2.x)

どちらでも同じt1値が求まる。

t1<0 の時は、P点より後ろ反対方向に交点がある。
t1>1 の時は、P+V点より先に交点がある。

交わらない時は、式の後半の『/』以降で0が発生する。

代入法版は、線分2のxが0でも0除算が発生してしまうので、

加減法版の式の方が例外が少なく扱いやすい。