Sign in to follow this  

Getting the ball rolling

This topic is 2817 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

Hello, I'm working on a pool game currently and having trouble figuring out how to get the ball rolling correctly. According to resources on the internet, when the ball is hit straight on without any english, the ball slides initially and begins to roll due to the friction from the table. The ball is in natural roll when v = wr, where v is the velocity at the center of mass, w is the angular velocity, and r is the radius of the ball. My issue is, when I apply friction to the ball F=uN to induce the roll, I apply a torque to initiate the roll and also apply the same force to the linear velocity. At low speeds, the friction acting on the linear velocity may eventually cause it to go in the opposite direction before it can detect the natural roll state! Am I incorrectly applying the forces of friction on the ball in the sliding state? here is my update method for the ball:
override public function update( et : Number ) : void
{
	var gravity : Number = World.GRAVITY;
	
	// -- add forces due to friction
	//var frictionForce : Vector3D = velocity.clone();
	//frictionForce.normalize();
	
	var mu : Number;
	var contactVec : Vector3D;
	var vp : Vector3D;
	var friction : Vector3D;
	
	if ( bodyState == STATE_SLIDING )
	{
		// -- find the velocity at a point on the surface of the ball
		contactVec = new Vector3D( 0.0, 0.0, radius );	
		//vp = contactVec.crossProduct( angularVelocity );
		vp = new Vector3D();
		vp.incrementBy( velocity );
		vp.normalize();
		
		// -- friction is a vector in the opposite direction of the velocity
		vp.scaleBy( -MU_SLIDE * gravity * mass );
		addForce( vp, contactVec );
	}
	else if ( bodyState == STATE_ROLLING )
	{
		// -- apply rolling resistence as torque
		contactVec = new Vector3D( 0.0, 0.0, radius );	
		vp = contactVec.crossProduct( angularVelocity );
		vp.normalize();
	
		vp.scaleBy( MU_ROLL * gravity * mass );
		addTorque( contactVec.crossProduct( vp ) );
	}
}



And here is my method for integrating forces on the object
public function integrateForces( et : Number ) : void
{
	torque.scaleBy( invInertia * et );
	angularVelocity.incrementBy( torque );
	
	var threshold : Number = 0.0001;
	
	if ( bodyState == STATE_ROLLING )
	{
		var cp : Vector3D = new Vector3D( 0, 0, radius );
		var av : Vector3D = cp.crossProduct( angularVelocity );
		
		velocity.x = av.x;
		velocity.y = av.y;
		velocity.z = av.z;
	}
	else if ( bodyState == STATE_SLIDING )
	{
		force.scaleBy( invMass * et );
		velocity.incrementBy( force );
		
		// -- check if i'm rolling
		var contact : Vector3D = new Vector3D( 0, 0, radius );
		var rw : Vector3D = contact.crossProduct( angularVelocity );
		var dotp : Number = rw.dotProduct( velocity );
		var diff : Number = rw.subtract( velocity ).length;
		
		if ( dotp && diff < 0.05 )
		{
			bodyState = STATE_ROLLING;
			trace( "rolling" );
			
			velocity.x = rw.x;
			velocity.y = rw.y;
			velocity.z = rw.z;
		}
	}
	
	// -- check if i'm coming to a stop
	var velSquared : Number = velocity.lengthSquared;
	var angSquared : Number = angularVelocity.lengthSquared;
	
	if ( velSquared < threshold && angSquared < threshold )
	{
		bodyState = STATE_REST;
		
		velocity.x = 0;
		velocity.y = 0;
		velocity.z = 0;
		
		angularVelocity.x = 0;
		angularVelocity.y = 0;
		angularVelocity.z = 0;
	}
	
	force.x = 0;
	force.y = 0;
	force.z = 0;
	
	torque.x = 0;
	torque.y = 0;
	torque.z = 0;
}



Share this post


Link to post
Share on other sites
Another question I have is when the ball is actually in the rolling state, I change the linear velocity based on the relationship of v=wr. Is that the correct way of doing it or is there another way?

Share this post


Link to post
Share on other sites
Well, unfortunately I can't help you directly with your problem but I can tell you that games are about the appearance of being correct, not about actually BEING correct.

So, unless you trying to do it as realistically as possible for a reason, I say fudge it so that it looks like you want, and call it good :P

If you are wanting to be a purist though, I would say that I don't think real physics is made up of state machines. Sliding and rolling balls don't magically have different forces applied to them, the issue is just whether or not the speed is greater than some maximum threshold needed for the felt of the table to cause the right kind of friction?

I'm not that much of a physics guy but hopefully you smell what I'm cooking

Share this post


Link to post
Share on other sites
It is a complicated issue. As Atrix said, you have to cook the Results a bit.
The simplest Model is start rolling bellow a certain Speed.
If you want to know some Theory about Ball rolling I recommend that you look for a specialized Book, about the Physics of Billiards, or any Sport that uses a Ball. For example the way a Tennis Ball starts rolling will be similar to Billiards.

Share this post


Link to post
Share on other sites
I'm not great with friction yet, so I'm probably no help but a few thoughts came to me. Should you be applying torque on the ball? I would assume not, only LV, or better yet a force, which would induce an acceleration. The friction model should create the torque for you as the cueball slows.

Share this post


Link to post
Share on other sites
Burnt_Fyr that Document is very good indeed.
Most Articles about pool have an abrupt transition between sliping and rolling, with which I don't agree. A ball should not instantaneously go from Kinetic Friction to Rolling Friction, without going through some intermediate state of half Friction half rolling.
This document makes a much better Analysis.

Share this post


Link to post
Share on other sites
Thanks for the replies, I figured out my problems. As for sliding vs rolling, once the angular velocity of the ball matches the linear velocity, the point where the ball is in contact with the ground, the relative velocity is zero. Therefore the ball is technically at rest so there is no friction.

To account for slipping from the ball sliding + the ball spinning during my "slide" state, I calculate the velocity at the point of contact which is the sum of the velocity at the center of mass and the radius x angular velocity. I find my friction from that velocity and apply it to the center of mass and also as a torque.


if ( bodyState == STATE_SLIDING )
{
// -- find the velocity at a point on the surface of the ball
contactVec = new Vector3D( 0.0, 0.0, radius );
vp = angularVelocity.crossProduct( contactVec );
vp.incrementBy( velocity );
vp.normalize();

// -- friction is a vector in the opposite direction of the velocity
vp.scaleBy( -MU_SLIDE * gravity * mass );
addForce( vp, contactVec );
}




as for my addForce method, it applies a force to the center of mass as well as a torque based off a point from the cm

public function addForce( af : Vector3D, point : Vector3D ) : void
{
atRest = false;
force.incrementBy( af );
torque.incrementBy( point.crossProduct( af ) );
}




I tried my code with top spin and back spin and the results look good.

Here is a link to my project as a swf. Click anywhere in the swf to shoot the ball. Currently, it's hard coded to add backspin at the hit.

http://megaswf.com/view/215cfff8869689bdfaa557a1df99ab53.html

Share this post


Link to post
Share on other sites

This topic is 2817 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this