Jump to content
  • Advertisement

Archived

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

endo

reflection vectors for bouncing

This topic is 5860 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have used the following code to calculate the reflection vector for my ball, the problem is it just bounces back in the direction it came from Any idea why? I followed the theory from one of the tutorials on the nehe site.
  	if( ball.getActive( ) )		//if inactive ball is drawn but doesnt move

	{
		ball.moveBall( );
		MyPolygon hit;

		if( ballPaddleCollision( paddle, *ball.getLoc( ), ball.getRadius( ), hit ) )
		{
//			cout << *hit.getNormal( ) << endl;

//			cout << *ball.getMove( ) << endl;

			Vector3d newVector;
			Vector3d hitNormal = *hit.getNormal( );
			Vector3d ballMovement = *ball.getMove( );
			hitNormal.normalise( );
			ballMovement.normalise( );
			newVector = hitNormal + ballMovement * dotProduct( -ballMovement, hitNormal ) * 2;
			newVector = newVector * ballMovement.length( );
			ball.setMove( newVector );
		}
	}  

Share this post


Link to post
Share on other sites
Advertisement
This line seems not to be right:

newVector = hitNormal + ballMovement * dotProduct( -ballMovement, hitNormal ) * 2;
shouldn''t it be:
newVector = ballMovement + hitNormal * dotProduct( -ballMovement, hitNormal ) * 2;

Hope that was the bug.

Share this post


Link to post
Share on other sites
Sorry, doesnt seem to have made any difference - although I''m sure its more correct than the way I had it

Share this post


Link to post
Share on other sites
a-((a.b)/(b.b))*b is the component of a orthogonal to b. If the magnitude of b is 1 then that reduces to a-(a.b)*b. You don''t want orthogonal, but the reflection so it is a-2*(a.b)*b. (a.b)*b is the component of a parallel to b and (-a).b = -(a.b). If you normal either points the wrong direction or is does not have a magnitude of one then you don''t get the right answer.

Share this post


Link to post
Share on other sites
I''m sure the normal is correct and as you can see the code normalises it before it is used.

Share this post


Link to post
Share on other sites
That may very well be your problem. You wrote

newVector = newVector * ballMovement.length( );

ballMovement''s length is 1 if it is normalized. In fact, once your vectors are normalized, you have just lost the magnitude of your speed, which isn''t very good. You can try this

Normal = Normalize(Normal);
finalspeed = initialspeed + Normal * Dot(initialspeed, Normal) * 2

Don''t normalize the initialspeed. This should work if your normal is pointing outside the paddle. However, if your code really bounces the ball back in the direction it came from, then your code for evaluating the normal might have a problem.

Cédric

Share this post


Link to post
Share on other sites
It seems the speed has to be normalised otherwise it tends to be amplified every time a collision occurs. Quite funny but not very helpful.

I am still sure that the normal is fine, it is a flat paddle at the bottom of the screen. When I print all the vertex data, including normal, to a file I get this:

normal : ( 0 , 1 , 0 )
( 52 , -88 , -10 )
( 52 , -88 , 10 )
( 82 , -88 , 10 )
( 82 , -88 , -10 )


This looks like it corresponds to the top polygon of the paddle exactly, apart from the changes due to translation.

Share this post


Link to post
Share on other sites
Let''s take a look at your code (with omnibrain''s change)

Vector3d newVector;
Vector3d hitNormal = *hit.getNormal( );
Vector3d ballMovement = *ball.getMove( );
hitNormal.normalise( );
ballMovement.normalise( );
newVector = ballMovement + hitnormal * dotProduct( -ballMovement, hitNormal ) * 2;
newVector = newVector * ballMovement.length( );
ball.setMove( newVector );

If normal = (0,1,0) and ballmovement = (3,-4,0)

hitNormal = (0,1,0)
ballmovement = Normalize(ballmovement) = (3/5, -4/5, 0)
newVector = (3/5 + 0, -4/5 + 1 * -4/5 * 2, 0) = (3/5, 4/5, 0)
newVector = newVector * 1 (since ballMovement is normalized)

Notice that newVector = (3/5, 4/5, 0) regardless of the magnitude of ballmovement. You could have chose (6, -8, 0) and still get the same results. If you insist on keeping the code as it is, then you have to store the length of ballMovement _before_ normalizing it, and multiply by that variable at the end, instead of multiplying by ballMovement.length().

Cédric

Share this post


Link to post
Share on other sites
If you are getting an amplification on reflection then your normal doesn''t have a magnitude of one. Lets use a simple case. You are bouncing off the x axis and the point of collision is the origin. Your velocity vector is (x,y) and the normal is (0,1). Your velocity vector after reflection is (x,y)-2*((0,1).(x,y))*(0,1) = (x,y)-2*y*(0,1) = (x,y)-(0,2y) = (x,y-2y)=(x,-y). Now how did your magnitude change?

Share this post


Link to post
Share on other sites
Updated code:

Vector3d newVector;
Vector3d hitNormal = *hit.getNormal( );
Vector3d ballMovement = *ball.getMove( );

hitNormal.normalise( );
ballMovement.normalise( );

newVector = (ballMovement + hitNormal) * dotProduct( -ballMovement, hitNormal ) * 2;

ball.setMove( newVector );

This is how it stand at present, the speed after collision is fine - looks the same. The problem is in the angle of reflection, it is inconsistent. Looking at it carefully, the ball reflects at an angle increasing closer to 90 degrees, parallel with the normal. Any other thoughts? I was hoping to solve this and make some significant progress today....

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!