Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Three.js: How to determine if a point is inside a box?

2025年09月23日に「Dev.to」が公開したITニュース「Three.js: How to determine if a point is inside a box?」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

Three.jsで点が箱の中にあるか判定するには、まず点のワールド座標を箱のローカル座標に変換する。これは箱の逆変換行列を点に適用して行う。変換後の点が箱の最小・最大値の範囲内にあるかを各軸で確認すれば、点が含まれるか判断できる。

ITニュース解説

Three.jsは、ウェブブラウザ上で3Dグラフィックスを簡単に扱うためのJavaScriptライブラリであり、ゲーム開発やバーチャルリアリティアプリケーションなど、様々な分野で利用されている。このThree.jsを使って3D空間を構築する際、ある特定の「点」が、空間内にある「箱」の内部に含まれているかどうかをプログラムで判定する場面が頻繁に発生する。これは、例えばゲームにおけるオブジェクト同士の衝突判定や、ユーザーがクリックした位置が特定の3Dモデル内であるかの確認など、3Dアプリケーションの挙動を制御する上で非常に基本的ながら重要な機能である。

この判定を行うには、まず3D空間における「座標系」の概念を理解する必要がある。3D空間には、すべてのオブジェクトが共通の基準に基づいて位置を示す「ワールド座標系」が存在する。これは、3D空間全体の原点(0,0,0)を基準とした座標である。一方、個々のオブジェクトはそれぞれ自分自身の「ローカル座標系」を持っている。ローカル座標系とは、そのオブジェクト自身の原点を基準とし、オブジェクト自身の向きに従って定義される座標系である。例えば、箱が3D空間内に存在する場合、その箱自体の形状やサイズは箱のローカル座標系で定義されている。

問題は、判定したい点(point)の位置が通常ワールド座標系で与えられるのに対し、箱の内部を定義する寸法(サイズ)は箱のローカル座標系で定義されている点にある。異なる座標系で定義された位置とサイズを直接比較しても、正確な判定はできない。そこで、点の位置を箱のローカル座標系へと「変換」する作業が必要となる。これは、点がいったん箱の視点から見たとき、箱のどこに位置しているのかという情報に変換することを意味する。

この変換には、「逆変換行列」というものが使われる。3Dグラフィックスにおいて「行列(Matrix)」は、オブジェクトの位置、回転、拡大縮小といった様々な変換を数学的に表現し、統一的に処理するための強力なツールである。通常、オブジェクトのローカル座標からワールド座標へ変換するために「変換行列」が使われるが、「逆変換行列」はその逆の働きをする。つまり、ワールド座標から特定のオブジェクトのローカル座標へ変換するために用いられる。

具体的な処理の流れをThree.jsのコードに沿って見ていくと、まず対象となる箱の現在のワールド座標における変換行列を取得し、それを反転させた「逆変換行列」を作成する。Three.jsでは、box.matrixWorld()というメソッドで箱のワールド変換行列を取得できる。この行列は、箱のローカル座標をワールド座標に変換するための情報を持っている。次に、invert()メソッドを呼び出すことで、このワールド変換行列の逆行列が計算され、inverseMatrixという変数に格納される。このinverseMatrixが、ワールド座標を箱のローカル座標へと変換するための鍵となる。

そして、判定したい点(point)のワールド座標に、このinverseMatrixを適用(乗算)する。point.clone().applyMatrix4(inverseMatrix)というコードがその処理を実行している。ここでclone()を使用しているのは、元のpointの位置情報を変更しないように、点の複製に対して変換を適用するためである。この処理の結果、localPointという新しい点が得られる。このlocalPointは、箱のローカル座標系における点の位置を示しており、これにより点と箱の寸法を直接比較できる状態となる。

点が箱のローカル座標に変換されたら、あとはそのlocalPointが箱の「境界ボックス(Bounding Box)」の中に収まっているかどうかをチェックするだけで良い。境界ボックスとは、3Dモデル全体を最小限のサイズでぴったりと覆う直方体のことで、そのモデルのX、Y、Z軸それぞれの方向における最小値(min)と最大値(max)の座標で定義される。この境界ボックスは、衝突判定や描画の効率化など、様々な場面で利用される基本的な概念である。

箱の場合、その幾何学的な形状(box.geometry)から境界ボックスを直接計算できる。Three.jsのコードでは、box.geometryを参照し、そのcomputeBoundingBox()というメソッドを呼び出すことで、幾何学形状を囲む境界ボックスが計算され、bboxという変数に格納される。

最終的な判定は、このbboxが持つ最小値と最大値の範囲内に、localPointのX、Y、Zそれぞれの座標値が収まっているかどうかを確認することで行われる。具体的には、localPointのX座標がbboxのX軸方向の最小値以上かつ最大値以下であり、同様にY座標とZ座標もそれぞれの軸方向の範囲内にあれば、その点は箱の内部にあると判断される。Three.jsにはbbox.containsPoint(localPoint)という便利なメソッドが用意されており、この一連の範囲チェックを自動で行ってくれる。このメソッドがtrueを返せば点は箱の内部にあり、falseならば外部にあるという結果になる。

このように、ある点が3D空間内の箱の内部にあるかどうかを判定するには、まず点のワールド座標を箱のローカル座標へと変換し、その変換された点が箱の境界ボックス内に収まっているかをチェックするという、段階的なアプローチが取られる。このプロセスは、3Dグラフィックスプログラミングにおける座標変換と衝突判定の基礎であり、Three.jsのようなライブラリを用いることで、これらの複雑な数学的処理を比較的簡単なAPIコールで実現できるようになっている。システムエンジニアを目指す上で、このような3D空間におけるオブジェクトの位置関係を理解し、適切に処理する能力は、特に3Dゲーム開発やAR/VRアプリケーション開発など、多岐にわたる分野で非常に役立つ基本的な知識となる。

関連コンテンツ

関連ITニュース