Friday, February 8, 2019

c# - How do I restrict the movement of a point to within a radius of another?


I have a situation where a sprite's center point needs to be constrained within a certain boundary in 2D space. The boundary is circular, so the sprite is constrained within a radius. This radius is defined as a distance from the center of a certain point.


I've got this code, but it only tells me when the center has overstepped the allowed radius:


float distance = Vector2.Distance(centerPosition, spritePosition));
if (distance > allowedDistance) {
// Point is outside allowed range
}

I would like to also return the sprite's center to the closest point within that radius whenever it oversteps the bounds.


How can I do that?




Answer



Take the position of the object, minus the origin of the circle. This will give you a vector from the origin to the object. The length of this vector is the distance to the object. Multiply this vector by the circle's radius divided by the distance to the object. Set the object's position to the circle's origin plus this vector.


Psuedo-Code:


Vector FromCircleToObject = Object.Position - Circle.Origin;
FromCircleToObject *= Circle.Radius / FromCircleToObject.Length;
Object.Position = Circle.Origin + FromCircleToObject;

You can optimize this by using the vector's length squared. This saves you a square root. If you use the vector's length squared, you must use the circle's radius squared. Luckily, squaring is cheaper than square rooting, so there's still an optimization to be had.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...