mirror of
https://github.com/charmbracelet/harmonica.git
synced 2026-07-19 10:09:33 -06:00
Update README and example code
This commit is contained in:
parent
3250234a99
commit
87e1a9dba6
38
README.md
38
README.md
@ -23,7 +23,7 @@ const targetX = 50.0
|
||||
const targetY = 100.0
|
||||
|
||||
// Initialize a spring with framerate, angular frequency, and damping values.
|
||||
spring := harmonica.NewSpring(harmonica.FPS60, 0.8, 0.98)
|
||||
spring := harmonica.NewSpring(harmonica.FPS(60), 6.0, 0.5)
|
||||
|
||||
// Animate!
|
||||
for {
|
||||
@ -38,6 +38,42 @@ For details, see the [examples][examples] and the [docs][docs].
|
||||
[examples]: https://github.com/charmbracelet/harmonica/tree/master/examples
|
||||
[docs]: https://pkg.go.dev/github.com/charmbracelet/harmonica?tab=doc
|
||||
|
||||
## Settings
|
||||
|
||||
`NewSpring` takes three different values on initialization:
|
||||
|
||||
* **Time Delta:** the time step to operate on. Game engines typically provide
|
||||
a way to determine the time delta, however if that's not available you can
|
||||
simply set the framerate with the included `FPS(int)` utility function. Make
|
||||
the framerate you set here matches your actual framerate.
|
||||
* **Angular Velocity:** this translates roughly to the speed. Higher values are
|
||||
faster.
|
||||
* **Damping Ratio:** the springiness of the animation, generally between `0`
|
||||
and `1`, though it can go higher. Lower values are springier. For details,
|
||||
see below.
|
||||
|
||||
## Damping Ratios
|
||||
|
||||
The damping ratio affects the motion in one of three different ways depending
|
||||
on how it's set.
|
||||
|
||||
### Under-Damping
|
||||
|
||||
A spring is under-damped when its damping ratio is less than `1`. An
|
||||
under-damped spring reaches equilibrium the fastest, but overshoots and will
|
||||
continue to oscillate as its amplitude decays over time.
|
||||
|
||||
### Critical Damping
|
||||
|
||||
A spring is critically-damped the damping ratio is exactly `1`. A critically
|
||||
damped spring will reach equilibrium as fast as possible without oscillating.
|
||||
|
||||
### Over-Damping
|
||||
|
||||
A spring is over-damped the damping ratio is greater than `1`. An over-damped
|
||||
spring will never oscillate, but reaches equilibrium at a slower rate than
|
||||
a critically damped spring.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
This library is a fairly straightforward port of [Ryan Juckett][juckett]’s
|
||||
|
||||
28
harmonica.go
28
harmonica.go
@ -5,16 +5,15 @@
|
||||
// Example usage:
|
||||
//
|
||||
// // Run once to initialize.
|
||||
// spring := NewSpring(FPS(60), 0.8, 1.0)
|
||||
// spring := NewSpring(FPS(60), 6.0, 0.2)
|
||||
//
|
||||
// // Update on every frame.
|
||||
// pos := 0.0
|
||||
// targetPos := 10.0
|
||||
// targetPos := 100.0
|
||||
// velocity := 0.0
|
||||
// spring.Update(&pos, &velocity, targetPos)
|
||||
//
|
||||
// // You could also use a custom FPS with the TimeDelta helper:
|
||||
// fps := TimeDelta(time.Second/24) // 24fps
|
||||
// someUpdateLoop(func() {
|
||||
// spring.Update(&pos, &velocity, targetPos)
|
||||
// })
|
||||
//
|
||||
// For background on the algorithm see:
|
||||
// https://www.ryanjuckett.com/damped-springs/
|
||||
@ -56,7 +55,9 @@ import (
|
||||
)
|
||||
|
||||
// FPS 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.
|
||||
// value can be used as the time delta when initializing a Spring. Note that
|
||||
// game engines often provide the time delta as well, which you should use
|
||||
// instead of this function, if possible.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
@ -66,7 +67,7 @@ func FPS(n int) float64 {
|
||||
return (time.Second / time.Duration(n)).Seconds()
|
||||
}
|
||||
|
||||
// In calculus ε is (in vague terms) an arbitrarily small positive number. In
|
||||
// In calculus ε is, in vague terms, an arbitrarily small positive number. In
|
||||
// the original C++ source ε is represented as such:
|
||||
//
|
||||
// const float epsilon = 0.0001
|
||||
@ -90,11 +91,14 @@ var epsilon = math.Nextafter(1, 2) - 1
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // First precomute spring coefficients based on your settings:
|
||||
// var x, xVel, y, yVel float
|
||||
// fps := TimeDelta(time.Second/60) // or use a const like FPS60 or FPS30
|
||||
// s := NewSping(fps, 0.98, 8.0)
|
||||
// s.Update(&x, &xVel, 10) // update the X position
|
||||
// s.Update(&y, &yVel, 20) // update the Y position
|
||||
// deltaTime := FPS(60)
|
||||
// s := NewSpring(deltaTime, 5.0, 0.2)
|
||||
//
|
||||
// // Then, in your update loop:
|
||||
// s.Update(&x, &xVel, 10) // update the X position
|
||||
// s.Update(&y, &yVel, 20) // update the Y position
|
||||
//
|
||||
type Spring struct {
|
||||
posPosCoef, posVelCoef float64
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user