struct Pendulum
{
RigidBall ball;
Line rope;
const int LEN;
float changeInAngle;
const float restAngle;
Pendulum() : LEN( 6 ), restAngle( Constants::DEGTORAD * 270 )
{
rope = Line( Vector3D( 0.0f,-LEN,0.0f) );
rope.setWhiteColor();
ball = RigidBall(1,1,0.0f,-LEN,0.0f);
ball.setYellowColor();
ball.setMass( 1.0f );
changeInAngle = 75 * Constants::DEGTORAD;
ball.posVec = Vector3D( LEN * cos( ( restAngle + changeInAngle ) ),
LEN * sin( ( restAngle + changeInAngle ) ),
0.0f);
}
void calculate(float deltaTime)
{
static const float EXTRA_FORCE = 5;
static float g = Constants::GRAVITY / LEN * EXTRA_FORCE;
//F = mg*sin(theta) = ma;
//a = F/ m
//a = mgsin(theta) / m
//a = g*sin(theta)
ball.accelVec = Vector3D( 0.0f, g * sin( changeInAngle ) , 0.0f );
//V = v_0 + a*t
ball.velVec += ball.accelVec * deltaTime;
// X = v*dt + 1/2 a*dt^2
ball.posVec += ball.velVec * deltaTime;// + 1.0f/2.0f * ball.accelVec * deltaTime * deltaTime;
changeInAngle = atan2( ball.posVec.getY(), ball.posVec.getX() ) - restAngle;
rope.setEndPoint( ball.posVec );
}
void draw(float deltaTime)
{
calculate(deltaTime);
rope.draw();
ball.draw();
//draw axis
glBegin(GL_LINES);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f(-7.0f,0.0f,0.0f);
glVertex3f(7.0f,0.0f,0.0f);
glVertex3f(0.0f,-7.0f,0.0f);
glVertex3f(0.0f,7.0f,0.0f);
glEnd();
}
}pendulum;
Simulating pendulum movement
I know there is something wrong here. I am trying to simulate a simple pendulum
by am failing.
Here is the relevancy.
I know some logic is wrong. Can you help ? When I run it the pendulum does
not oscillate towards the x = 0 line. It just decays down the y-axis. after a
few millisecond.
[Edited by - Concentrate on December 25, 2009 10:23:42 PM]
I though my calculation was correct but apparently not.
Can someone check my calculation.
restAngle is 270 degrees in radians.
Can someone check my calculation.
void calculate(float deltaTime) { static const float EXTRA_FORCE = 5; static float g = Constants::GRAVITY / LEN * EXTRA_FORCE; //F = mg*sin(theta) = ma; //a = F/ m //a = mgsin(theta) / m //a = g*sin(theta) ball.accelVec = Vector3D( g * sin( changeInAngle ) ,g * cos(changeInAngle) , 0.0f ); //V = v_0 + a*t ball.velVec += ball.accelVec * deltaTime; // X = v*dt + 1/2 a*dt^2 ball.posVec += ball.velVec * deltaTime;// + 1.0f/2.0f * ball.accelVec * deltaTime * deltaTime; changeInAngle = atan2( ball.posVec.getY(), ball.posVec.getX() ) - restAngle; rope.setEndPoint( ball.posVec ); }
restAngle is 270 degrees in radians.
It appears that you're calculating the force on the ball based on a change in angle.
The force on the ball due to gravity will be a constant m*g in the vertical direction, whatever the position of the ball. The acceleration vector will be (0,-m*g,0), and the change in velocity accelVec*deltaSecs, if the Y axis is pointing up.
The force on the ball due to gravity will be a constant m*g in the vertical direction, whatever the position of the ball. The acceleration vector will be (0,-m*g,0), and the change in velocity accelVec*deltaSecs, if the Y axis is pointing up.
>>It appears that you're calculating the force on the ball based on a change in angle.
Yes.
>>The force on the ball due to gravity will be a constant m*g in the vertical direction, whatever the position of the ball. The acceleration vector will be (0,-m*g,0), and the change in velocity accelVec*deltaSecs, if the Y axis is pointing up.
Thanks. How will I account, for the horizontal force then ?
Yes.
>>The force on the ball due to gravity will be a constant m*g in the vertical direction, whatever the position of the ball. The acceleration vector will be (0,-m*g,0), and the change in velocity accelVec*deltaSecs, if the Y axis is pointing up.
Thanks. How will I account, for the horizontal force then ?
The horizontal force comes from the rope. You're probably simulating it as a straight rod (which is simplest).
Divide the vertical force (m*g*deltaSecs) into a force along the direction of the rope and a force normal to the rope, according to the angle the rope makes with the vertical. The force along the direction of the rope will be cancelled by the force of the rope on the ball. The normal force (perpendicular to the rope) will cause acceleration normal to the rope.
Divide the vertical force (m*g*deltaSecs) into a force along the direction of the rope and a force normal to the rope, according to the angle the rope makes with the vertical. The force along the direction of the rope will be cancelled by the force of the rope on the ball. The normal force (perpendicular to the rope) will cause acceleration normal to the rope.
Quote:Original post by Buckeye
The horizontal force comes from the rope. You're probably simulating it as a straight rod (which is simplest).
Divide the vertical force (m*g*deltaSecs) into a force along the direction of the rope and a force normal to the rope, according to the angle the rope makes with the vertical. The force along the direction of the rope will be cancelled by the force of the rope on the ball. The normal force (perpendicular to the rope) will cause acceleration normal to the rope.
Is that tangential force
mg*sin(theta)?
If, by "tangential," you mean perpendicular to the direction of the rope, then yes. And if your "theta" is the angle of the rope with respect to the Y axis, Y pointing down, then that force would be m*g*sin(theta).
Make sure you apply the sign of the angle correctly - the force will always tend to swing the ball back toward that Y axis.
Make sure you apply the sign of the angle correctly - the force will always tend to swing the ball back toward that Y axis.
Sorry for the late response.
I think my calculations are correct but the result shows otherwise. I am trying
what you said, but its acting weird.
This is what I have now :
Here is whats happening ,
I think my calculations are correct but the result shows otherwise. I am trying
what you said, but its acting weird.
This is what I have now :
void calculate(float deltaTime) { static const float EXTRA_FORCE = 10; static float g = Constants::GRAVITY / LEN * EXTRA_FORCE; //F = mg*sin(theta) = ma; //a = F/ m //a = mgsin(theta) / m //a = g*sin(theta) ball.forceVec = Vector3D( ball.getMass() * g * sin(changeInAngle) , ball.getMass() * g , 0.0f); ball.accelVec = ball.forceVec/ ball.getMass(); //V = v_0 + a*t ball.velVec += ball.accelVec * deltaTime; // X = v*dt + 1/2 a*dt^2 ball.posVec += ball.velVec * deltaTime + 1.0f/2.0f * ball.accelVec * deltaTime * deltaTime; changeInAngle = atan2( ball.posVec.getY(), ball.posVec.getX() ) - restAngle; rope.setEndPoint( ball.posVec ); }
Here is whats happening ,
Maybe this picture will help. In this picture, theta is the angle between the Y-axis and the rope.
mg points down along the Y-axis (always). The tangential force [mg sin(theta)] is not opposed and is what causes the acceleration. The force on the ball from the rope can only be along the direction of the rope and is always equal to mg*cos(theta).
Divide the rope force into x- and y-components (shown on the right):
x-force = -mg cos(theta) sin(theta)
y-force = -mg cos(theta) cos(theta)
At an angle theta, the force on the ball is:
Vector3D( -m*g*cos(theta)*sin(theta), m*g - (-m*g*cos(theta)*cos(theta)), 0);
The Y component = mg + (1-cos^2(theta)). 1-cos^2 = sin^2, so:
force = Vector3D( -m*g*cos(theta)*sin(theta), m*g*sin(theta)*sin(theta), 0);
Testing some values-
When the ball is hanging straight down, theta = 0 and force = (0,0,0). That is, there is no tangential force and the rope supports the ball. The velocity is not affected.
When the ball is straight out to the right, theta = pi/2 and force = (0, mg, 0). Gravity is pulling straight down on the ball and acceleration is maximum.
Thanks for the explanation. Shouldn't the second triangle (the one on the right of your picture) be the same as the first one ( the one on the left of your picture) because I thought they should be similar triangles?
I must be doing something wrong because I adjusted the force from your derivation
and its similar to what I had in the youtube video (plus/minus).
This is what I have for the current definition,
I don't think its any problem with my display function because I do not
manipluate anything except the time in there.
I must be doing something wrong because I adjusted the force from your derivation
and its similar to what I had in the youtube video (plus/minus).
This is what I have for the current definition,
struct Pendulum{ RigidBall ball; Line rope; const int LEN; float changeInAngle; const float restAngle; Pendulum() : LEN( 6 ), restAngle( Constants::DEGTORAD * 270 ) { rope = Line( Vector3D( 0.0f,-LEN,0.0f) ); rope.setWhiteColor(); ball = RigidBall(1,1,0.0f,-LEN,0.0f); ball.setYellowColor(); ball.setMass( 1.0f ); changeInAngle = 75 * Constants::DEGTORAD; ball.posVec = Vector3D( LEN * cos( ( restAngle + changeInAngle ) ), LEN * sin( ( restAngle + changeInAngle ) ), 0.0f); } void calculate(float deltaTime) { static const float EXTRA_FORCE = 10; static float g = Constants::GRAVITY / LEN * EXTRA_FORCE; static float m = ball.getMass(); float theta = changeInAngle; //F = mg*sin(theta) = ma; //a = F/ m //a = mgsin(theta) / m //a = g*sin(theta) ball.forceVec = Vector3D( -m*g*cos(theta)*sin(theta), m*g*sin(theta)*sin(theta), 0); ball.accelVec = ball.forceVec/ ball.getMass(); //V = v_0 + a*t ball.velVec += ball.accelVec * deltaTime; // X = v*dt + 1/2 a*dt^2 ball.posVec += ball.velVec * deltaTime + 1.0f/2.0f * ball.accelVec * deltaTime * deltaTime; changeInAngle = atan2( ball.posVec.getY(), ball.posVec.getX() ) - restAngle; rope.setEndPoint( ball.posVec ); } void draw(float deltaTime) { calculate(deltaTime); rope.draw(); ball.draw(); }}pendulum;
I don't think its any problem with my display function because I do not
manipluate anything except the time in there.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement