lol i dont see where i went wrong in the formation yet. but i see why it flys off to the side. the normal is pure y. the first crossproduct is pure z (two x, y planer vectors will always make that true). the resultant on the second cross product is going to be pure x cause its a pure y crossed by a pure z. its good your normal is a clean one component vector it made the bad math conceptually stand out.
now to where i went wrong in the math.
reflection vectors for bouncing
If you wanna mail me (see my profile) I can send my code straight to you, but I understand if you dont want to it about 1500 lines worth already.
I originally followed the collision code on the nehe site, here is a direct link to the tutorial:
http://nehe.gamedev.net/tutorials/lesson.asp?l=30
My actual collision code isn''t identical though, I cobbled it together from different sources so that I could understand as much as possible.
Gotta eat now, but I''ll check my mail in about an hour and sen the code then if you like. Thanks again for the help, a least it works now and I can move on a bit
I originally followed the collision code on the nehe site, here is a direct link to the tutorial:
http://nehe.gamedev.net/tutorials/lesson.asp?l=30
My actual collision code isn''t identical though, I cobbled it together from different sources so that I could understand as much as possible.
Gotta eat now, but I''ll check my mail in about an hour and sen the code then if you like. Thanks again for the help, a least it works now and I can move on a bit

my darn TI has dead batteries. i went back over the math.
assertion 1:
-move X normal = TowardsYou
confident thats true.
assertion 2:
newmove X normal = -TowardsYou
again confident that is true. (basis: same sine value means same magnitude direction is easy to see as opposite)
conclusion 3:
normal X -TowardsYou = newmove // ops on a cross product
thats where i went wrong. thinking thats a bad operation. man. how much math have i done wrong cause of that i wonder. the basis was i x j = k implies j x k = i but im thinking it matters that both are normalized... hrmm wish my TI had batteries.
----------------------------------------------------
but skip that
the case of the normal being (0,1,0) made me see what they are doing with dot products.
in the case of (0,1,0) we can just negate the y component of move and we get the right newmove.
newmove = move
newmove.y = -newmove.y
right?
for that special case. but what about the general case?
for that we need to express the move vector not in terms of i and j but in terms of the normal and something at 90 degrees of the normal.
we can make use of that crossproduct again. you know the bug version result
basis= CrossProduct(-move,normal);//negated for conceptual clarity
basis= CrossProduct(basis,normal);
//No potential bug here it comes out in the resulting projection. if its one way the proj is negative if tis another its positive
That gives us a vector at 90 degrees to the normal vector but sharing a plane with the move vector amd the normal vector. ie if both move and normal have a 0 z it will have a 0 z.
now we dot product
proj.y = DotProduct(normal,move);
proj.x = DotProduct(basis,move);
all thats saying is in terms of the normal move is this big in that direction (projection). and in terms of the normal to the normal move is this big in that direction (projection).
now as per the specific case we negate the normal component but leave the x alone.
proj.y = - proj.y
done? no the scale values are just in terms of the normal / normal to the normal.
newmove = proj.x * basis; //note this is a scaler times a vector
newmove += proj.y * normal;
bugless? heck no. but i been known to get lucky. the crossproducts are just there to produce a vector at 90 degrees to the normal to express the move vector in terms of the normal vector. there are other ways i bet.
EDIT:
thanks for listening to me but im really just reinventing the wheel. im sure this has been solved out before. now that i have explored the prob ill reread your code. and try to stick to the question =)
i decided this code should work:
basis= CrossProduct(-move,normal);
basis= CrossProduct(basis,normal);//its orth to the normal
proj.y = DotProduct(normal,move);
proj.x = DotProduct(basis,move);
proj.y = - proj.y
newmove = proj.x * basis; //use the proj data to reform the vector
newmove += proj.y * normal;
[edited by - declspec on May 5, 2002 12:34:44 PM]
[edited by - declspec on May 6, 2002 1:03:32 AM]
assertion 1:
-move X normal = TowardsYou
confident thats true.
assertion 2:
newmove X normal = -TowardsYou
again confident that is true. (basis: same sine value means same magnitude direction is easy to see as opposite)
conclusion 3:
normal X -TowardsYou = newmove // ops on a cross product
thats where i went wrong. thinking thats a bad operation. man. how much math have i done wrong cause of that i wonder. the basis was i x j = k implies j x k = i but im thinking it matters that both are normalized... hrmm wish my TI had batteries.
----------------------------------------------------
but skip that
the case of the normal being (0,1,0) made me see what they are doing with dot products.
in the case of (0,1,0) we can just negate the y component of move and we get the right newmove.
newmove = move
newmove.y = -newmove.y
right?
for that special case. but what about the general case?
for that we need to express the move vector not in terms of i and j but in terms of the normal and something at 90 degrees of the normal.
we can make use of that crossproduct again. you know the bug version result
basis= CrossProduct(-move,normal);//negated for conceptual clarity
basis= CrossProduct(basis,normal);
//No potential bug here it comes out in the resulting projection. if its one way the proj is negative if tis another its positive
That gives us a vector at 90 degrees to the normal vector but sharing a plane with the move vector amd the normal vector. ie if both move and normal have a 0 z it will have a 0 z.
now we dot product
proj.y = DotProduct(normal,move);
proj.x = DotProduct(basis,move);
all thats saying is in terms of the normal move is this big in that direction (projection). and in terms of the normal to the normal move is this big in that direction (projection).
now as per the specific case we negate the normal component but leave the x alone.
proj.y = - proj.y
done? no the scale values are just in terms of the normal / normal to the normal.
newmove = proj.x * basis; //note this is a scaler times a vector
newmove += proj.y * normal;
bugless? heck no. but i been known to get lucky. the crossproducts are just there to produce a vector at 90 degrees to the normal to express the move vector in terms of the normal vector. there are other ways i bet.
EDIT:
thanks for listening to me but im really just reinventing the wheel. im sure this has been solved out before. now that i have explored the prob ill reread your code. and try to stick to the question =)
i decided this code should work:
basis= CrossProduct(-move,normal);
basis= CrossProduct(basis,normal);//its orth to the normal
proj.y = DotProduct(normal,move);
proj.x = DotProduct(basis,move);
proj.y = - proj.y
newmove = proj.x * basis; //use the proj data to reform the vector
newmove += proj.y * normal;
[edited by - declspec on May 5, 2002 12:34:44 PM]
[edited by - declspec on May 6, 2002 1:03:32 AM]
Thanks so much for putting in the effort, for the moment I'll leave it as it is, just adding the y component to the result. It seems to be working fine, but I'll be after some maths books to try and learn some of this tuff in a few days 
EDIT:
Seems I was wrong, it only seems to work for the polygons facing upwards. When its hits the sides or bottom it all goes pear-shaped
[edited by - endo on May 5, 2002 2:57:08 PM]

