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 , but rather (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?

**1**

# Moving pendulum

Started by BradDaBug, Nov 23 2012 01:05 PM

1 reply to this topic

###
#2
Members - Reputation: **912**

Posted 23 November 2012 - 05:20 PM

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]

[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]

I like the DARK layout!