Sign in to follow this  
BradDaBug

Moving pendulum

Recommended Posts

BradDaBug    913
I thought this would be simpler than it has turned out to be. Imagine a string with a heavy weight at one end that's attached to the mouse cursor, and as the player moves the mouse cursor the weight at the end of the string should sway and oscilate around. Creating a simple pendulum is easy, but making the pendulum and the weight move around in response to the movement of the pendulum.... I'm not having any luck. I found this: [url="http://math.stackexchange.com/questions/3072/pendulum-with-moving-pivot"]http://math.stackexc...th-moving-pivot[/url] but that diagram doesn't look correct.That angle between A1 and A is not [eqn]a - \beta[/eqn], but rather [eqn]\pi/2 - a - \beta[/eqn] (right?).

Anyway, here is a snippet of code but it doesn't work. The bob doesn't behave at all like what I want. I call this method each frame, and the coordinates represent the mouse coordinates. I'm not using _bobAngle.Y yet, so ignore the fact that I'm not calculating it. I'm just trying to get the bob to behave correctly in 1 dimension before I work on the second.

[source lang="csharp"]private void update(float elapsedTime, int x, int y)
{
// figure out the current mouse velocity
Vector3 vel = new Vector3();
vel.X = x - _position.X;
vel.Y = 0;
vel.Z = y - _position.Z;
vel *= elapsedTime;

// compare the current velocity with the old to calculate acceleration
Vector3 acceleration = (vel - _oldVelocity) / elapsedTime;
acceleration.Y = -5.0f * elapsedTime;
_oldVelocity = vel;

float b2 = (float)Math.Atan2(acceleration.X, -acceleration.Y);
float a1 = acceleration.Length() * (float)Math.Cos(MathHelper.PiOver2 - Utils.AngleDiff(_bobAngle.X, b2)) * 1.0f;
_bobAngularVelocity.X += a1 / _springLength * elapsedTime;

// apply damping
_bobAngularVelocity -= _bobAngularVelocity * 0.01f * elapsedTime;

// apply velocity
_bobAngle.X += _bobAngularVelocity.X * elapsedTime;
_bobAngle.Y += _bobAngularVelocity.Y * elapsedTime;

_bobAngle.X = MathHelper.WrapAngle(_bobAngle.X);
_bobAngle.Y = MathHelper.WrapAngle(_bobAngle.Y);

_position.X = x;
_position.Z = y;
}

private Vector2 calcBobPosition()
{
Vector2 p = new Vector2();
p.X = _position.X + _springLength * (float)Math.Sin(_bobAngle.X);
p.Y = _position.Z + _springLength * (float)Math.Sin(_bobAngle.Y);
return p;
}
[/source]

Can anyone tell what I'm doing wrong?

Share this post


Link to post
Share on other sites
BradDaBug    913
I think that diagram may have been more confusing than helpful (plus I found at least one bug in my code). After some more work I came up with this, and it seems to work ALMOST correctly (in 2 dimensions, even), except when I really start slinging the cursor around. It seems like the pendulum bob should be held straight out by centrifugal force, but instead it kind of starts jumping around erradically until it looses some velocity and settles down.

[source lang="csharp"]private void update(float elapsedTime, int x, int y)
{
// figure out the current mouse velocity
Vector3 vel = new Vector3();
vel.X = x - _position.X;
vel.Y = 0;
vel.Z = y - _position.Z;
vel /= elapsedTime;

// compare the current velocity with the old to calculate acceleration
Vector3 acceleration = (vel - _oldVelocity) / elapsedTime;
acceleration.Y = -90000.0f * elapsedTime;
_oldVelocity = vel;

// calculate the XY plane angular velocity
float accelerationZ = acceleration.Z;
acceleration.Z = 0;

float b = (float)Math.Atan2(acceleration.Y, acceleration.X);
float a = acceleration.Length() * (float)Math.Cos(b - (_bobAngle.X - MathHelper.PiOver2));

_bobAngularVelocity.X += a / _springLength * elapsedTime;

// calculate the YZ plane angular velocity
acceleration.Z = accelerationZ;
acceleration.X = 0;
b = (float)Math.Atan2(acceleration.Y, accelerationZ);
a = acceleration.Length() * (float)Math.Cos(b - (_bobAngle.Y - MathHelper.PiOver2));

_bobAngularVelocity.Y += a / _springLength * elapsedTime;

// apply damping
_bobAngularVelocity -= _bobAngularVelocity * 2.0f * elapsedTime;

// apply velocity
_bobAngle.X += _bobAngularVelocity.X * elapsedTime;
_bobAngle.Y += _bobAngularVelocity.Y * elapsedTime;

_bobAngle.X = MathHelper.WrapAngle(_bobAngle.X);
_bobAngle.Y = MathHelper.WrapAngle(_bobAngle.Y);

_position.X = x;
_position.Z = y;
}[/source]

Share this post


Link to post
Share on other sites

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