Easy vector math question...

Started by
7 comments, last by Dookie 19 years, 4 months ago
Hello! I'm not a math wiz, and this problem is really bugging me 'cause I can't figure it out. It's for a 2D sidescroller game. I'll reference my poorly drawn picture to make it easier for me to describe what I'm trying to do. You can see two boxes, one on the left (leftBox) and a smaller slightly rotated one on the right (rightBox). I'd like an equasion to tell my program that 'rightBox' collided with 'leftBox', and also I'd like to know how to tell my program the vector normal (is that correct?) of the side of 'leftBox' that 'rightBox' collided with. If I'm thinking straight and a normalized upward vector on an (x,y) grid is indeed (0,1), then the above collision detection example would tell my program that 'rightBox' collided with 'leftBox', and the normal returned from the function was (0,1). Whew, hope I wasn't too confusing in my problem description... I pretty much confused myself, though! :D Thanks in advance for the help! :)
"The crows seemed to be calling his name, thought Caw"
Advertisement
I'm afraid collision detection is beyond my skillset, but just to clarify for others, do you mean you would like to find the normal of the face of leftbox that rightbox collided onto?

Quote:If I'm thinking straight and a normalized upward vector on an (x,y) grid is indeed (0,1), then the above collision detection example would tell my program that 'rightBox' collided with 'leftBox', and the normal returned from the function was (0,1).


How do you arrive at that? *confused*
My stuff.Shameless promotion: FreePop: The GPL god-sim.
Thanks for the reply, Doc!

Quote:Original post by Doc
I'm afraid collision detection is beyond my skillset, but just to clarify for others, do you mean you would like to find the normal of the face of leftbox that rightbox collided onto?

Yes, that's exactly what I want.

Quote:Original post by Doc
How do you arrive at that? *confused*

I'm sure my math is completely bonkers, so I prolly got that one wrong. You might have to read between the lines to figure out what I'm wanting to do... Hopefully I'm not being more confusing than I'm being at describing! :(

What's embarassing about asking my question is that it's probably an amazingly simple thing, but I just don't have the math background to actually DO what I'm wanting to do. Anybody else know how to make this collision detection scheme happen?

Thanks!
"The crows seemed to be calling his name, thought Caw"
So, in this example, you have rightbox colliding into the left face of leftbox. Now, a normal to any face is perpendicular to that face, so here you want your algorithm to return (1, 0). Does that sound like it makes sense to you?

I'm not able to help solve the actual algorithm, though. Hopefully someone else is better versed in that area. [smile]
My stuff.Shameless promotion: FreePop: The GPL god-sim.
Well, the question of detecting whether or not two boxes colide is relatively straight forward for a 2D plot. You have the vertices of rightBox, so go through each vertex and see if any of them lie inside the other box, i.e.:

if (vertex <= leftBox.MaxX &&
vertex <= leftBox.MaxY &&
vertex >= leftBox.MinX &&
vertex >= leftBox.MinY)
{
// boxes collided.
}

(the code sample is assuming leftBox is axis-aligned, obviously. If that's not the case you'll have to transform the box or change the test a bit)

That obviously only tests whether or not one vertex of rightBox is inside leftBox. In order to be completely correct, you should test for the case where one face of rightBox intersects with a corner of leftBox (i.e. test each face of rightbox to see if it overlaps leftBox. You can do this by testing whether any of the vertices of leftBox are inside rightBox).

(then there's the border case where two of the faces directly overlap. You can choose whether or not to handle that case based on what makes sense for your program)

If you want to find which face it is that the collision happened, then you need to know the velocity of rightBox, so you can determine which direction it's moving.

For example: In your example, how do you know that it intersected the right face of leftBox? It could have taken a while drawing the last frame and rightBox may have been moving left-to-right and just passed most of the way through leftBox.

-Alias
If you are unsure of the orientation of either box have a go at the following...

say the left box has vectors L1 L2 L3 L4 and the right box has vectors R1 R2 R3 R4

To test if a point of the right box is inside the left box, you will need to show that the angles from R* to each edge of the left polygon add to 360 degrees or 2 pi...

The angle between two vectors can be computed by acos of the dot product...

float CVector2::Dot(const CVector2 &v1, const CVector2 &v2)
{
return v1.x * v2.x + v1.y * v2.y;
}

float CVector2::Angle(const CVector2 &v1, const CVector2 &v2)
{
return acos(Dot(v1,v2));
}

So in the above example...
You want 4 vectors from R to each L1

bool PointInBox(const CVector2 &R, const CVector2 &L1, ... , const CVector2 &L4)
{
SVector2 v1(L1 - R);
SVector2 v2(L2 - R);
SVector2 v3(L3 - R);
SVector2 v4(L4 - R);

float Angle = 0;
Angle += CVector2::GetAngle(v1,v2);
Angle += CVector2::GetAngle(v2,v3);
Angle += CVector2::GetAngle(v3,v4);
Angle += CVector2::GetAngle(v4,v1);

return (Angle >= 2 * Pi);
}

as for the normal, your best bet would be probably just the use the -velocity as Alias suggested. This will not give you proper reflection / bounce though.

- Steve
EDIT: I'm an idiot, ignore me. Thanks Dmytry [smile]

[Edited by - joanusdmentia on December 15, 2004 2:11:32 AM]
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
hmm, separating axis thingy, as i understand, is just absolutely incorrectly used.
Let we have 2 boxes staying one right to other, parallel. Then we turned entire thing by 45 degrees.


As about checking for collision:
It is
1: needed to check if one vertice of one box is inside other box, and vice-versa.
2: check each pair of edges for intersection.
Imagine cross, made of horisontal and vertical box. Do you need to find collision in that case?("1:" will not work) It's not really necessary because you need to collide in way detectable by "1:" before that, and then penetrate deep enough.

as about normal:
it is not well-defined unless you'll do collision prediction. It is pretty simple:

relatively to first box, for all segments between vertices of second box in prev.frame and vertices in current frame, find intersection of segments with edges of first box. Find intersection that happens earlier, and use normal of intersected face.
Then do same for second box.

Doing something relatively to boxA mean that you subtract velocity of boxA from vecocity of boxB, and then work like velocity of boxA is 0.

[Edited by - Dmytry on December 15, 2004 2:19:59 AM]
Whew, I think I just need to learn a little more trig before I can really grasp those concepts. And to be able to describe future problems while using the proper terminology!

I did some research and Doc's right, the normal of the line where 'rightBox' is colliding would be a perpendicular vector for the 'leftBox' line that it's colliding with. That's what I'm trying to get when 'rightBox' hits it.

Right now I'm using a simple collision detection routine that doesn't take into account rotations and such, so it cannot do what I'm trying to do. But maybe after reading the same book where I learned about normals (that a 'normal' for a line is actually a perpendicular vector and not the line itself - duh!), maybe I can convert that collision detection routine to work with rotated objects.

Thanks for the replies, guys. Who'd think that the physics behind a friggin Pong-style game would be so complicated? Granted, it's a somewhat 'unconventional' Pong game... Anyways, wish me luck, because I'm gonna need it. Thanks again! :)
"The crows seemed to be calling his name, thought Caw"

This topic is closed to new replies.

Advertisement