Class: Charming::Spring

Inherits:
Object
  • Object
show all
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

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.

Returns:

  • (Boolean)


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