# How do you allow objects to only move in opposite direction of a vector? Can it be applied to boundaries?

## Recommended Posts

tom_mai78101    693
There is a circular obstacle in a game. The circle's center is marked as X. The obstacle is not shown fully in the diagram. The black object is the main object that can move around freely, but not inside the circle obstacle. I would like for the object to interact with the circular obstacle with the following passage:

"At any given point in time, once the black object touches the circle obstacle, the object can only move in the opposite direction of the vector."

Below is a diagram that depicts what I intended (expected myself) to do, and what I wanted to ask for.

[img]http://i.imgur.com/yPfoH.jpg[/img]
If there's a solution to the above, would it be also possible to extend the solution, so that the black object's movement can be limited by a given boundary? (meaning that the object can only move towards somewhere that is inside the purple boundary, shown in the diagram above.)

The boundary part is my ultimate question. Thanks in advance.

##### Share on other sites
Ripiz    539
Looks like you should allow movement only if angle between movement direction and vector is over 90 degrees.

Depending on directions of both vectors, this may or might not be correct, hopefully I didn't mess up logic/maths either.
[CODE]
if(dot(normalize(movement), normalize(vector)) < 0)
position += movement;
[/CODE]

If in #2 you mean completely opposite direction you need to compare to -1, but it's not likely to ever be ==-1, so try <-0.99 or something like that. Edited by Ripiz

##### Share on other sites
Cosmic314    2002
Use the radius of the circle and compare it to the distance the object is away from the center of the circle. You probably want to avoid using sqrt, so compare the distance squared to the radius squared. If the distance is <= radius then it is intersecting. To send it in exactly the opposite direction (as opposed to reflecting it) simply negate the entire direction vector. Edited by Cosmic314

##### Share on other sites
HappyCoder    5052
You probably want to take a look at this
[url="http://en.wikipedia.org/wiki/Vector_projection"]Vector Projection[/url]
Basically what it does is it takes two vectors and "flattens" one vector onto the other vector.

To project one vector onto the other.
[CODE]
double dot(Vector2 a, Vector2 b)
{
return a.x * b.x + a.y * b.y;
}
Vector2 scale(Vector vec, double scalar)
{
return new Vector2(vec.x * scalar, vec.y * scalar);
}
Vector2 projectAOntoB(Vector2 a, Vector2 b)
{
return scale(b, dot(a,b)/dot(b,b));
}
[/CODE]

The vector that restricts your movement can be calculated by subtracting the objects position from centers position.

[CODE]
restrictiveDirection = object.position - center;
[/CODE]

So then when you go to update the position of the object you want to restrict along the path you simply project the velocity of the object onto the vector that restricts the movement. Then we can check to see if the projected velocity is in the opposite direction of the restrictive direction using the [url="http://en.wikipedia.org/wiki/Dot_product"]dot product[/url]. (dot(a,b) = length(a) * length(b) * cos(angleBetween(a,b)) = a.x * b.x + a.y * b.y)

[CODE]
projectedVelocity = projectAOntoB(object.velocity, restrictiveDirection);

if (dot(projectedVelocity, restrictiveDirection) < 0)
{
// vectors point in opposite directions
projectedVelocity = new Vector2(0, 0);
}

// update the objects position using the new velocity
object.position += projectedVelocity * time;
[/CODE]

That code will restrict movement along only the line. If you want to restrict movement to the purple region you can modify the last snippet to look like this.
[CODE]
Vector2 newVelocity;
if (dot(object.velocity, restrictiveDirection) < 0)
{
// vectors point in opposite directions
// slide object along boundry
newVelocity = object.velocity - projectAOntoB(object.velocity, restrictiveDirection);
}
else
{
// moving away from center
newVelocity = object.velocity;
}
// update the objects position using the new velocity
object.position += newVelocity * time;
[/CODE] Edited by HappyCoder