module

Harmonica

This file defines a simplified damped harmonic oscillator, colloquially known as a spring. This is ported from Ryan Juckett’s simple damped harmonic motion, originally written in C++.

Example usage:

# Run once to initialize.
spring = Harmonica::Spring.new(Harmonica.fps(60), 6.0, 0.2)

# Update on every frame.
pos = 0.0
velocity = 0.0
target_pos = 100.0
pos, velocity = spring.update(pos, velocity, target_pos)

For background on the algorithm see: https://www.ryanjuckett.com/damped-springs/

Copyright (c) 2008-2012 Ryan Juckett Ported to Go by Charmbracelet, Inc. in 2021. Ported to Crystal by Dominic Sisneros in 2025.

Constants

Gravity = Vector.new(0, -9.81, 0)

Gravity is a utility vector that represents gravity in 2D and 3D contexts, assuming that your coordinate plane looks like in 2D or 3D:

y y ±z │ │ / │ │/ └───── ±x └───── ±x

(i.e. origin is located in the bottom-left corner)

TerminalGravity = Vector.new(0, 9.81, 0)

TerminalGravity is a utility vector that represents gravity where the coordinate plane's origin is on the top-right corner.

VERSION = "0.1.0"

Class methods

fps(n : Int) : Float64

Returns a time delta for a given number of frames per second.

This value can be used as the time delta when initializing a Spring. Game engines often provide the time delta as well, which you should use instead of this function, if possible.

spring = Spring.new(fps(60), 5.0, 0.2)
Source

Nested types