traer

package module
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 24, 2026 License: MIT, Unlicense Imports: 3 Imported by: 0

README

traer

Simple particle system physics engine for Go

Documentation

Overview

Package traer provides a simple particle system physics engine for Go. Designed to be application / domain agnostic. All this is supposed to do is let you make particles, apply forces and calculate the positions of particles over time in real-time. Anything else you need to handle yourself.

There are four parts

ParticleSystem - takes care of gravity, drag, making particles, applying forces and advancing the simulation
Particles - they move around in 3D space based on forces you've applied to them
Springs - they act on two particles
Attractions - which also act on two particles

Acknowledgement

This package is a port of the processing library TRAER.PHYSICIS 3.0

For the orginal library see http://murderandcreate.com/physics/

Index

Constants

View Source
const (
	DEFAULT_MASS = 1

	// DEFAULT_GRAVITY is no gravity.
	DEFAULT_GRAVITY = 0

	DEFAULT_DRAG = 0.001
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Attraction

type Attraction struct {
	A *Particle
	B *Particle

	// Strength, the G in the formula G*m1*m2/d^2
	Strength float64
	// Minimum Distance, the force does not get stronger closer than this.
	// The value is stored squared as that is needed for applying attractions.
	MinimumDistanceSquared float64

	On bool
}

Attraction or repulsion (negative attraction) acts on 2 particles and either constantly pulls them together or constantly pushes them apart by applying a force to each particle:

G*m1*m2/d^2

Because in the formula the d (distance between A,B) is squared, the force is much stronger close up than far away.

func (*Attraction) SetMinimumDistance

func (a *Attraction) SetMinimumDistance(minimumDistance float64)

SetMinimumDistance will square the minimumDistance argument and set the MinimumDistanceSquared field of the attraction.

func (*Attraction) TurnOff

func (a *Attraction) TurnOff()

TurnOff is shorthand for setting the On field of the attraction to false.

func (*Attraction) TurnOn

func (a *Attraction) TurnOn()

TurnOn is shorthand for setting the On field of the attraction to true.

type FPS

type FPS struct {
	Value float64
	// contains filtered or unexported fields
}

func (FPS) String

func (f FPS) String() string

func (*FPS) Tick

func (f *FPS) Tick() *FPS

type IntegrationStep

type IntegrationStep func(t float64) float64

IntegrationStep is the interface common to all integration algorithms. The return value for the function is a measure of how much speed is still in particles the system.

func MakeDefaultVerletIntegrator

func MakeDefaultVerletIntegrator(ps *ParticleSystem) IntegrationStep

MakeDefaultVerletIntegrator creates an integrator that performs the following calculation for every particle p that is no fixed.

a := p.Force.Scale(1.0 / p.Mass)
position := p.Position.Add(p.Velocity.Scale(1.0 / t)).Add(a.Scale(1.0 / (t * t))
p.Velocity = position.Subtract(p.Position).Scale(t)
p.Position = position

func MakeVelocityVerletIntegrator

func MakeVelocityVerletIntegrator(ps *ParticleSystem) IntegrationStep

MakeVelocityVerletIntegrator creates an integrator that performs the following calculation for every particle p that is no fixed.

a := p.Force.Scale(1.0 / p.Mass)
p.Position.AddAssign(p.Velocity.Scale(1.0 / t))
p.Position.AddAssign(a.Scale(1.0 / (2.0*t*t)))
p.Velocity.AddAssign(a.Scale(1.0 / t))

type Particle

type Particle struct {
	Position Vec3
	Velocity Vec3
	Force    Vec3
	Mass     float64

	Fixed bool
}

type ParticleSystem

type ParticleSystem struct {
	Particles   []*Particle
	Springs     []*Spring
	Attractions []*Attraction

	// Gravity contains the strength of gravity, down (in the positive y
	// direction) or in whatever 3D direction you feel like. You probably want
	// the magnitude of this to be in the range of 0-5.
	Gravity Vec3
	// Drag is the drag force that acts on all objects equally, and proportional
	// to velocity.
	Drag float64

	// Step holds a Velocity Verlet integration step function by default. This
	// implementation is practically identical to the Modified Euler integrator
	// from Traer Physics 3.0 but has bug-fixes to the algorithm.
	Step IntegrationStep
}

ParticleSystem is in charge of everything. It makes particles and forces for you and you tell it to advance the simulation using Tick().

func MakeDefaultParticleSystem

func MakeDefaultParticleSystem() *ParticleSystem

Construct a new particle system with DEFAULT_GRAVITY (0) and DEFAULT_DRAG (0.001).

func MakeParticleSystem

func MakeParticleSystem(g, drag float64) *ParticleSystem

MakeParticleSystem constructs a new particle system with some downward (positive y) or 3D gravity and some drag. You can make as many of these as you'd like as long as forces from one system don't refer to particles from another. I don't know what would happen if you connected particles from one system to another.

func (*ParticleSystem) ApplyForces

func (ps *ParticleSystem) ApplyForces()

ApplyForces wil apply gravity, drag, spring and attraction forces to particles

func (*ParticleSystem) Clear

func (ps *ParticleSystem) Clear()

Clear deletes all the particles and all the forces in the system (except the omnipresent gravity and drag even if ther are 0).

func (*ParticleSystem) MakeAttraction

func (ps *ParticleSystem) MakeAttraction(a, b *Particle, strength, minimumDistance float64) *Attraction

MakeAttraction makes an attraction (or repulsion) force between two particles. If the strength is negative they repel each other, if the strength is positive they attract. There is also a minimum distance that limits how strong this force can get close up.

func (*ParticleSystem) MakeDefaultParticle

func (ps *ParticleSystem) MakeDefaultParticle() *Particle

MakeDefaultParticle creates a new particle in the system with mass 1.0 at x, y, z position (0, 0, 0).

func (*ParticleSystem) MakeParticle

func (ps *ParticleSystem) MakeParticle(mass, x, y, z float64) *Particle

MakeParticle creates a new particle in the system with some mass and at some x, y, z position.

func (*ParticleSystem) MakeSpring

func (ps *ParticleSystem) MakeSpring(a, b *Particle, strength, damping, restLength float64) *Spring

MakeSpring makes a spring in the system between 2 particles you have previously created.

strength -  A strong spring acts like a stick. A weak one takes a
  long time to return to its rest length.
damping - A spring with high damping doesn't overshoot and settles
   down quickly, while a low damping spring oscillates.
restLength - A spring wants to be at this length and acts on the
    particles to push or pull them exactly this far apart at all times.

func (*ParticleSystem) Tick

func (ps *ParticleSystem) Tick(t float64) float64

Tick advances the simulation by a 1/t seconds (t is the argument to Tick). By default use a t of 1.0 indicating a simulation duration of a second for that Tick call. Increase t to a higher value in order to make the simulation run SLOWER, as a higher t will lead to a lower 1/t value forcing the simulation to run smaller time increments for every call to Tick.

Note that target framerate in TraerAS3 was 31fps and it used Tick(1). We usually get 60fps so we can double the step size and by doing so splitting the step time in half.

type Spring

type Spring struct {
	A *Particle
	B *Particle

	// Strength, when high makes a spring strong and act like a stick. When
	// set low, will make a spring weak, causing it to take a long time to
	// return to its rest length (see below).
	Strength float64
	// Damping, when set high will prevent the spring from overshooting and
	// cause it to settle down quickly. When set low, a spring oscillates.
	Damping float64
	// Rest Length is the length the spring wants to be at. It acts on the
	// particles to push or pull them exactly this far apart at all times.
	RestLength float64

	On bool
}

Spring connects 2 particles A,B and tries to keep them a certain distance apart.

A spring has 3 properties Strength, Damping and RestLength that determine its behavior.

func (*Spring) TurnOff

func (s *Spring) TurnOff()

TurnOff is shorthand for setting the On field of the spring to false.

func (*Spring) TurnOn

func (s *Spring) TurnOn()

TurnOn is shorthand for setting the On field of the spring to true.

type Vec3

type Vec3 struct {
	X, Y, Z float64
}

func (Vec3) Add

func (v Vec3) Add(a Vec3) Vec3

func (*Vec3) AddAssign

func (v *Vec3) AddAssign(a Vec3)

func (Vec3) Dot

func (v Vec3) Dot(a Vec3) float64

func (Vec3) Length

func (v Vec3) Length() float64

func (Vec3) LengthSquared

func (v Vec3) LengthSquared() float64

func (Vec3) Scale

func (v Vec3) Scale(scalar float64) Vec3

func (*Vec3) ScaleAssign

func (v *Vec3) ScaleAssign(scalar float64)

func (Vec3) Subtract

func (v Vec3) Subtract(a Vec3) Vec3

func (*Vec3) SubtractAssign

func (v *Vec3) SubtractAssign(a Vec3)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL