Class: Charming::Spring
- Inherits:
-
Object
- Object
- Charming::Spring
- Defined in:
- lib/charming/spring.rb
Overview
Spring is a damped harmonic oscillator for physics-based animation. It precomputes motion coefficients for a fixed time step so each frame update is four multiply-adds. Instances are immutable; the caller owns position and velocity (typically as Float attributes on an ApplicationState) and feeds them back in every frame:
SPRING = Charming::Spring.new(delta_time: Charming.fps(60))
position, velocity = SPRING.update(position, velocity, target)
The damping ratio shapes the motion: below 1 overshoots and oscillates, exactly 1 reaches the target as fast as possible without overshooting, above 1 approaches slower still. Angular frequency scales the speed.
Instance Method Summary collapse
-
#initialize(delta_time:, angular_frequency: 6.0, damping_ratio: 0.5) ⇒ Spring
constructor
A new instance of Spring.
-
#settled?(position, velocity, target, epsilon: 0.01) ⇒ Boolean
True once the motion has effectively come to rest at target — the guard for stopping an animation timer.
-
#update(position, velocity, target) ⇒ Object
Advances one frame toward target, returning
[new_position, new_velocity].
Constructor Details
#initialize(delta_time:, angular_frequency: 6.0, damping_ratio: 0.5) ⇒ Spring
Returns a new instance of Spring.
49 50 51 52 53 54 55 |
# File 'lib/charming/spring.rb', line 49 def initialize(delta_time:, angular_frequency: 6.0, damping_ratio: 0.5) angular_frequency = [0.0, angular_frequency].max damping_ratio = [0.0, damping_ratio].max @pos_pos, @pos_vel, @vel_pos, @vel_vel = coefficients(delta_time, angular_frequency, damping_ratio) freeze end |
Instance Method Details
#settled?(position, velocity, target, epsilon: 0.01) ⇒ Boolean
True once the motion has effectively come to rest at target — the guard for stopping an animation timer.
66 67 68 |
# File 'lib/charming/spring.rb', line 66 def settled?(position, velocity, target, epsilon: 0.01) (position - target).abs < epsilon && velocity.abs < epsilon end |
#update(position, velocity, target) ⇒ Object
Advances one frame toward target, returning [new_position, new_velocity].
58 59 60 61 62 |
# File 'lib/charming/spring.rb', line 58 def update(position, velocity, target) relative = position - target [relative * @pos_pos + velocity * @pos_vel + target, relative * @vel_pos + velocity * @vel_vel] end |