Skip to content

Instantly share code, notes, and snippets.

@edom18
Created October 15, 2015 15:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save edom18/67f37e3d300f60c417d8 to your computer and use it in GitHub Desktop.
Save edom18/67f37e3d300f60c417d8 to your computer and use it in GitHub Desktop.
[3D] 三角形と線分の交差判定(Raycast) ref: http://qiita.com/edo_m18/items/2bd885b13bd74803a368
0 ≦ u ≦ 1 \\
0 ≦ v ≦ 1 \\
0 ≦ u + v ≦ 1
x_i = \frac{det(A_i)}{det(A)}
det(A_1) =
\begin{vmatrix}
c_1 &b_1 \\
c_2 &b_2
\end{vmatrix}
=
(c_1 \times b_2) - (b_1 \times c_2)
\begin{vmatrix}
a1 \\
a2 \\
a3
\end{vmatrix}
u +
\begin{vmatrix}
b1 \\
b2 \\
b3
\end{vmatrix}
v +
\begin{vmatrix}
c1 \\
c2 \\
c3
\end{vmatrix}
t =
\begin{vmatrix}
d1 \\
d2 \\
d3
\end{vmatrix}
/**
* 三角形の内包判定
*
* @param vecA vectorA
* @param vecB vectorB
* @param vecC vectorC
*/
function det(vecA, vecB, vecC) {
return ((vecA.x * vecB.y * vecC.z)
+ (vecA.y * vecB.z * vecC.x)
+ (vecA.z * vecB.x * vecC.y)
- (vecA.x * vecB.z * vecC.y)
- (vecA.y * vecB.x * vecC.z)
- (vecA.z * vecB.y * vecC.x));
}
/**
* Raycast
*
* @param origin origin vector of ray
* @param ray ray direction
* @param v0 a vertex of a triangle
* @param v1 a vertex of a triangle
* @param v2 a vertex of a triangle
*
* @return result object
*/
function rayIntersectsTriangle(origin, ray, v0, v1, v2) {
// 交差判定結果を表すオブジェクト
var ret = {
result: false,
point: new THREE.Vector3(),
distance: 0
};
// レイの逆方向のベクトルを得る
var invRay = ray.clone().multiplyScalar(-1);
var edge1 = (new THREE.Vector3()).subVectors(v1, v0);
var edge2 = (new THREE.Vector3()).subVectors(v2, v0);
// クラメルの公式の分母
var denominator = det(edge1, edge2, invRay);
// レイが平面と平行でないかチェック
if (denominator <= 0) {
return ret;
}
var d = (new THREE.Vector3()).subVectors(origin, v0);
var u = det(d, edge2, invRay) / denominator;
if ((u >= 0) && (u <= 1)) {
var v = det(edge1, d, invRay) / denominator;
if ((v >= 0) && (u + v <= 1)) {
var t = det(edge1, edge2, d) / denominator;
// 距離がマイナスの場合は交差していない
if (t < 0) {
return ret;
}
var tmp = ray.clone().multiplyScalar(t);
ret.point = (new THREE.Vector3()).addVectors(origin, tmp);
ret.result = true;
ret.distance = t;
}
}
return ret;
}
\begin{vmatrix}
1 &2 \\
3 &4
\end{vmatrix}
=
(1 \times 4) - (2 \times 3) = -2
a_1 x_1 + b_1 x_2 = c_1 \\
a_2 x_1 + b_2 x_2 = c_2
\begin{vmatrix}
a_1 &b_1 \\
a_2 &b_2
\end{vmatrix}
\begin{vmatrix}
x_1 \\
x_2
\end{vmatrix}
=
\begin{vmatrix}
c_1 \\
c_2
\end{vmatrix}
// レイを元に算出します
// origin ... レイの始点
// ray ... レイの方向
// t ... 交点までの距離
P = origin + ray * t
(edge1 * u) + (edge2 * v) - (ray * t) = origin - v0
origin + ray * t = v0 + edge1 * u + edge2 * v
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment