Started by Oct 05 2012 12:43 PM

,
3 replies to this topic

Posted 05 October 2012 - 12:43 PM

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.

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.

"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.

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.

Posted 05 October 2012 - 01:08 PM

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.

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.

Depending on directions of both vectors, this may or might not be correct, hopefully I didn't mess up logic/maths either.

if(dot(normalize(movement), normalize(vector)) < 0) position += movement;

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, 05 October 2012 - 01:10 PM.**

Posted 05 October 2012 - 01:23 PM

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, 05 October 2012 - 01:31 PM.**

Posted 05 October 2012 - 03:49 PM

You probably want to take a look at this

Vector Projection

Basically what it does is it takes two vectors and "flattens" one vector onto the other vector.

To project one vector onto the other.

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

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 dot product. (dot(a,b) = length(a) * length(b) * cos(angleBetween(a,b)) = a.x * b.x + a.y * b.y)

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.

Vector Projection

Basically what it does is it takes two vectors and "flattens" one vector onto the other vector.

To project one vector onto the other.

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)); }

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

restrictiveDirection = object.position - center;

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 dot product. (dot(a,b) = length(a) * length(b) * cos(angleBetween(a,b)) = a.x * b.x + a.y * b.y)

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;

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.

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;

**Edited by HappyCoder, 05 October 2012 - 03:55 PM.**

My current game project Platform RPG