Search Unity

How to find a point in a collider farthest from a given position? (reversed ClosestPointOnBounds)

Discussion in 'Scripting' started by Compressed, Jul 28, 2015.

  1. Compressed

    Compressed

    Joined:
    Sep 20, 2014
    Posts:
    59
    If i have some vector 3 position in the world and i have some collider (box, sphere...) in the world as well, how do i find out, which position in this collider is the most far from my vector 3 position?

    So basically reversed ClosestPointOnBounds, ( as in something like FarthestPointOnBounds). Thanks
     
  2. martinmr

    martinmr

    Joined:
    Mar 25, 2015
    Posts:
    325
    I don't think there's a method provided by Unity, so you have to calculate them yourself.

    But why you need this ? :D
     
  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    move your vector 3 to the exact opposite side of the collider, and check the closestpointonbounds from there.

    So if your vector is "position", and the collider is "col", it'd be:

    Code (CSharp):
    1. Vector3 positionToCollider = col.transform.position - position;
    2.  
    3. Vector3 otherSide = col.transform.position + positionToCollider;
    4.  
    5. Vector3 farthersPoint = col.ClosestPointOnBounds(otherSide);
     
  4. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    If the collider is a primitive you can use the properties of the primitive to 'project' the position across. Spheres will be easiest, but it will work with cubes or capsules as well.

    If you are working with a complex mesh collider you are stuck iterating through vertices of the mesh and doing distance checking on each one.

    Edit: Just realised you are working with bounds. This makes it pretty simple. Just check the corners of the bounding box to determine which point is furthest away. Fun fact, with cubes it will always be one of the corners on the opposite face that is furthest away.
     
  5. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Will this work for anything not a sphere? Its late and my math is a bit sketchy.
     
  6. Compressed

    Compressed

    Joined:
    Sep 20, 2014
    Posts:
    59
    Baste: That doesn't work for box colliders, i tried it, but it returns incorrect values

    BoredMormon: I can't seem to figure out how to get world position of the corners from a collider box.
     
    Last edited: Jul 28, 2015
  7. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Since bounds are always square, its bounds.centre + bounds.extents. Separate the extents out to its individual float values.
     
  8. martinmr

    martinmr

    Joined:
    Mar 25, 2015
    Posts:
    325
    For a Box Collider when i'm correct, one of the vertex points of the collision box has to be the farest point away.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class NewBehaviourScript : MonoBehaviour {
    6.  
    7.  
    8.     public List<Vector3> vertexPoints = new List<Vector3>();
    9.     public Vector3 myVector = new Vector3 (10f, 10f, 10f);
    10.  
    11.     void Start () {
    12.  
    13.         BoxCollider boxCollider = gameObject.GetComponent<BoxCollider> ();
    14.  
    15.         vertexPoints.Add (boxCollider.bounds.max);
    16.         vertexPoints.Add (boxCollider.bounds.min);
    17.         vertexPoints.Add (new Vector3 (boxCollider.bounds.max.x, boxCollider.bounds.max.y, boxCollider.bounds.min.z));    
    18.         vertexPoints.Add (new Vector3 (boxCollider.bounds.max.x, boxCollider.bounds.min.y, boxCollider.bounds.min.z));      
    19.         vertexPoints.Add (new Vector3 (boxCollider.bounds.max.x, boxCollider.bounds.min.y, boxCollider.bounds.max.z));    
    20.         vertexPoints.Add (new Vector3 (boxCollider.bounds.min.x, boxCollider.bounds.min.y, boxCollider.bounds.max.z));    
    21.         vertexPoints.Add (new Vector3 (boxCollider.bounds.min.x, boxCollider.bounds.max.y, boxCollider.bounds.max.z));
    22.         vertexPoints.Add (new Vector3 (boxCollider.bounds.min.x, boxCollider.bounds.max.y, boxCollider.bounds.min.z));
    23.  
    24.  
    25.         int maxDistanceVector = 0;
    26.         float distance = 0;
    27.         Vector3 getCollisionPoint = boxCollider.ClosestPointOnBounds (myVector);
    28.  
    29.         for (int i = 0; i < vertexPoints.Count; i++){
    30.             if (i == 0) {
    31.                 distance = Vector3.Distance(getCollisionPoint, vertexPoints[i]);
    32.                 maxDistanceVector = 0;
    33.             } else {
    34.                 float newDistance = Vector3.Distance(getCollisionPoint, vertexPoints[i]);
    35.                 if(distance < newDistance){
    36.                     distance = newDistance;
    37.                     maxDistanceVector = i;
    38.                 }
    39.             }
    40.  
    41.         }
    42.  
    43.         Debug.Log ("Farest away point of box collider from vector: " + vertexPoints [maxDistanceVector]);
    44.     }
    45. }
     
    Last edited: Jul 28, 2015
    Kiwasi likes this.
  9. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    That's what I was suggesting. You missed two vertex points, but the concept is sound.
     
    martinmr likes this.
  10. Compressed

    Compressed

    Joined:
    Sep 20, 2014
    Posts:
    59
    Thanks guys, it works. But i noticed one buglike thing. If i place sphere on the vert coordinates to actually see them visually, the get placed exactly at the collider box vertices if the game object is placed with zero rotation. But if the object is rotated then the verts are in incorrect position it seems.