- Home /
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?
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;
}
Yep works out the gate, thank you! Could you change your comment to answer
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.
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 $$anonymous$$d finds an alternative.
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.$$anonymous$$.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.$$anonymous$$.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];
Well you aren't actually finding the closest point along the line, you're just finding the closest corner of the square.
Your answer
Follow this Question
Related Questions
How would you make a jump like geometry dash/impossible game? 7 Answers
Object Selection does not stop on next object 0 Answers
2D sprites - Can I use point filtering without getting the "rippling" effect when the camera moves? 2 Answers
Is it possible to default sprites to Point (No filter) instead of Bilinear? 0 Answers
2D Moving on clicked position 2 Answers