Archived

This topic is now archived and is closed to further replies.

evilclown

Vectors bouncing

Recommended Posts

How would I bounce a vector off a wall or paddle? To get the new vector from a paddle collision would I add the vectors and do something else? I have no idea how to do the wall collision, but I know the angle between the ball and wall is the same as the new ball direction and wall. I looked at the reflection vectors for bouncing thread, but I don't understand it. Maybe I just need a basic vecor tutorial? I've read about how you add and subtract vectors, but am not sure how to apply it. [edited by - evilclown on May 5, 2002 3:40:45 PM]

Share this post


Link to post
Share on other sites
my thread below has confused me immensly, but I think I''m making some slow progress. Anyway, to get the ball bouncing off the walls you have to negate the appropriate vector element. eg if it touches the top or bottom, negate the Y component of your movement vector, if it hits the left or the right then negate the X component. Compared to the paddle that bits a doddle!!

Hope that helps get you started. Is it a breakout type game your doing by any chance?

Share this post


Link to post
Share on other sites
if it hhits the left or right side multiply the x component by negative 1 so it starts moving in opposite direction same for y component up or down

Share this post


Link to post
Share on other sites
if it hhits the left or right side multiply the x component by negative 1 so it starts moving in opposite direction same for y component up or down

Share this post


Link to post
Share on other sites
not quite sure, but I would imagine the x = -x version would have to create a new variable, hence a call to a constructor at the very least. Therefore probably slower, but I''m just guessing...

Share this post


Link to post
Share on other sites
quote:
Original post by evilclown
what would be faster for the computer?

x *= -1;

or

x = -x;


Go for the second, just because it''s clearer. It does NOT make a temporary variable.

Actually, any compiler with any optimization whatsoever will make both of those the same machine code. Don''t sweat it; you can profile later.

Share this post


Link to post
Share on other sites
dont care about _THAT_ bit of code..
the compiler will optimice it anyways
and do you think that this will be a speedloss if a normal pc can do this up to 2.4billion times a second today. i dont think you have 10million paddles..

"take a look around" - limp bizkit
www.google.com

Share this post


Link to post
Share on other sites
another good one is

for(;
{
int temp;
}

versus

int temp;
for(;
{ ...}

if you dont reference temp outside the for loop they will both generate the same code. in fact putting it in the for loop is safer. that keeps the scope very clear.

dont optimize for the compilier. code in a clear manner. the compilier doesnt always do it by the book. if it did it would suck.

consider both the above. the new variable in the loop looks nasty and would be if the compilier were forced to take it off the stack at the end of the loop . consider the variable outside the for loop ewww now its got a huge scope. the compilier is smarter then both of those cases.

worry bout algo''s not code tricks. generally speaking compiliers kick your butt anyhow in the code tricks department. just code what your trying to say. literally. say it in code. that should be your focus.

sigh but i have seen people gig''d by TAs on the first. its silly. in my view the first is better cause it limits scope and announces in code to a reader that i have no use for this variable beyond this loop. but scoping everything with { int temp; for(;{...}} is a tad silly too.


Share this post


Link to post
Share on other sites
Is the smiley supposed to be a ; ) ?

Do I need to worry about optimizing at all? All I know is multiplying is faster than dividing, thats why i asked the x question.

Now how do I get the ball to move? Is there a better way than to find the rotation of the vector, and the magnitude. Then use cos and sin to find the new coordinates using that?

If so, Is there a faster way at finding the rotation besides doing

rotation = degtorad((1 / (cos (vector.x / vector.magnitude))));


I''m not sure if the degtorad is in the right place, but otherwise the above is supposed to mean:


rotation = cosinverse (x / r)

Share this post


Link to post
Share on other sites
in order:

1. worry bout your algo
1.5 worry bout calls to malloc/new and disc access
2. worry bout copying classes/structs
3. worry bout only having memory allocated as much as it is mutable.
4. worry bout efficient mathematics in a general form. (fast equations)


number 1) is well known worry bout looping.
number 1.5 (added in edit)) new and malloc ARE SLOW! call them only in key specific places. almost all games dont actually free/alloc memory while running. they just keep it all in a big pile a free/alloc privately. disc access is worse =/
number 2) i use
class foo
{
public:
//stuff
....
private:
foo(foo &f){;};
};

i use that ALOT. basically copying anything non trivial is expensive. unfortunatly every class in C++ has a built in memory copying foo(foo& f); constructor. its always there but there is no reason to use it normally. yet you do it gets called in places that you dont think of. so make the copy constructor private and copy via functions specifically.

number 3)
worry bout having 400 instances of a class that all have one field that is always the same value. as a rule you should try for only having as much mem allocated as is independantly changable.

and number 4)
a rip from quake3s mod code:
/*
===============
RotatePointAroundVector

This is not implemented very well...
===============
*/

those little blurps were all over quake2's mod code. "this could be better" etc. lots less in q3's i notice. basically code to finish while worrying bout the above. then after its easy enough to go back and rewrite the math to be fast. and it is a concern its just your last concern.

thats my list. not on it is worrying bout whether i++ is faster then ++i



[edited by - declspec on May 6, 2002 3:08:16 PM]

Share this post


Link to post
Share on other sites
optimize algorithms.. for example this one:
for every vertex {
for every triangle {
if vertex is part of this triangle {
generate face normal
add face normal to vertex
}
}
}

that means you go through every triangle for every vertex.. an O(n*m) operation

if you do it like this:

for every triangle {
generate face normal
for each of the 3 vertices {
add face normal to vertex
}
}

(as you stored the indecees to the vertex array you find the vertices for free, just use the indecees)

result:

O(3*n) for the vector additions, O(n) for the crossproduct..

result is that for meshes with big polygoncount say 1024 vertices and 1024 faces (if this is possible..)
your amount of calcs go from 1024*1024 to 1024*4 (more or less)

a boost of 256!

algorithmic optimations are always great.. if your algo is short and clean structured, it normally is fast (means if you know what you do you are not too stupid to do it slow)

an other thing is data management object oriented programming can help there a lot but not at all if used wrong (you possibly know the scare cries uh virtual function calls are SLOW! they arent.. if used correctly.. means not perpixel please, but per object its no problem at all)

means structure your whole code to be fast.. this is easy for simple engines like this:

while(1) {
for every object {
object->Update();
object->Draw();
}
}

but gets difficult with networking and other stuff and fixed time steps but variable frame rate etc..

depends on what you wanna do

dont try to optimize onliners of code..

but make sure you don''t do some major faults:

if you know math, you can get rid of a lot of trigonometic funcion calls with trigonometric identities or a simple piece of paper..

example:
cosine(2x) == 2cosine(x)^2-1
if you calculate with halfangles (often used for fast perpixellighting) you can''t use for example this:
cosine(2x) = cosine(2*arccosine(x)) in a pixelshader.. those functions are simply not there in..

math functions used in your engine should not use that much if/else statements, for example in a vector class there should be no if/else (except for the normalization making sure /0 does not happen.. well except u use an automatic function taking care of this, namely some fast_reverse_square_root )

try to optimize the mathfuncs if you _WANT_ (like invert_matrix4x4 or something) but don''t try to optimize one-liners like that x = -x or something..

this is job of your compiler, not of you..

and if you write it in a normal way the compiler will have a big chance to recocnise this structure and says ahh! he wants to negate it! so well.. lets use an automated assember instruction wich simply changes 1 bit, the sign bit.. if this is fast on the cpu.. (the instruction is called fneg i think, but not 100% sure)

care about a fast collisiondetection algo, not about a fast sign-inversion-algo

for your main question:

if you have a surface normal vector, then a reflection for arbitary directions is this:

reflected = incomming - 2*dotproduct(normal,incomming)*normal

for a bottom floor the normal is for example (0,1) (1 is one in y direction, one up)

resulting equation:

reflected = incomming - 2*(0*incomming.x+1*incomming.y)*(0,1)

reflected = incomming - 2*incomming.y*(0,1)

reflected = incomming - (0,2*incomming.y)

this means your x-direction is not affected, but the y-direction gets

reflected = incomming.y - 2*incomming.y = -incomming.y

what the suggestions had for reflecting on the floor


got some ideas?

"take a look around" - limp bizkit
www.google.com

Share this post


Link to post
Share on other sites
Thanks for all the help.

I understood everything before "for your main question", whats a "surface normal vector".

Are you multiplying by (0, 1) because then on the ball vector, the y would change, but x would not?

Share this post


Link to post
Share on other sites
A surface normal avector is a vector pointing "upwards" from the plane/polygon. eg if your polygon is lying flat on the origin the surface normal can be (0, 1, 0) or (0, -1, 0) depending on if the front of the polygon is facing up or down.Sorry dont know the answer to your other question

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
in 3d your bounce vector is...

bounceVector = surfaceNormal * -2.0f * DotVector( surfaceNorm, velocityVectorNormalized);

bounceVector now contains the true reflection in 3d...its normalized of course..so youll need to multiply your speed back into the vector.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
oops thats supposed to be a += and not an =

so...

bounceVector += surfaceNormal * -2.0f * DotVector( surfaceNorm, velocityVectorNormalized);

ok now this is your 3d reflection vector

Share this post


Link to post
Share on other sites
omg... omg. that is sooo right and soooo easy. *sighs at self* you dont understand we worked this to death in 2d. and i read your final version. and im like naw thats always going to be up. then i saw the += *flash of light* think to self: omg that is soooo right and sooo easy. sorry endo.


Share this post


Link to post
Share on other sites
Guest Anonymous Poster
yeah, it is a very easy and very fast equation..

dotvectors are pretty powerful operations when you know how to use them. some hardwares now have dotvector operations built right onto the chip, so its just a couple of asm instructions..though youll probably have to overload your dotvector routine with straight assmebly to get full optimization..

something like...

extern inline f32 DotVec( constVectorArg v0, constVectorArg v1 )
{
asm("xxxx";
}

Share this post


Link to post
Share on other sites
naw
there is no reason to do an asm version of
return a.x * b.x + a.y * b.y + a.z * b.z;

there isnt a asm coder alive that could code that better in asm then then the C++ compilier will do.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
sorry, but you are wrong.

say your writting code for the ps2..and you want the compilier to be smart about how it builds your code..its better to just write it yourself. besides that some of the compiliers dont optimize classes efficiently in all cases, especially vector and matrix classes where you want must of your code to be inlined with as few instructions as possible and ordered in such a way that causes the least amount of pipeline stalls. our lead engine guy actaully went into the source of gcc and fixed some of these class issues for the ps2 compilier.

Share this post


Link to post
Share on other sites