private void UpdateVelocity(double timeStep) { var deltaPosition = ProjectedCenter - Position; var newVelocity = Velocity + timeStep * RestoringCoefficient * deltaPosition; newVelocity += Vector3D.ComponentMult(-Velocity.ComponentSign(), Vector3D.ComponentMin(Velocity.ComponentAbs(), FrictionVector)); var maxVelocity = 3.0 / 2 / timeStep * deltaPosition.ComponentAbs(); //P + ts * V - PC <= 1/2 (PC - P) -> V <= 3/(2ts) (PC - P) Velocity = Vector3D.ComponentMin(maxVelocity, Vector3D.ComponentMax(-maxVelocity, newVelocity)); //so it eventually converges Velocity = Vector3D.ComponentMin(MaxVelocityVector, Vector3D.ComponentMax(newVelocity, -MaxVelocityVector)); //so it's not too fast }