• ### Announcements

#### Archived

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

# Vectors bouncing

## Recommended Posts

evilclown    122
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 on other sites
Nemes1s    122
http://www.gamasutra.com/features/20020118/vandenhuevel_03.htm

##### Share on other sites
endo    122
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 on other sites
IFooBar    906
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 on other sites
IFooBar    906
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 on other sites
evilclown    122
what would be faster for the computer?

x *= -1;

or

x = -x;

##### Share on other sites
endo    122
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 on other sites
Sneftel    1788
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 on other sites
endo    122
oops, I stand corrected

##### Share on other sites
davepermen    1047
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

##### Share on other sites
declspec    126
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 on other sites
evilclown    122
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 on other sites
declspec    126
in order:

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 on other sites
davepermen    1047
optimize algorithms.. for example this one:
for every vertex {
for every triangle {
if vertex is part of this triangle {
generate face normal
}
}
}

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 {
}
}

(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)

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

##### Share on other sites
evilclown    122
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 on other sites
endo    122
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 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 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 on other sites
declspec    126
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 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 on other sites
declspec    126
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.