Documentation ¶
Overview ¶
Package silk provides an N-dimensional implementation of the wave function collapse algorithm. This package was largely inspired by the work of Maxim Gumin seen here: https://github.com/mxgmn/WaveFunctionCollapse.
The package provides two levels of abstraction around the algorithm. The first (and primary) way to use silk is through the Loom type. The Loom type internally configures and collapses a wave function through a simple API. The Loom type uses a Shuttle interface to produce a propogator for the wave, as well as interpret the wave result. Out-of-the-box shuttles are provided under github.com/split-cube-studios/silk/pkg/shuttle.
Below is a simple example of how one may use silk in their own project:
size := []int{128, 128} // size can be any number of dimensions loom := silk.NewLoom(size, myShuttle) // myShuttle may be a custom implementation, or one of the provided shuttles if err := loom.Weave(); err != nil { panic(err) }
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrWaveFullyCollapsed = errors.New("wave fully collapsed")
ErrWaveFullyCollapsed is returned from Wave.Step when called on a fully collapsed wave function.
var ErrWaveParadox = errors.New("wave paradox")
ErrWaveParadox is returned from Wave.Step when a paradox is encountered.
Functions ¶
func CoordsToIndex ¶
CoordsToIndex converts a set of n-dimensional coordinates to an index.
Types ¶
type Loom ¶
Loom is the primary way to use silk. A loom is initialized with a shuttle and a set of working dimensions. When *Loom.Weave() is called, the loom will collapse the wave function completely and pass each observation result to the shuttle.
type ObservationHeuristic ¶
type ObservationHeuristic byte
ObservationHeuristic a type is the mode of state selection for observation.
const ( // HeuristicRandom selects a random state. ObservationHeuristicRandom ObservationHeuristic = iota // HeuristicMinEntropy selects the state with the lowest entropy. ObservationHeuristicMinEntropy // HeuristicMaxEntropy selects the state with the highest entropy. ObservationHeuristicMaxEntropy )
type Shuttle ¶
type Shuttle interface { // Propogator accesses the shuttle's wave propogator and returns // a slice of all compatible states c for a given state t in direction d. Propogator(d, t int) []int // ObservationHeuristic returns which heuristic to use for the wave's observations. ObservationHeuristic() ObservationHeuristic // Weights returns a slice of weights for each state. Weights() []float64 // Directions returns a slice of directional offsets for traversing the wave function. // Each offset in the slice is a vector of offsets along each dimension. // Opposite directions are sequential, ie index 0 and index 1 are opposite directions. // For example, a 2D wave function with 4 directions could return: // [][]int{ // []int{0, -1}, // []int{0, 1}, // []int{1, 0}, // []int{-1, 0}, // } Directions() [][]int // Weave is called for each observation of a wave function. // The shuttle should interpret the wave function and produce an output. // The done parameter indicates whether the full collapse has completed. Weave(coefficients [][]bool, done bool) error }
Shuttle is an interface responsible for defining wave propogation rules, as well as interpreting the results of a wave function.
In a general sense, a shuttle describes the data a wave function represents. For example, a shuttle output may be a 2D image, and the wave function might represent the image's pixel values.
type ShuttlePatternProvider ¶
type ShuttlePatternProvider struct { // ShuttlePatternProviderOptions are the options used to initialize the provider. ShuttlePatternProviderOptions // Patterns is a slice of all possible patterns. Patterns [][]int // Weights is a slice of weights for each pattern. Weights []float64 // Directions is a slice of directional offsets for traversing the wave function. Directions [][]int // contains filtered or unexported fields }
ShuttlePatternProvider exposes helper functions for pattern/feature extraction. The provider operates on N-dimensional slices of integers. Each integer represents a possible state in the wave function. If the provider does not support the needs of a given project, the user is able to use custom logic in their shuttle implementation. PRs are also welcome!
func NewShuttlePatternProvider ¶
func NewShuttlePatternProvider(opts ShuttlePatternProviderOptions) *ShuttlePatternProvider
NewShuttlePatternProvider initializes a new shuttle pattern provider with the given options.
func (*ShuttlePatternProvider) WavePropogator ¶
func (p *ShuttlePatternProvider) WavePropogator() WavePropogator
WavePropogator returns a propogator function for the pattern provider's input data.
type ShuttlePatternProviderOptions ¶
type ShuttlePatternProviderOptions struct { // N is the size of the pattern. N defaults to 3. N int // Dims is a slice of dimensions for the input data. Dims []int // Data is a slice of integers representing the input data. Data []int // Reflections is a slice of axis indices to reflect patterns across. Reflections []int }
ShuttlePatternProviderOptions are options for the shuttle pattern provider.
Features/patterns are extracted from the input data in length N volumes in the given dimensions. The extraction process uses a sliding window, so features may overlap. Features are then deemed compatible if their values overlap in a given direction.
Using the weight of each feature and the compatibility of each feature pair, a WavePropogator is generated for the shuttle.
type Wave ¶
type Wave struct { WavePropogator ObservationHeuristic // contains filtered or unexported fields }
Wave is a silk wave function. A wave may be N-dimensional. Waves can be collapsed iteratively or all at once with a given heuristic.
func NewWave ¶
func NewWave(p WavePropogator, h ObservationHeuristic, weights []float64, dims []int, directions [][]int, cb WaveObservationCallbackFn) *Wave
NewWave creates a new silk wave function. The wave function is N-dimensional. An optional callback can be provided, which will be called upon each observation.
func (*Wave) Observe ¶
Observe will observe the wave function n amount of times. Each observation will collapse regions of the wave to a single state. Observe will run until the wave function is fully collapsed when n is -1. ErrWaveFullyCollapsed is returned when Observe is called on a fully collapsed wave function, or when n is -1 and the collapse comes to completion. ErrWaveParadox is returned when a paradox is encountered.
func (*Wave) ObserverBus ¶
ObserverBus returns a channel which indicates the progress of the wave function collapse.
type WaveObservationCallbackFn ¶
WaveObservationCallbackFn is a callback function which is called upon each observation step.
type WavePropogator ¶
WavePropogator is a function which access a static or dynamic wave propogator matrix. The matrix contains compatibility rules for neighboring states in the wave function. The wave propogator matrix is a 3-dimensional matrix of size [d][t][c], where d is the direction, t is the state, and c is the compatible state.