Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have this nice drawing:

http://bildr.no/view/1085283

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.

share|improve this question
1  
Is the rectangle always axis-aligned, or does it have an orientation? –  Sam Hocevar Jan 22 '12 at 14:00

2 Answers 2

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:

  • to the correct side of each of the two lines bordering that quadrant (the diagonal ones in the drawing above), i.e. it must lie between them;

AND

  • to the correct side of the rectangle-edge that lies within that quadrant (between the aforementioned diagonal lines.

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

share|improve this answer
    
Seems like a lot more work than just doing a dot product. Additionally, your solution is limited to rectangle only. –  Nic Foster Jan 27 '12 at 15:44
    
@NicFoster Not getting any upvotes, eh? Hmm. –  Nick Wiggill Jan 27 '12 at 17:16
    
You've avoided the context of the original comment. You don't agree that this is a lot of work to find the side of the shape a position lies? –  Nic Foster Jan 27 '12 at 20:54
    
I'd say this answer is slightly more intuitive, albeit not by much. It certainly doesn't take any credibility from your own. If you've ever tried to explain what the dot or cross product are, visually, you'll see that it becomes less trivial to follow the logic in solving the problem as a whole. Many take the mathematics behind those factors for granted, and use them without understanding what they are actually doing. And no, I don't agree. The conciseness of my answer in relation to yours speaks to that fact. Writing a method checkSide(Line l, Point p) isn't what I'd call onerous. –  Nick Wiggill Jan 28 '12 at 13:43
    
Agree with most that, but I do feel like your answer is tailored more towards rectangles specifically, whereas the use of vector math (dot product, unitization) is applicable to just about any shape or situation in both 2D and 3D. –  Nic Foster Jan 29 '12 at 4:52

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:

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.