平面と直線の交点

点(x1, y1, z1)を通り法線(Nx, Ny, Nz)を持つ平面の方程式

Nx(x - x1) + Ny(y - y1) + Nz(z - z1) = 0

となります。

今回は、この平面の方程式に加えて直線の方程式を作って「平面と直線の交点と交点までの線分の長さ」を求めてみましょう。レイトレーシングや衝突判定など3D空間を扱う時には、必要になる場面も多い処理ですね。

直線は、実際の3D処理で扱いやすいよう1点と方向ベクトルで表すことにします。「平面上の1点と法線ベクトルで表される平面」と「直線上の1点と方向ベクトルで表される直線」の交点、また直線の始点から交点までの距離(線分の長さ)を求めてみるわけです。

点と方向ベクトルから求める直線の方程式

方向ベクトルは「方向性を成分ごとに表示したもの」ですので、ある1点(x2, y2, z2)を通る方向ベクトル(Vx, Vy, Vz)に沿った軌跡は、任意の実数(媒介変数)tで以下のようにあらわすことができます。

x = x2 + t * Vx
y = y2 + t * Vy
z = z2 + t * Vz

つまり、これが「ある点(x2, y2, z2)を通り方向ベクトル(Vx, Vy, Vz)を持つ直線の方程式」になるわけです。

(Vx, Vy, Vz)が単位ベクトルなら、tの値が直線上の(x2, y2, z2)からの距離になります。

平面と直線の交点(点と平面の距離)の計算法

「点を通る直線の方程式」ができたので、この方程式と前回の平面の方程式を連立させて「平面と直線の連立方程式」にしてみましょう。連立方程式の解から、求める交点の情報が得られるはずです。

点(x1, y1, z1)を通り法線ベクトル(Nx, Ny, Nz)を持つ面は、以下の方程式で表すことができました。

Nx(x - x1) + Ny(y - y1) + Nz(z - z1) = 0

この式に今回のx/y/zを代入すると

Nx(x2 + t * Vx - x1) + Ny(y2 + t * Vy - y1) + Nz(z2 + t * Vz - z1) = 0

直線(ある点と方向ベクトル)と平面の関係では、「直線の始点から交点までの線分の長さ」を求めたいことも多いでしょうから、線分の長さに対応するtについて整理してみましょう。

t = -(Nx(x2 - x1) + Ny(y2 - y1) + Nz(z2 - z1)) / (Nx * Vx + Ny * Vy + Nz * Vz)

このtの値が長さとして意味を持つ値、つまり正の実数になれば平面と直線は交点を持ち点(x2, y2, z2)と平面上の交点の(方向ベクトルに沿った)距離はtである、と言えるわけです。

直線と平面の交点を求めるプログラム

直線と平面の交点、線分の長さを求める式ができたので、プログラムにまとめてみましょう。といっても、計算プログラム自体は式をそのまま書くだけですね。

まずtの値を求めるJavaScript関数は、以下のようになります。

function getPlaneDistance(x1, y1, z1, nx, ny, nz, x2, y2, z2, vx, vy, vz) {
return -(nx * (x2 - x1) + ny * (y2 - y1) + nz * (z2 - z1)) / (nx * vx + ny * vy + nz * vz);
}

この艇の値は直線の方程式に代入すれば、交点が求まるわけですね。

直線の出発点方向ベクトル

x
y
z

x
y
z

平面上の点法線ベクトル

x
y
z

x
y
z

線分の長さ:
交点:

直線の出発点と方向ベクトル、平面上の点と法線ベクトルから交点を計算するプログラムです。

値を入れたら、「計算」ボタンをクリックしてください。