# Moving pendulum

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

## Recommended Posts

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: http://math.stackexc...th-moving-pivot 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 on other sites
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]