KENTEM TechBlog

建設業のDXを実現するKENTEMの技術ブログです。

【Unity】多角形の内外判定を行う方法 #3 (平面を用いる)

前回の記事では指定された点が多角形の内部に存在するか否かを、ベクトルの成す角度を用いて判定しました。

本記事では平面を用いて判定する仕組みについて紹介します。

本記事に関して

多角形の内外判定を行う方法のシリーズの3本目です。

UIや必要な事前準備は同じであるため、最初の記事からご覧いただけると理解しやすいと考えております。

この記事では1回目の記事でも用いたIsPolygonInsideメソッドで多角形の内外判定を行っている箇所のみを紹介します。

シリーズ目次

  1. 【Unity】多角形の内外判定を行う方法 #1 (外積を用いる) tech.kentem.jp
  2. 【Unity】多角形の内外判定を行う方法 #2 (角度を用いる) tech.kentem.jp
  3. 【Unity】多角形の内外判定を行う方法 #3 (平面を用いる) ←本記事 tech.kentem.jp
  4. 【Unity】多角形の内外判定を行う方法 #4 (Ray Casting Algorithmを用いる) tech.kentem.jp

平面の式を用いた方法

本記事では多角形の内外判定を行うために、UnityのPlaneクラスにある面の裏表を取得する機能を用います。

本記事では示しませんが、同様の処理を計算によって実装したい場合は参考URLの平面の式を用いて判定することもできます。

仕組み

今回の方法では、下記の図のような多角形の内部を覆う平面を作成し、その面の内側に存在していれば多角形の内部にあると判定しています。

その判定を行う手順を説明します。

法線の向きを計算

平面を定義するのに必要な法線の向きを求めます。

法線の向きとは、下記の図で黄色の矢印に相当するような平面に対して垂直に伸びているベクトルのことをいいます。

ここでは青色で塗られた平面の法線を求めてみます。

そのために、平面に接している多角形のベクトル(赤色)と、カメラの視点方向(黒色)の外積を計算します。

そうすると、法線ベクトル(黄色)が得られます。

今回定義した方法では、法線のベクトルは多角形の内側を向くという性質を持っていることがわかります。

他の面に対しても同様の性質があります。

平面の定義

法線ベクトルの情報と平面上の点の情報をUnityのPlaneクラスのコンストラクターに代入し、平面を定義します。

docs.unity3d.com

法線ベクトルと同じ方向かの判定

Plane.GetSide()を用い、面のどちら側にあるかを判定します。

このメソッドは、引数に代入されたVector3の座標が、面の法線と同じ方向に存在していればtrueを返します。

法線の計算でも解説したように、すべての面が法線と同じ方向であれば多角形の内部と判定できるため、そのように実装します。

ソースコード

private bool IsPolygonInside(Vector3 mousePosition)
{
    var count = _polygon.Vertices.Count;

    for (int i = 0; i < count; i++)
    {
        var currentIndex = i;
        var nextIndex = (i + 1) % count;
        // 多角形の辺を示すベクトル(写真の赤色のベクトル)
        var sideVector = _polygon.Vertices[nextIndex] - _polygon.Vertices[currentIndex];
        // 平面の法線ベクトル(写真の黄色のベクトル)
        var planeNormal = Vector3.Cross(_camera.transform.forward, sideVector).normalized;

        // 平面を作成
        var plane = new Plane(planeNormal, _polygon.Vertices[currentIndex]);
        // 平面の法線ベクトルと異なる場合(GetSide()の戻り値がfalseとなる場合)、多角形の外側と判定とする必要があるためfalseを返す
        if (!plane.GetSide(mousePosition)) return false;
    }
    return true;
}

参考URL

manabitimes.jp

おわりに

KENTEMでは、様々な拠点でエンジニアを大募集しています! 建設×ITにご興味頂いた方は、是非下記のリンクからご応募ください。 recruit.kentem.jp career.kentem.jp