A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by grassgames » Fri Oct 01, 2010 10:06 am
I'm trying to add spin to a ping pong ball with no luck so far.
I've some problems, possibly related:
1) Adding torque or omega to the ball to simulate side spin seems to have no effect on the path of the ball - I can see the ball spinning on its axis as it moves, but it moves in a straight line with no curve whatsoever.
2) Changing the ball's mass seems to make no difference to anything.
3) Not sure how to use NewtonBodySetMassMatrix() for a hollow sphere as opposed to a solid sphere.
Here's what I've got so far:
- Code: Select all
#define GRAVITY -9.81f
float ball_mass = 0.027f;
NewtonCollision *coll = NewtonCreateSphere(m_world,ball_radius,ball_radius,ball_radius,NULL);
m_ball_body = NewtonCreateBody(m_world,coll);
dVector origin,inertia;
NewtonConvexCollisionCalculateInertialMatrix(coll,&inertia[0],&origin[0]);
float Ixx,Iyy,Izz;
Ixx = ball_mass * inertia[0];
Iyy = ball_mass * inertia[1];
Izz = ball_mass * inertia[2];
// Ixx = (2.0f / 5.0f) * ball_mass * ball_radius * ball_radius * inertia[0];
// Iyy = (2.0f / 5.0f) * ball_mass * ball_radius * ball_radius * inertia[1];
// Izz = (2.0f / 5.0f) * ball_mass * ball_radius * ball_radius * inertia[2];
NewtonBodySetMassMatrix (m_ball_body, m, Ixx, Iyy, Izz);
NewtonBodySetCentreOfMass (m_ball_body, &origin[0]);
ForceAndTorqueCB():
- Code: Select all
// apply gravity
dFloat mass,Ixx,Iyy,Izz;
NewtonBodyGetMassMatrix (body,&mass,&Ixx,&Iyy,&Izz);
dVector force(0.0f,0,-mass*GRAVITY);
NewtonBodySetForce(body,&force.m_x);
// test side spin
NewtonBodyGetOmega(body,m_ball_omega);
m_ball_omega[2] += 1000.0f;
NewtonBodySetOmega(body,m_ball_omega);
Any help appreciated...
-
grassgames
-
- Posts: 8
- Joined: Sun Jul 22, 2007 6:00 pm
by Julio Jerez » Fri Oct 01, 2010 1:05 pm
if you are trying to simulatiet a ping pon ball curving when you apply spin to it, adding spin alone will not make a curved trajectory.
There is a Bernulli proccess that makes the air speed in one side of the ball go faster than the other when the ball is spinning.
the air speed changes the surface presure and the translate to a differencial force that pushes the ball sideway alone the trajectory.
It is very eassy to simulate.
Tell me if that is what you are doing I can give you some pointers.
-
Julio Jerez
- Moderator

-
- Posts: 12452
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by grassgames » Fri Oct 01, 2010 1:24 pm
Yes that sounds good if it can be done - pointers would help a lot.
-
grassgames
-
- Posts: 8
- Joined: Sun Jul 22, 2007 6:00 pm
by Julio Jerez » Fri Oct 01, 2010 2:22 pm
you can do this as a physical simulation when you need to determine physics properties of the ball and air density. or you can do it arcade but still in the spirit of the physical simulation.
But method follow the same procedure is jus the one is more detail than the hot he
Basically you have to write and force and torque call back for the ball.
-In the force do add the gravity first.
-the you get the angular and linear velocity of the ball
veloc = GetVelocity(body)
omega = GetOmega(body)
// get a vector perpendicular to the trajectory by getitng the cross between the angular
// velocity axis and the linear velocity
vector lateral =cross ( Omega, velocy)
lateral = lateral. Normalize()
// now you need a point on the surface of the ball on each side of ball trajectory
vector pointBall1 = lateral.Scale (ballRadious)
vector pointBall2 = lateral.Scale (-ballRradious)
// now you need to calculate instance velocity of that point
pointVeloc1 = (veloc + cross (omega, pointBall1)
pointVeloc2 = (veloc + cross (omega, pointBall2)
// not yo nee teh pat of teh vlocist tah is aligned with the linear velocity of the ball
velocityDir = veloc.Normalize()
pointVeloc1 = velocityDir.Scale ( pointVeloc1, velocityDir);
pointVeloc2 = velocityDir.Scale ( pointVeloc2, velocityDir);
// now the diffrencial of the air speed is the difference between the at those tow points.
differencailSpeed = pointVeloc1 - pointVeloc2
//the side forect is proportinal to teh magnotu of the fifrencil air speed squared
force =someconstant * lateral.Scale (dotProduct (differencailSpeed, differencailSpeed);
//nowo you add this force to the Ball/
bodyAddforce (body, force)
The difference between tha method son a more accurate method si that you will be sampling only the most extreme point of the surface of ball ,
for that you can simple have some fix number of points of the ball, or you can use a more Gauss or Green threrema integration but I beleive that the methdo above will do for you.
-
Julio Jerez
- Moderator

-
- Posts: 12452
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by grassgames » Fri Oct 01, 2010 3:21 pm
That's amazing, thanks very much. I don't know how you know all this stuff.

I've implemented it as following and am seeing some results but I'm not sure if I have it right, particularly the 4th and 2nd last points - can you have a quick look?
- Code: Select all
BallSetForceAndTorqueCB()
{
// add spin if needed
if (m_ball_omega_changed)
{
NewtonBodyGetOmega(body,m_ball_omega);
m_ball_omega[2] += 100;
NewtonBodySetOmega(body,m_ball_omega);
m_ball_omega_changed = 0;
}
// add the gravity first
dFloat mass,Ixx,Iyy,Izz;
NewtonBodyGetMassMatrix (body,&mass,&Ixx,&Iyy,&Izz);
dVector force(0,0,-mass*GRAVITY);
NewtonBodyAddForce(body,&force.m_x);
// get the angular and linear velocity of the ball
dVector veloc; NewtonBodyGetVelocity(body,&veloc.m_x);
dVector omega; NewtonBodyGetOmega(body,&omega.m_x);
// get a vector perpendicular to the trajectory by getting the cross between the angular velocity axis and the linear velocity
dVector lateral = omega * veloc; NormalizeVector(&lateral);
// need a point on the surface of the ball on each side of ball trajectory
dVector pointBall1 = lateral.Scale(ball_radius);
dVector pointBall2 = lateral.Scale(-ball_radius);
// calculate instance velocity of that point
dVector pointVeloc1 = (veloc + (omega * pointBall1));
dVector pointVeloc2 = (veloc + (omega * pointBall2));
// get the part of the velocity that is aligned with the linear velocity of the ball
dVector velocityDir = veloc; NormalizeVector(&velocityDir);
pointVeloc1 = velocityDir.Scale(pointVeloc1 % velocityDir);
pointVeloc2 = velocityDir.Scale(pointVeloc2 % velocityDir);
// get the differential of the air speed is the difference between the at those two points
dVector differentialSpeed = pointVeloc1 - pointVeloc2;
// the side force is proportional to the magnitude of the differential air speed squared
const float some_constant = 0.001f;
force = lateral.Scale (differentialSpeed % differentialSpeed);
force = force.Scale(some_constant);
// add this force to the Ball
NewtonBodyAddForce(body,&force.m_x);
}
-
grassgames
-
- Posts: 8
- Joined: Sun Jul 22, 2007 6:00 pm
Return to General Discussion
Who is online
Users browsing this forum: No registered users and 42 guests