I recently visited the SpringConstraint documentation, because it had a very helpful equation that told me how the force to apply between its Attachments was calculated. I recently discovered that it was removed from the page.
It’s not on the Wayback Machine, I’ve checked. I’ve searched the forum and nobody seems to have noticed that it’s gone, and it’s not posted anywhere as far as I can tell. I would like for the equation to be put back on the SpringConstraint page if that’s possible.
Hm. I’m asking internally to see what this page used to look like.
That being said, what kind of equations are you looking for? Maybe I can help out in the meantime?
Force = Stiffness * distanceFromFreeLength
Critical Damping is the configuration where the spring returns to free length the fastest and doesn’t overshoot. The equation for Critical Damping is
Damping = 2 * sqrt(Stiffness * mass)
You have to consider mass being a non trivial value when dealing with a complicated mechanism. For example, if you wanted to make car suspensions critically damped you would use massOfCar/N for the N number of wheels (assuming mass distribution is even).
A lot of useful stuff can be found by googling “Damped Harmonic Oscillator” which is a physicsy way of saying “Spring”.
The SpringConstraint doc page used to have some equation that went along the lines of math.abs((attachment1.Position - attachment0.Position).Magnitude - springConstraint.FreeLength) * springConstraint.Stiffness - (attachment1.Velocity - attachment2.Velocity):dot(whatever) * springConstraint.Damping
I really don’t remember it, I hope this gives you an idea of what was there, because I can’t find it anywhere.
I’ve talked to the team in charge of Dev Hub and they will add more info on there. For now here is a place that has the script (it is under the spring constraint). I’ll also paste the function here.
local function getSpringForce( spring )
if not (spring:IsA("SpringConstraint")) then
print("Error: Not a spring constraint")
return
end
local currentLength = spring.CurrentLength
local freeLength = spring.FreeLength
if (spring.LimitsEnabled) then
currentLength = math.clamp( currentLength, spring.MinLength, spring.MaxLength )
freeLength = math.clamp( freeLength, spring.MinLength, spring.MaxLength )
end
local springLength = currentLength - freeLength
local axis = spring.Attachment0.WorldPosition - spring.Attachment1.WorldPosition
if (axis.Magnitude > 0) then
axis = axis.Unit
end
local effectiveVelocity = spring.Attachment0.Parent.Velocity - spring.Attachment1.Parent.Velocity
-- https://en.wikipedia.org/wiki/Harmonic_oscillator
-- f = k * x - c * dx/dt + fext
local forceExternal = Vector3.new(0, -workspace.Gravity, 0) -- Gravity may not be all the external forces. Friction may affect this, but its harder to account for.
local force = -spring.Stiffness * springLength - spring.Damping * axis:Dot(effectiveVelocity) + axis:Dot(forceExternal)
force = math.clamp(force, -spring.MaxForce, spring.MaxForce)
return force
end