I have this nice drawing:
I know the ball's center and the rectangle's center, but how do I know (programming C#) what side of the rectangle the ball is?
By my drawing, the answer in this case should be the right side.
I have this nice drawing:
I know the ball's center and the rectangle's center, but how do I know (programming C#) what side of the rectangle the ball is?
By my drawing, the answer in this case should be the right side.
What side of A is B on? Using this info (see Solution 3) you can determine which side of a line A point (or points) B, is on.
For your particular scenario, you need to check which of four sides of the rectangle, the circle is in. In this case, you can treat your circle as just it's centre/origin point. Now you need to look at the rectangle like this:
\ /
\ q1 /<--one of the two lines bordering quadrant 4
*---*
|\ /|<---rectangle edge for quadrant 4
q4| x |q2
|/ \|
*---*
/ q3 \<--one of the two lines bordering quadrant 4
/ \
The q
's stand for quadrant or side of the rectangle you're on; the numberings are abritrary, but just show you that the centre point can lie in any of these 4 distinct quadrants. You need to determine that the circle centre is:
AND
This will tell you if the point falls in to the bowl-shaped area on each of the four sides of the rectangle shown above.
The "correct" side is determined by you, when you construct the formula in the link given above. It depends on whether you specify a line as PQ or it's reverse, QP. This is known as winding order (see "Winding Order of Vertices").
checkSide(Line l, Point p)
isn't what I'd call onerous.
\$\endgroup\$
– Engineer
Jan 28 '12 at 13:43
I do this by giving all of my game entities a position (Vector 2D/3D), and a rotation (Matrix 3x3). Your rotation matrix will have either a column or row for its forward, up, and right vectors. In the case of a 2D game, the 'up' vector is unnecessary.
First you get the vector from your square's center to the ball's center.
Vector2 direction = ball.position - square.position;
Now you normalize/unitize the vector to make it represent a unit-length direction
direction.Unitize();
// Here's a method to unitize a 2D vector
void Vector2::Unitize()
{
const float inverseLength = 1.0f / Length();
x *= inverseLength;
y *= inverseLength;
}
Unitizing requires knowing the length of your vector, so we make a helper method for that as well
float Length(void) const { return sqrtf( x * x + y * y ); }
Ok, now that we have a direction from the square to the ball, defined earlier by the 2D vector we called direction
, we now do a dot-product between that direction, and the square's right vector (the direction the represents its right-hand side). For this example, in your image, let's say the square is facing toward the top of the image, and that the ball is on the square's right-hand side. Doing this dot product will tell us if the ball is on the right-hand or left-hand side of the square.
Vector2 squareRightVect; // You would retrieve this from the square's rotation matrix
float dotResult = direction.Dot(squareRightVect);
Now we have the dotResult
, which will be a value between -1 and 1, anything greater than 0 means the ball is on the right side of the square. Based on the image I'd say the dot product would be about 0.85, putting the ball on the right side of the square. If your dot-product gave a result of anything less than zero than the ball is on the left.
And finally, here's your dot-product method:
float Dot(const Vector2& rhs) const { return (x * rhs.x + y * rhs.y); }
And here are some helpful links if you want to learn more about the processes involved in the above code: