Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Discussion Point in polygon with dot product?

Discussion in 'Scripting' started by Vaizerition, Aug 28, 2022.

  1. Vaizerition

    Vaizerition

    Joined:
    Apr 25, 2020
    Posts:
    57
    I made some code to check when the player camera is in front of a quad and the camera point is projected on a plane that faces the same direction as the quad.

    The vertices go around the quad clockwise order.

    I used dot product to check if the camera point is inside the quad.

    I wanted to use a cross product with it but, I had a problem with vector 3 and int in the if statement.

    The code seems to work.

    How do I use a cross product with the if statement in the loop?

    ???

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PointInPolygon : MonoBehaviour
    6. {
    7.     private Mesh mesh;
    8.  
    9.     public bool PointInside;
    10.  
    11.     private Vector3 Point;
    12.  
    13.     private Vector3 CamPoint;
    14.  
    15.     public Vector3[] vertices;
    16.  
    17.     public List<Plane> Planes = new List<Plane>();
    18.  
    19.     public List<Vector3> tpvertices = new List<Vector3>();
    20.  
    21.     // Start is called before the first frame update
    22.     void Start()
    23.     {
    24.         mesh = GetComponent<MeshFilter>().sharedMesh;
    25.  
    26.         int[] triangles = mesh.triangles;
    27.         vertices = mesh.vertices;
    28.  
    29.         for (int i = 0; i < triangles.Length; i += 3)
    30.         {
    31.             Vector3 p1 = vertices[triangles[i + 0]];
    32.             Vector3 p2 = vertices[triangles[i + 1]];
    33.             Vector3 p3 = vertices[triangles[i + 2]];
    34.  
    35.             Vector3 tp1 = transform.TransformPoint(p1);
    36.             Vector3 tp2 = transform.TransformPoint(p2);
    37.             Vector3 tp3 = transform.TransformPoint(p3);
    38.  
    39.             Planes.Add(new Plane(tp1, tp2, tp3));
    40.         }
    41.  
    42.         for (int i = 0; i < vertices.Length; i++)
    43.         {
    44.             Vector3 p = vertices[i];
    45.             Vector3 tp = transform.TransformPoint(p);
    46.             tpvertices.Add(tp);
    47.         }
    48.     }
    49.  
    50.     // Update is called once per frame
    51.     void Update()
    52.     {
    53.         CamPoint = Camera.main.transform.position;
    54.  
    55.         Point = Vector3.ProjectOnPlane(CamPoint, Planes[0].normal);
    56.  
    57.         for (int i = 0; i < tpvertices.Count; i++)
    58.         {
    59.             int j = i + 1;
    60.  
    61.             if (j == tpvertices.Count)
    62.             {
    63.                 j = 0;
    64.             }
    65.  
    66.             Vector3 tp1 = tpvertices[i];
    67.             Vector3 tp2 = tpvertices[j];
    68.  
    69.             float DotProduct = Vector3.Dot(Point - tp1, tp2 - tp1);
    70.  
    71.             PointInside = true;
    72.  
    73.             if (DotProduct < 0)
    74.             {
    75.                 PointInside = false;
    76.                 break;
    77.             }
    78.         }
    79.  
    80.         if (PointInside == true)
    81.         {
    82.             Debug.Log("Point inside");
    83.         }
    84.     }
    85. }
    86.  
     
    Last edited: Aug 28, 2022
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    32,222
    Is this just an experiment? You already say:

    so... what are you trying to do? Just use another method than the one you are using?

    I would start with google, perhaps something like:

    test inside polygon with cross product
     
  3. Vaizerition

    Vaizerition

    Joined:
    Apr 25, 2020
    Posts:
    57
    I was trying to find other ways to do point in polygon for 3D and the example code that I'm finding is for 2D.

    The code above only works with quads, so I got the polygon triangles and did a point in triangle test.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PointInPolygon2 : MonoBehaviour
    6. {
    7.     public Mesh mesh;
    8.  
    9.     public int[] triangles;
    10.  
    11.     public Vector3[] vertices;
    12.  
    13.     public bool PointInside;
    14.  
    15.     private Vector3 Point;
    16.  
    17.     private Vector3 CamPoint;
    18.  
    19.     public Plane TriPlane;
    20.  
    21.     // Start is called before the first frame update
    22.     void Start()
    23.     {
    24.         mesh = GetComponent<MeshFilter>().sharedMesh;
    25.  
    26.         triangles = mesh.triangles;
    27.         vertices = mesh.vertices;
    28.  
    29.         Vector3 tp1 = transform.TransformPoint(vertices[triangles[0]]);
    30.         Vector3 tp2 = transform.TransformPoint(vertices[triangles[1]]);
    31.         Vector3 tp3 = transform.TransformPoint(vertices[triangles[2]]);
    32.  
    33.         TriPlane = new Plane(tp1, tp2, tp3);
    34.     }
    35.  
    36.     // Update is called once per frame
    37.     void Update()
    38.     {
    39.         CamPoint = Camera.main.transform.position;
    40.  
    41.         Point = Vector3.ProjectOnPlane(CamPoint, TriPlane.normal);
    42.  
    43.         for (int i = 0; i < triangles.Length; i += 3)
    44.         {
    45.             Vector3 tp1 = transform.TransformPoint(vertices[triangles[i + 0]]);
    46.             Vector3 tp2 = transform.TransformPoint(vertices[triangles[i + 1]]);
    47.             Vector3 tp3 = transform.TransformPoint(vertices[triangles[i + 2]]);
    48.  
    49.             PointInside = false;
    50.  
    51.             //Point in triangle test: blackpawn.com/texts/pointinpoly
    52.  
    53.             // Compute vectors
    54.             Vector3 v0 = tp3 - tp1;
    55.             Vector3 v1 = tp2 - tp1;
    56.             Vector3 v2 = Point - tp1;
    57.  
    58.             // Compute dot products
    59.             float dot00 = Vector3.Dot(v0, v0);
    60.             float dot01 = Vector3.Dot(v0, v1);
    61.             float dot02 = Vector3.Dot(v0, v2);
    62.             float dot11 = Vector3.Dot(v1, v1);
    63.             float dot12 = Vector3.Dot(v1, v2);
    64.  
    65.             // Compute barycentric coordinates
    66.             float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
    67.             float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
    68.             float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
    69.  
    70.             // Check if point is in triangle
    71.             if (u >= 0 && v >= 0 && u + v < 1)
    72.             {
    73.                 PointInside = true;
    74.                 break;
    75.             }
    76.         }
    77.  
    78.         if (PointInside == true)
    79.         {
    80.             Debug.Log("Point inside");
    81.         }
    82.     }
    83. }