Hello, i'm playing with 2D physics. I've got this object i want to oscillate. I decided that the motion of a spring would be ideal for representing this oscilation. The object is at maximum velocity at the spring's resting point ® and gradually decelerates until at some distance (D) the object stops and starts going the other way. I want to maintain the distance D so it oscillates forever.
I'm using velocity-verlet integration, i've tried a few things and my object doesn't want to adhere to that stopping distance D.The theoretical spring constant k=1 where it should be stable, instead means it skyrockets out of control, anything less means it does so faster, any more and it eventually comes to rest. I tried adding a small damping force to it but this also makes it stop.
I'm not altogether surprised, and am pretty sure I need to fake-it. What I am thinking of doing is waiting for the object to get close to R, and if the velocity exceeds the desired speed, i'll correct it. I could also wait for the object to get to D and zero the velocity out. Is there any best solution to this or can i just kinda pick one at my leisure?
Stable Spring Physics
Started by SmokingRope, Dec 10 2008 06:07 PM
4 replies to this topic
#1
Posted 10 December 2008 - 06:07 PM
#2
Posted 10 December 2008 - 08:09 PM
What's wrong with a simple harmonic oscillator?
x(t) = A cos(sqrt(k/m) * t)
where A is the initial displacement, k is your spring constant, m is the mass and t is time.
x(t) = A cos(sqrt(k/m) * t)
where A is the initial displacement, k is your spring constant, m is the mass and t is time.
#3
Posted 11 December 2008 - 01:28 AM
I've tried to adhere to a strict component-based design. Presently i just have my verlet physics component. I can probably extract the interface and make the simple harmonic oscillator fit nicely.
My project includes more than just oscillating springs, and i hadn't even considered breaking out of my physics system! :lol:
My project includes more than just oscillating springs, and i hadn't even considered breaking out of my physics system! :lol:
#4
Posted 11 December 2008 - 02:21 PM
From my unexperienced and peripheral understanding, you should be able to get Verlet to work. Dampening is not what you want, as this simply is a force that slowly forces the system back to equilibrium. Rather, you need to impose constraints, which usually involves correcting for position.
Another good place for this would be GameDev's physics forum. I've seen lots of spring system discussions there, including Verlet/Euler/RK stuff...
Another good place for this would be GameDev's physics forum. I've seen lots of spring system discussions there, including Verlet/Euler/RK stuff...
#5
Posted 11 December 2008 - 11:11 PM
I haven't searched Gamedev specifically, but my understanding is that there is no cure-all for instability with spring forces.
The reason springs are unstable is because the fixed time step means that sometimes things overshoot.
I went ahead and wrote a generic solution that manually recalculates the velocity as it passes over the spring's resting point. This works.
my spring is oscilating on the X-axis (mass and the spring constant are also one) so this is an overly complicated solution, but the idea is:
don't touch the component of the velocity that is perpendicular to the spring force
make the component that is tangent to the spring force have the expected value.
The only problem here is if my oscillating object overshoots too much when it passes the center.
The reason springs are unstable is because the fixed time step means that sometimes things overshoot.
I went ahead and wrote a generic solution that manually recalculates the velocity as it passes over the spring's resting point. This works.
PositionComponent *l_pos = (PositionComponent*)component(GameObject::CID_POSITION);
PhysicsComponent *l_phys = (PhysicsComponent*)component(GameObject::CID_PHYSICS);
const float g_SpringConstant = 1.0f;
const float g_Mass = 1.0f;
const float g_Distance = 32.0f;
Vector2 l_tangent, l_perp;
l_tangent = l_pos->get() - m_Center;
if( l_tangent.Length2() < 1.0f )
{
l_perp = l_tangent;
l_perp.Perp();
l_perp.Normalize();
float l_dist = l_tangent.Magnitude();
l_tangent.Normalize(l_dist);
l_dist = sqrt((g_Distance - l_dist)*(g_Distance - l_dist)*g_SpringConstant/g_Mass);
l_perp = l_perp.Dot(l_phys->velocity()) * l_perp;
l_tangent = l_tangent.Dot(l_phys->velocity()) * l_tangent;
l_tangent.Normalize();
l_phys->setVelocity(l_perp + l_tangent * l_dist);
}
my spring is oscilating on the X-axis (mass and the spring constant are also one) so this is an overly complicated solution, but the idea is:
don't touch the component of the velocity that is perpendicular to the spring force
make the component that is tangent to the spring force have the expected value.
The only problem here is if my oscillating object overshoots too much when it passes the center.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users