EDIT:
Seems I was wrong, it only seems to work for the polygons facing upwards. When its hits the sides or bottom it all goes pear-shaped

[edited by - endo on May 5, 2002 2:57:08 PM]
http://www.gamasutra.com/features/20020118/vandenhuevel_03.htm
here is a good article on calculating collision and bounce.
here is a good article on calculating collision and bounce.
Previously I had said this
"Nice try, now the ball hits the polygon and travels off along the x axis. "
It turns out this isn''t entirely correct because it seems to travel along the plane in which the polygon lies, ie perpendicular to the normal. I dont know if this will help at all but it might be important so I thought I''d mention it
Thanks for the link nemesis, I''ll check it out later when I can access my email account.
"Nice try, now the ball hits the polygon and travels off along the x axis. "
It turns out this isn''t entirely correct because it seems to travel along the plane in which the polygon lies, ie perpendicular to the normal. I dont know if this will help at all but it might be important so I thought I''d mention it
Thanks for the link nemesis, I''ll check it out later when I can access my email account.
Your velocity vector can be viewed as being the sum of two vectors. One is parallel to the normal and the other is orthogonal to it. So o+p=v where o is the component orthogonal and p is the component parallel to n. If you draw these by positioning o and v at the same location and p at the terminal point of o then you get a right triangle. You have one of those vectors, v. What o and p are depends on what you are orthogonal and parallel to, i.e. your normal n. n.v=|n||v|cos(theta) so (n.v)*(1/|n|)=|v|cos(theta). |v| is the length of the hypotheneous of a right triangle. |p| and |o| are the lengths of the other two sides. |p|=|v|cos(theta) and |o|=|v|sin(theta). |n x v|=|n||v|sin(theta). |n x v|(1/|n|)=|v|sin(theta)=|o|. p=|p|n(1/|n|) and o=v-p. So v minus p is a vector orthogonal to n which is what you have. Now if you call your reflected vector r then r=v-2p, v=o+p and r=o-p. o=(v x n) x n (1/|n|^2). r=o-p, p=v-o and r=2o-v.
Might be some mistakes in there, but it should be pretty close. Your normal is normalized so the (1/|n|) terms can be ignored. You can use the dot product, you can use the cross product, but either way you have to multiply by 2.
Might be some mistakes in there, but it should be pretty close. Your normal is normalized so the (1/|n|) terms can be ignored. You can use the dot product, you can use the cross product, but either way you have to multiply by 2.
Keys to success: Ability, ambition and opportunity.
come on endo try this one
still wish i had my darn ti going.
basis= CrossProduct(-move,normal);basis= CrossProduct(basis,normal);//its orth to the normalproj.y = DotProduct(normal,move);proj.x = DotProduct(basis,move);proj.y = - proj.ynewmove = proj.x * basis; //use the proj data to reform the vectornewmove += proj.y * normal;
still wish i had my darn ti going.
Sorry for dragging this out, but I haven''t done any calculus in over 5 years and vector maths is completely new to me. That last code sample doesn''t work either, its very unpredictable having totally different reactions depending on where it hits.
I did think about calculating the angle between the movement vector and the normal, and using that to create the new vector. Would that be possible?
I did think about calculating the angle between the movement vector and the normal, and using that to create the new vector. Would that be possible?
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement