• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by PlayCreatively · Nov 11, 2020 at 10:57 AM · 2ddistanceboundspointgeometry

Get closest point on 2D perimeter using Bounds

I'm using the Bounds.ClosestPoint to get the closest point on bounds but when inside the bounds you just get the current spot but I want to keep getting a point on the perimeter.

Can anyone throw me the calculations for that?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by elenzil · Nov 13, 2020 at 08:59 PM

okay, this actually works. there was another error in my example as well, but I've tested this.

 Vector3 finder(Vector3 p, Bounds b)
 {
     // I'll assume the 2D aspect of this is X and Y, and ignore Z.

     Vector3[] edgePoints = new Vector3[4];

     // point on left edge
     edgePoints[0].x = b.min.x;
     edgePoints[0].y = Mathf.Clamp(p.y, b.min.y, b.max.y);
     edgePoints[0].z = b.center.z;


     // point on right edge
     edgePoints[1].x = b.max.x;
     edgePoints[1].y = Mathf.Clamp(p.y, b.min.y, b.max.y);
     edgePoints[1].z = b.center.z;

     // point on bottom edge
     edgePoints[2].x = Mathf.Clamp(p.x, b.min.x, b.max.x);
     edgePoints[2].y = b.min.y;
     edgePoints[2].z = b.center.z;

     // point on top edge
     edgePoints[3].x = Mathf.Clamp(p.x, b.min.x, b.max.x);
     edgePoints[3].y = b.max.y;
     edgePoints[3].z = b.center.z;

     // now find the closest.

     float closestSqrDist = -1; // value doesn't matter.
     int closestIndex = -1; // value doesn't matter.
     for (int n = 0; n < 4; ++n)
     {
         float sqrDist = (edgePoints[n] - p).sqrMagnitude;
         if ((n == 0) || (sqrDist < closestSqrDist))
         {
             closestSqrDist = sqrDist;
             closestIndex = n;
         }
     }

     Vector3 closestPointOnEdgeOfBoundingBox = edgePoints[closestIndex];

     return closestPointOnEdgeOfBoundingBox;
 }
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image PlayCreatively · Nov 14, 2020 at 12:03 AM 0
Share

Yep works out the gate, thank you! Could you change your comment to answer

avatar image elenzil PlayCreatively · Nov 14, 2020 at 12:49 AM 0
Share

awesome, I'm glad this worked for you !

avatar image
1

Answer by elenzil · Nov 11, 2020 at 06:56 PM

 heh. interesting.
 
 I can't think of a way to shortcut it,
 so you'd need to find the shortest distance to each edge yourself.  
 
 Note that Bounds is an Axis-Aligned Bounding Box,
 which means the edges are parallel to the X and Y axes,
 which simplifies finding the distance from a point to an edge.

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image PlayCreatively · Nov 11, 2020 at 07:27 PM 0
Share

I was afraid that was the case. I read some nightmare solution on the web that makes you find a point along every edge and then pick the closest one. But like you said this can probably be achieved easily since there's no rotation to factor in. Hope some brilliant mind finds an alternative.

avatar image elenzil PlayCreatively · Nov 12, 2020 at 11:02 PM 0
Share

hm. frankly this is not a particularly burdensome task. even doing it with an arbitrarily-oriented bounding box is far from nightmarish. .. or should be, I don't know the code you found.

here's an implementation. I haven't tested it, but it should work whether your point is inside the box, outside the box, or on the edge of the box. it uses sqr$$anonymous$$agnitude instead of magnitude because it's a good practice when you're comparing distances to use the squared version because it may be faster if you're dealing with a bazillion comparisons. in this case, magnitude would probably be more than fine.

 Vector3 p = <the point you're interested in>;
 Bounds  b = <the AABB bounding box>;
 
 // I'll assume the 2D aspect of this is X and Y, and ignore Z.
 
 Vector3[] edgePoints = Vector3[4];  // syntax might be wrong on this. an array of 4 Vector3's.
 
 // point on left edge
 edgePoints[0]   = p;
 edgePoints[0].x = b.min.x;
 
 // point on right edge
 edgePoints[1]   = p;
 edgePoints[1].x = b.max.x;
 
 // point on bottom edge
 edgePoints[2]   = p;
 edgePoints[2].y = b.min.y;
 
 // point on top edge
 edgePoints[3]   = p;
 edgePoints[3].y = b.max.y;
 
 // now find the closest.
 
 float closestSqrDist = -1; // value doesn't matter.
 int   closestIndex   = -1; // value doesn't matter.
 for (int n = 0; n < 4; ++n) {
     float sqrDist = (edgePoints[0] - p).sqr$$anonymous$$agnitude;
     if ((n == 0) || (sqrDist < closestSqrDist)) {
         closestSqrDist = sqrDist;
         closestIndex   = n;
     }
 }
 
 Vector3 closestPointOnEdgeOfBoundingBox = edgePoints[closestIndex];

avatar image PlayCreatively elenzil · Nov 13, 2020 at 07:54 PM 0
Share

Well you aren't actually finding the closest point along the line, you're just finding the closest corner of the square.

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

306 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to make a 2D character points his gun to the mouse position? 2 Answers

Why is this ray returning distance as zero? 1 Answer

Find center between 4 points 3 Answers

Keep player from falling outside the camera? [2d] 1 Answer

What should I use as boundaries to a 2d game? 0 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges