xirho

package module
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Jan 1, 2021 License: Zlib Imports: 13 Imported by: 0

README

ξρ

Xirho is a simple generalized iterated function system plotter. It makes pretty pictures out of math.


Spherical gasket


An iterated function system, or IFS, is just a list of functions that turn points into other points.

Take a random place in 3D space. Pick a function in the system at random. Apply the function to the point, resulting in a new point. Plot the new point. Repeat.

That's it.


Sierpinski gasket


The original treatments of IFS were mostly concerned with affine transformations: simple functions describing uniform scaling, rotation, shearing, and translation. We can get some pretty good images out of just these; the Sierpinski gasket just above is an example.

The "fractal flame" algorithm is a way of generalizing IFS: allowing arbitrary functions in the system and adding color and tone mapping to the output. The spherical gasket at the top of this page is very similar to the Sierpinski gasket, just replacing a couple affine transformations with a simple nonlinear function.


Grand Julian


Xirho is a pretty basic fractal flame renderer, with only a handful of function types available (for now). It doesn't support designing a system interactively (yet). The renderer is flexible thanks to Go's powerful type system, and it's fast because of its completely lock-free parallel design. It's simpler algorithmically than its counterparts, and that simplicity leads to some generalizations that may be interesting to explore.


Splits-Elliptic


Ultimately, xirho is a pet project that I've wanted to implement for a decade to address the bugs in Apophysis and the commercial limitations in Chaotica (which is still an outstanding piece of software!). xirho isn't intended to be the fastest IFS renderer, nor the most versatile, and it's explicitly avoiding compatibility with those other tools and their mimics. But it's something I enjoy working on, so it will get better than it is.


Disc Julian

Documentation

Overview

Package xirho implements an iterated function system fractal art renderer.

An iterated function system is a collection of functions from points to points. Starting with a randomly selected point, we choose a function at random, apply that function to the point, and plot its new location, then repeat ad infinitum. With some additional steps, the result images can be stunning.

The mathematical terminology used in xirho's documentation and API is as follows. A point is an element of R³ × [0, 1], i.e. a 3D point plus a color coordinate. A function, sometimes function type, is a procedure which maps points to points, possibly using additional fixed parameters to control the exact mapping. (Other IFS implementations typically refer to functions in this sense as variations.) A node is a particular instance of a function and its fixed parameters. An iterated function system, or just system, is a non-empty list of nodes, a Markov chain giving the probability of the algorithm transitioning from each node in the list to each other node in the list, an additional node applied to each output point to serve as a possibly nonlinear camera, and a mapping of color coordinates to colors. The Markov chain of a system may also be called the weights graph, or just the graph.

Xirho does not include a designer to produce systems to render. Existing parameters can be loaded through the encoding and encoding/flame subpackages, or programmed by hand.

To use xirho to render a system, create a Render containing the System and a Hist to plot points, then call its Render method with a non-trivial context. (The context closing is the only way that Render returns.) Alternatively, the RenderAsync method provides an API to manage rendering concurrently, e.g. to support a UI. For fine-grained control of the rendering process, the System.Iter method can be used directly.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func HistMem

func HistMem(width, height int) int

HistMem estimates the memory usage in bytes of a histogram of a given size.

func Tx

func Tx(ax *Ax, x, y, z float64) (tx, ty, tz float64)

Tx transforms a coordinate with an affine transform.

func TxVec

func TxVec(ax *Ax, v [3]float64) [3]float64

TxVec transforms a 3-vector with an affine transform.

Types

type Affine

type Affine = Ax

Affine is an affine transform function parameter.

type Angle

type Angle float64

Angle is an angle function parameter. External interfaces wrap its value into the interval (-pi, pi].

type Ax

type Ax f64.Aff4

Ax is an affine transform.

func Eye

func Eye() Ax

Eye returns an identity transform.

func (*Ax) Eye

func (ax *Ax) Eye() *Ax

Eye sets the transform to the identity transform and returns it.

func (*Ax) Pitch

func (ax *Ax) Pitch(tx float64) *Ax

Pitch rotates the transform about the x axis centered on the transform's translation point and returns it.

func (*Ax) Roll

func (ax *Ax) Roll(ty float64) *Ax

Roll rotates the transform about the y axis centered on the transform's translation point and returns it.

func (*Ax) RotX

func (ax *Ax) RotX(tx float64) *Ax

RotX rotates the transform about the x axis and returns it. Specifically, tx is the counter-clockwise rotation in the y/z plane in radians. The translation vector is also rotated appropriately.

func (*Ax) RotY

func (ax *Ax) RotY(ty float64) *Ax

RotY rotates the transform about the y axis and returns it. Specifically, ty is the rotation in the x/z plane in radians.

func (*Ax) RotZ

func (ax *Ax) RotZ(tz float64) *Ax

RotZ rotates the transform about the z axis and returns it. Specifically, tz is the rotation in the x/y plane in radians.

func (*Ax) Scale

func (ax *Ax) Scale(sx, sy, sz float64) *Ax

Scale scales the transform along each axis and returns it.

func (*Ax) SetVO added in v0.2.0

func (ax *Ax) SetVO(v Vec3) *Ax

SetVO sets the O vector of the transform, which is the translation vector, and returns the transform.

func (*Ax) SetVX added in v0.2.0

func (ax *Ax) SetVX(v Vec3) *Ax

SetVX sets the X vector of the transform, which is the first column, and returns the transform.

func (*Ax) SetVY added in v0.2.0

func (ax *Ax) SetVY(v Vec3) *Ax

SetVY sets the Y vector of the transform, which is the second column, and returns the transform.

func (*Ax) SetVZ added in v0.2.0

func (ax *Ax) SetVZ(v Vec3) *Ax

SetVZ sets the Z vector of the transform, which is the third column, and returns the transform.

func (*Ax) Translate

func (ax *Ax) Translate(dx, dy, dz float64) *Ax

Translate translates the transform and returns it.

func (*Ax) Tx added in v0.2.0

func (ax *Ax) Tx(x, y, z float64) (tx, ty, tz float64)

Tx transforms a coordinate.

func (*Ax) VO added in v0.2.0

func (ax *Ax) VO() Vec3

VO returns the O vector of the transform, which is the translation vector.

func (*Ax) VX added in v0.2.0

func (ax *Ax) VX() Vec3

VX returns the X vector of the transform, which is the first column.

func (*Ax) VY added in v0.2.0

func (ax *Ax) VY() Vec3

VY returns the Y vector of the transform, which is the second column.

func (*Ax) VZ added in v0.2.0

func (ax *Ax) VZ() Vec3

VZ returns the Z vector of the transform, which is the third column.

func (*Ax) Yaw

func (ax *Ax) Yaw(tz float64) *Ax

Yaw rotates the transform about the z axis centered on the transform's translation point and returns it.

type ChangeRender

type ChangeRender struct {
	// System is the new system to render. If the system is empty, then the
	// renderer continues using its previous non-empty system.
	System System
	// Size is the new histogram size to render. If this is the zero value,
	// then the histogram is neither resized nor reset. If this is equal to the
	// histogram's current size, then all plotting progress is cleared.
	Size image.Point
	// Camera is the new camera transform to use, if non-nil.
	Camera *Ax
	// Palette is the new palette to use, if it has nonzero length. The palette
	// is copied into the renderer.
	Palette []color.NRGBA64
	// Procs is the new number of worker goroutines to use. If this is zero,
	// then the renderer does no work until receiving a nonzero Procs.
	Procs int
}

ChangeRender signals to RenderAsync to modify its system, histogram, or number of workers. RenderAsync can be paused without discarding render progress by sending this type's zero value.

type Complex

type Complex complex128

Complex is an unconstrained function parameter in R^2.

type Flag

type Flag bool

Flag is a boolean function parameter.

type Func

type Func interface {
	// Calc calculates the function at a point.
	Calc(in Pt, rng *RNG) Pt
	// Prep is called once prior to iteration so that a function can cache
	// expensive calculations.
	Prep()
}

Func is a function ("variation") type.

Functions may be parametrized in a number of ways with the types Flag, List, Int, Angle, Real, Complex, Vec3, Affine, Func, and FuncList. If fields of these types are exported, package fapi can collect them to enable a user interface for setting and displaying such parameters.

type FuncList

type FuncList []Func

FuncList is a function parameter holding a list of functions.

type Hist

type Hist struct {
	// contains filtered or unexported fields
}

Hist is a uniform two-dimensional histogram.

func NewHist

func NewHist(width, height int) *Hist

NewHist allocates a histogram. An alternative to this function is to create a zero Hist value and call Reset and SetBrightness to initialize it.

func (*Hist) Add

func (h *Hist) Add(x, y int, c color.NRGBA64)

Add increments a histogram bucket by the given color. It is safe for multiple goroutines to call this concurrently.

func (*Hist) Aspect

func (h *Hist) Aspect() float64

Aspect returns the histogram's aspect ratio. If the histogram is empty, the result is 0.

func (*Hist) At

func (h *Hist) At(x, y int) color.Color

At returns the color of a pixel in the histogram. Note that this is a fairly expensive operation.

func (*Hist) Bounds

func (h *Hist) Bounds() image.Rectangle

Bounds returns the bounds of the histogram.

func (*Hist) Brightness

func (h *Hist) Brightness() (br, gamma, tr float64)

Brightness returns the last brightness parameters passed to SetBrightness.

func (*Hist) ColorModel

func (h *Hist) ColorModel() color.Model

ColorModel returns the histogram's internal color model.

func (*Hist) Empty

func (h *Hist) Empty() bool

Empty returns true if the histogram has zero size.

func (*Hist) Reset

func (h *Hist) Reset(width, height int)

Reset reinitializes the histogram counts. If the given width and height are not equal to the histogram's current respective sizes, then the histogram is completely reallocated.

func (*Hist) SetBrightness

func (h *Hist) SetBrightness(br, gamma, tr float64)

SetBrightness sets the brightness parameters for the rendered image. br controls the brightness of color channels relative to alpha. gamma applies nonlinear brightness to the alpha channel to balance low-count bins, but only applies to bins exceeding a relative count of tr.

type Int

type Int int64

Int is an integer function parameter, possibly bounded.

type List

type List int

List is a function parameter to choose among a fixed set of options.

type Metadata

type Metadata struct {
	// Title is the name of the fractal.
	Title string `json:"title"`
	// Authors is the list of people who created the fractal.
	Authors []string `json:"authors"`
	// Date is the time the fractal was last modified.
	Date time.Time `json:"date"`
	// License is the license under which the fractal parameters are shared.
	// Typically this would be the title of the license, e.g. "CC4-BY-SA",
	// rather than the full license text.
	License string `json:"license"`
}

Metadata holds metadata about a fractal.

type Node added in v0.5.0

type Node struct {
	// Func is the function which transforms points.
	Func Func
	// Opacity scales the alpha channel of points plotted by the node. It
	// must be in the interval [0, 1].
	Opacity float64
	// Weight controls the proportion of iterations which map to this node.
	// It must be a finite, nonnegative number.
	Weight float64
	// Graph is the weights from this node to each other node in the
	// system. If the graph is shorter than the number of nodes in the
	// system, then the missing values are treated as being 1.
	Graph []float64

	// Label is the label for this node.
	Label string
}

Node describes the properties of a single node within a system.

type PlotOnto

type PlotOnto struct {
	// Image is the image to plot onto. The histogram is plotted using the Over
	// Porter-Duff operator.
	Image draw.Image
	// Scale is the resampling method to use to resample the histogram to the
	// size of Image.
	Scale draw.Scaler
	// Bright, Gamma, and Thresh correspond to the same parameters to
	// Hist.SetBrightness.
	Bright, Gamma, Thresh float64
}

PlotOnto is a work item for RenderAsync to plot onto.

type Pt added in v0.5.0

type Pt struct {
	// X, Y, and Z are spatial coordinates.
	X, Y, Z float64
	// C is the color coordinate in [0, 1].
	C float64
}

Pt is a point in R^3 × [0, 1].

func (Pt) IsValid added in v0.5.0

func (p Pt) IsValid() bool

IsValid returns true if its spatial coordinates are finite and its color coordinate is in [0, 1].

type RNG

type RNG = xmath.RNG

RNG is the randomness source type.

type Real

type Real float64

Real is a floating-point function parameter, possibly bounded.

type Render added in v0.5.0

type Render struct {

	// Hist is the target histogram.
	Hist *Hist
	// Camera is the camera transform.
	Camera Ax
	// Palette is the colors used by the renderer.
	Palette []color.NRGBA64

	// Meta contains metadata about the fractal.
	Meta *Metadata
	// contains filtered or unexported fields
}

Render manages the rendering of a System onto a Hist.

func (*Render) Hits added in v0.5.0

func (r *Render) Hits() int64

Hits returns the number of iterations the renderer has plotted. It is safe to call this while the renderer is running.

func (*Render) Iters added in v0.5.0

func (r *Render) Iters() int64

Iters returns the number of iterations the renderer has performed. It is safe to call this while the renderer is running.

func (*Render) Render added in v0.5.0

func (r *Render) Render(ctx context.Context, system System, procs int)

Render renders a System onto a Hist. Calculation is performed by procs goroutines, or by GOMAXPROCS goroutines if procs <= 0. Render returns after the context closes and after all its renderer goroutines finish. It is safe to call Render multiple times in succession to continue using the same histogram.

func (*Render) RenderAsync added in v0.5.0

func (r *Render) RenderAsync(ctx context.Context, change <-chan ChangeRender, plot <-chan PlotOnto, imgs chan<- draw.Image)

RenderAsync manages asynchronous rendering. It is intended to be used in a go statement. The renderer does not begin work until receiving a System and other render settings over the change channel.

RenderAsync is designed to allow a user interface to change rendering parameters and receive plots safely, without needing to explicitly synchronize worker goroutines. Whenever it receives items over the change or plot channels, RenderAsync handles pausing and resuming workers as needed to prevent data races. It also attempts to group together multiple changes and plot requests to reduce unnecessary work.

Once the context closes, RenderAsync stops its workers, closes the imgs channel, and returns. If needed, other goroutines may join on RenderAsync by waiting for imgs to close. Until imgs closes, it is not safe to modify any of the renderer's fields.

func (*Render) ResetCounts added in v0.5.0

func (r *Render) ResetCounts()

ResetCounts resets the values returned by Iters and Hits to zero. Unlike those methods, it is not safe to call this while the renderer is running.

type System

type System struct {
	// Nodes is the system's node list.
	Nodes []Node
	// Final is an additional function applied after each function, if it is
	// non-nil. The result from Final is used only for plotting; the input to
	// it is the same as the input to the next iteration's function.
	Final Func
}

System is a generalized iterated function system.

func (System) Check

func (s System) Check() error

Check verifies that the system is properly configured: it contains at least one node, no opacities are outside [0, 1], and no weight is negative or non-finite. If any of these conditions is false, then the returned error describes the problem.

func (System) Empty

func (s System) Empty() bool

Empty returns whether the system contains no functions.

func (System) Iter

func (s System) Iter(ctx context.Context, r *Render, rng RNG)

Iter iterates the function system and plots points onto r. It continues iterating until the context's Done channel is closed. rng should be seeded to a distinct state for each call to this method. Iter panics if Check returns an error.

func (System) Prep

func (s System) Prep()

Prep calls the Prep method of each function in the system. It should be called once before any call to Iter.

type Vec3

type Vec3 [3]float64

Vec3 is an unconstrained function parameter in R^3.

Directories

Path Synopsis
cmd
xirho
The xirho command implements a basic renderer using xirho.
The xirho command implements a basic renderer using xirho.
Package encoding implements marshaling and unmarshaling function systems.
Package encoding implements marshaling and unmarshaling function systems.
flame
Package flame implements parsing the XML-based Flame format.
Package flame implements parsing the XML-based Flame format.
Package fapi creates a generic public API for xirho functions.
Package fapi creates a generic public API for xirho functions.
Package xi provides function registration and implementations for xirho.
Package xi provides function registration and implementations for xirho.
Package xmath provides mathematics routines convenient to xirho and its components.
Package xmath provides mathematics routines convenient to xirho and its components.

Jump to

Keyboard shortcuts

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