Documentation
¶
Overview ¶
Package fractal provides pure–Go, standard-library-only tools for computing and exploring classic fractals.
The package is organized around several independent topics:
- Escape-time fractals: the Mandelbrot set and Julia sets, including per-point escape iteration counts, smooth (normalized) iteration counts for continuous coloring, closed-form interior tests (main cardioid and period-2 bulb), and evaluation over a rectangular grid via a Viewport.
- Fractal dimension: box-counting dimension of a finite point set, a generic log-log least-squares slope helper, and the exact self-similar (Hausdorff) dimension of strictly self-similar sets.
- L-systems: deterministic context-free string rewriting (LSystem) plus a turtle-graphics interpreter that turns a command string into line [Segment]s or a vertex path, with presets for the Koch curve, Sierpinski triangle, dragon curve, and a branching plant.
- Iterated function systems: affine contraction maps (AffineMap), the random "chaos game" (IFS.ChaosGame), and presets for the Barnsley fern and Sierpinski triangle/carpet.
- Deterministic geometric fractals: the Koch curve and snowflake, the Sierpinski triangle by recursive subdivision, and the Cantor set.
All routines use only the Go standard library and are deterministic: any randomness (the chaos game) is driven by an explicit caller-supplied seed.
Complex numbers are represented with the builtin complex128 type; planar points use Point2D.
Index ¶
- func BoxCount(points []Point2D, boxSize float64) int
- func BoxCountingDimension(points []Point2D, boxSizes []float64) float64
- func BoxCountingDimensionFromCounts(boxSizes, counts []float64) float64
- func FitLine(xs, ys []float64) (slope, intercept float64)
- func FitSlope(xs, ys []float64) float64
- func HausdorffDimensionSelfSimilar(n int, scale float64) float64
- func InJuliaSet(z, c complex128, maxIter int) bool
- func InMainCardioid(c complex128) bool
- func InMandelbrotSet(c complex128, maxIter int) bool
- func InPeriod2Bulb(c complex128) bool
- func JuliaSmooth(z, c complex128, maxIter int, bailout float64) float64
- func MandelbrotSmooth(c complex128, maxIter int, bailout float64) float64
- func Orbit(z0, c complex128, n int) []complex128
- type AffineMap
- type EscapeResult
- type Grid
- func (g *Grid) At(x, y int) float64
- func (g *Grid) Clone() *Grid
- func (g *Grid) CountFinite() int
- func (g *Grid) Max() float64
- func (g *Grid) Mean() float64
- func (g *Grid) Min() float64
- func (g *Grid) MinMax() (min, max float64)
- func (g *Grid) Normalize() *Grid
- func (g *Grid) Row(y int) []float64
- func (g *Grid) Set(x, y int, v float64)
- type IFS
- type Interval
- type LSystem
- type Point2D
- func (p Point2D) Add(q Point2D) Point2D
- func (p Point2D) Dist(q Point2D) float64
- func (p Point2D) Lerp(q Point2D, t float64) Point2D
- func (p Point2D) Midpoint(q Point2D) Point2D
- func (p Point2D) Norm() float64
- func (p Point2D) Rotate(angle float64) Point2D
- func (p Point2D) Scale(s float64) Point2D
- func (p Point2D) Sub(q Point2D) Point2D
- type Segment
- type Triangle
- type TurtleConfig
- type TurtleState
- type Viewport
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BoxCount ¶
BoxCount returns the number of distinct axis-aligned grid boxes of side boxSize that contain at least one of the given points. It panics if boxSize is not positive. This is the count N(epsilon) used in box-counting dimension estimation.
func BoxCountingDimension ¶
BoxCountingDimension estimates the box-counting (Minkowski–Bouligand) dimension of a finite point set by counting occupied boxes at each of the given box sizes and returning the slope of log N(epsilon) versus log(1/epsilon). At least two box sizes are required; the sizes must be positive. Smaller boxes give a better estimate for a true fractal but require densely sampled points.
func BoxCountingDimensionFromCounts ¶
BoxCountingDimensionFromCounts estimates a fractal dimension directly from a table of (box size, occupied-box count) samples: it returns the slope of log(count) versus log(1/size). This is useful when counts were obtained externally. The slices must have equal length of at least two, and all entries must be positive. For an exact power law count = k*size^(-D) the returned value is exactly D.
func FitLine ¶
FitLine returns the slope and intercept of the ordinary least-squares line y = slope*x + intercept fitted to the paired samples xs, ys. It panics if the slices differ in length or contain fewer than two points. When every x is identical the slope is 0 and the intercept is the mean of ys.
func FitSlope ¶
FitSlope returns the slope of the ordinary least-squares line y = m*x + b fitted to the paired samples xs, ys. It panics if the slices differ in length or contain fewer than two points, and returns 0 when every x is identical.
func HausdorffDimensionSelfSimilar ¶
HausdorffDimensionSelfSimilar returns the exact similarity (Hausdorff) dimension of a strictly self-similar set composed of n non-overlapping copies of itself, each scaled by the ratio scale (0 < scale < 1). The dimension is log(n)/log(1/scale). For example n=3, scale=1/2 gives the Sierpinski triangle dimension log2(3) ≈ 1.585; n=4, scale=1/3 gives the Koch curve dimension log(4)/log(3) ≈ 1.262. It panics if n < 1 or scale is not in (0,1).
func InJuliaSet ¶
func InJuliaSet(z, c complex128, maxIter int) bool
InJuliaSet reports whether the seed z lies in the filled Julia set of z -> z^2 + c, i.e. whether its orbit fails to escape radius 2 within maxIter iterations.
func InMainCardioid ¶
func InMainCardioid(c complex128) bool
InMainCardioid reports, in closed form, whether c lies inside the main cardioid of the Mandelbrot set — the large heart-shaped region containing all c for which z -> z^2 + c has an attracting fixed point. Writing p = |c - 1/4| = sqrt((Re c - 1/4)^2 + (Im c)^2), the membership criterion is Re(c) <= p - 2*p^2 + 1/4, which holds exactly on the closed cardioid.
func InMandelbrotSet ¶
func InMandelbrotSet(c complex128, maxIter int) bool
InMandelbrotSet reports whether c lies in the Mandelbrot set, i.e. whether the orbit of z -> z^2 + c starting at 0 fails to escape radius 2 within maxIter iterations. Because the test is truncated at maxIter, points very near the boundary may be misclassified as members.
func InPeriod2Bulb ¶
func InPeriod2Bulb(c complex128) bool
InPeriod2Bulb reports, in closed form, whether c lies inside the period-2 bulb of the Mandelbrot set: the disk of radius 1/4 centered at -1. Membership is exactly |c + 1| <= 1/4.
func JuliaSmooth ¶
func JuliaSmooth(z, c complex128, maxIter int, bailout float64) float64
JuliaSmooth returns the smooth (fractional) escape iteration count for the Julia map z -> z^2 + c seeded at z. See EscapeResult.Smooth.
func MandelbrotSmooth ¶
func MandelbrotSmooth(c complex128, maxIter int, bailout float64) float64
MandelbrotSmooth returns the smooth (fractional) escape iteration count for the Mandelbrot map at c. See EscapeResult.Smooth. A large bailout (for example 256) gives the smoothest result.
func Orbit ¶
func Orbit(z0, c complex128, n int) []complex128
Orbit returns the first n+1 points of the orbit of z -> z^2 + c starting at z0, that is [z0, f(z0), f(f(z0)), ...] of length n+1. For n < 0 it returns nil.
Types ¶
type AffineMap ¶
type AffineMap struct {
A, B, C, D, E, F float64
}
AffineMap is a 2-D affine transformation of the form
x' = A*x + B*y + E y' = C*x + D*y + F
Such contraction maps are the building blocks of iterated function systems.
func NewAffineMap ¶
NewAffineMap constructs an AffineMap from its six coefficients in the order a, b, c, d, e, f matching the field layout x' = a*x+b*y+e, y' = c*x+d*y+f.
type EscapeResult ¶
type EscapeResult struct {
Escaped bool
Iterations int
FinalZ complex128
}
EscapeResult records the outcome of iterating a quadratic map z -> z^2 + c until the orbit escapes a bailout radius or a maximum iteration count is reached. Escaped reports whether the bailout was exceeded; Iterations is the number of completed iterations at that moment (equal to the maximum when the orbit did not escape); FinalZ is the last computed orbit value.
func JuliaEscape ¶
func JuliaEscape(z, c complex128, maxIter int, bailout float64) EscapeResult
JuliaEscape computes the escape-time result for the filled Julia set of the map z -> z^2 + c starting from the seed point z. The orbit escapes once |z| exceeds bailout (at least 2). Iteration stops after maxIter steps.
func MandelbrotEscape ¶
func MandelbrotEscape(c complex128, maxIter int, bailout float64) EscapeResult
MandelbrotEscape computes the escape-time result for the Mandelbrot map z -> z^2 + c starting from z = 0. The point c is considered to have escaped once |z| exceeds bailout (which should be at least 2, the Mandelbrot escape radius). Iteration stops after maxIter steps.
func (EscapeResult) Smooth ¶
func (r EscapeResult) Smooth(bailout float64) float64
Smooth returns the fractional (normalized) iteration count for an escaped result, giving continuous values suitable for smooth coloring. It uses the standard renormalization mu = n + 1 - log2(log|z| / log(bailout)). For a result that did not escape it returns the integer iteration count unchanged. The estimate is most accurate when bailout is large (for example 256).
type Grid ¶
Grid is a dense Width×Height array of scalar values stored in row-major order (index = y*Width + x). It is the natural output of rasterizing an escape-time fractal over a rectangular region.
func JuliaGrid ¶
func JuliaGrid(c complex128, v Viewport, width, height, maxIter int, bailout float64) *Grid
JuliaGrid rasterizes the filled Julia set of z -> z^2 + c over the given viewport into a width×height Grid. Each cell holds the smooth escape iteration count of the seed sampled at that pixel. Row 0 corresponds to the top of the viewport.
func MandelbrotGrid ¶
MandelbrotGrid rasterizes the Mandelbrot set over the given viewport into a width×height Grid. Each cell holds the smooth escape iteration count (see EscapeResult.Smooth) of the complex value sampled at that pixel, so interior (non-escaping) points hold maxIter. Row 0 corresponds to the top of the viewport. See Viewport.PixelToComplex for the pixel-to-complex mapping.
func NewGrid ¶
NewGrid allocates a zero-filled Grid with the given dimensions. It panics if width or height is negative.
func (*Grid) At ¶
At returns the value at column x, row y. It panics if the coordinates are out of range.
func (*Grid) CountFinite ¶
CountFinite returns the number of grid cells whose value is finite (neither NaN nor infinite).
func (*Grid) MinMax ¶
MinMax returns the minimum and maximum values in the grid. For an empty grid it returns (0, 0).
func (*Grid) Normalize ¶
Normalize returns a new Grid whose values are linearly rescaled so that the original minimum maps to 0 and the original maximum maps to 1. If all values are equal the result is all zeros. The receiver is not modified.
type IFS ¶
IFS is an iterated function system: a list of affine contraction Maps with an equal-length list of selection Weights. When run as a chaos game the map at index i is chosen with probability Weights[i] / sum(Weights). If Weights is nil or empty the maps are chosen uniformly.
func BarnsleyFern ¶
func BarnsleyFern() IFS
BarnsleyFern returns the four-map iterated function system that generates Michael Barnsley's fern. The maps and their selection probabilities are the classical values; the attractor fits within roughly x in [-2.2, 2.7] and y in [0, 10].
func SierpinskiCarpetIFS ¶
func SierpinskiCarpetIFS() IFS
SierpinskiCarpetIFS returns the eight-map iterated function system whose attractor is the Sierpinski carpet: the unit square is divided into a 3x3 grid and every cell except the center maps back to the whole via a 1/3-scale contraction. The maps are chosen with equal probability.
func SierpinskiTriangleIFS ¶
func SierpinskiTriangleIFS() IFS
SierpinskiTriangleIFS returns the three-map iterated function system whose attractor is the Sierpinski triangle with vertices (0,0), (1,0) and (0.5, 0.5). Each map scales the plane by 1/2 toward one vertex; the maps are chosen with equal probability.
func (IFS) ChaosGame ¶
ChaosGame runs the chaos game starting from the origin, discarding 20 transient points, and returns n attractor points. It is a convenience wrapper around IFS.ChaosGameFrom. The output is deterministic for a given seed.
func (IFS) ChaosGameFrom ¶
ChaosGameFrom runs the random-iteration ("chaos game") algorithm starting from the point start: it repeatedly picks a map according to the system's weights and applies it, discarding the first transient points before recording n points. Randomness is driven solely by seed, so the output is fully deterministic for a given seed. It returns n points and panics if the system has no maps or n is negative.
type Interval ¶
type Interval struct {
Start, End float64
}
Interval is a closed real interval [Start, End].
func CantorSet ¶
CantorSet returns the intervals remaining after iterations steps of the middle-thirds Cantor construction applied to [start, end]. Iteration 0 returns the single interval [start, end]; each step replaces every interval by its first and last thirds, so the result contains 2^iterations intervals with total length (end-start)*(2/3)^iterations. Intervals are returned in increasing order. It panics if iterations is negative.
type LSystem ¶
LSystem is a deterministic context-free Lindenmayer system: an Axiom string and a set of production Rules mapping a single symbol (rune) to a replacement string. Symbols with no rule are left unchanged (they act as constants).
func DragonLSystem ¶
func DragonLSystem() LSystem
DragonLSystem returns the Heighway dragon curve L-system: axiom "F" with rules X -> X+YF+ and Y -> -FX-Y, rendered with a turn angle of 90 degrees. The symbols X and Y control the recursion and draw nothing themselves.
func KochLSystem ¶
func KochLSystem() LSystem
KochLSystem returns the classic Koch curve L-system: axiom "F" with the rule F -> F+F--F+F. Rendered with a turn angle of 60 degrees it produces the Koch curve.
func NewLSystem ¶
NewLSystem constructs an LSystem from an axiom and a rule map. The rule map is copied so later mutation of the argument does not affect the system.
func PlantLSystem ¶
func PlantLSystem() LSystem
PlantLSystem returns a branching plant L-system: axiom "X" with rules X -> F+[[X]-X]-F[-FX]+X and F -> FF, rendered with a turn angle of about 25 degrees. It uses the bracket commands to create branches.
func SierpinskiLSystem ¶
func SierpinskiLSystem() LSystem
SierpinskiLSystem returns an L-system whose turtle rendering (turn angle 60 degrees) draws the Sierpinski triangle. Axiom "F-G-G" with rules F -> F-G+F+G-F and G -> GG.
type Point2D ¶
type Point2D struct {
X, Y float64
}
Point2D is a point in the Euclidean plane with coordinates X and Y.
func BoundingBox ¶
BoundingBox returns the axis-aligned bounding box of pts as its minimum and maximum corners. It returns two zero points when pts is empty.
func KochCurve ¶
KochCurve returns the polyline vertices of the Koch curve constructed between the endpoints p0 and p1 after the given number of iterations. Iteration 0 returns the two endpoints [p0, p1]; each further iteration replaces every segment by four segments (a bump raised on its middle third), so the result has 4^iterations + 1 points. Bumps are raised to the left of the p0->p1 direction. It panics if iterations is negative.
func KochSnowflake ¶
KochSnowflake returns the closed polyline of the Koch snowflake inscribed in the circle of the given radius centered at center, after the given number of iterations. The base is an equilateral triangle whose corners lie on the circle; each edge is replaced by a Koch curve with bumps pointing outward. The returned slice is closed (its last point equals its first). It panics if iterations is negative.
func TurtlePath ¶
func TurtlePath(commands string, cfg TurtleConfig) []Point2D
TurtlePath interprets a command string and returns the ordered vertices visited by the turtle: the start position followed by the endpoint of every forward move (both drawing and non-drawing). It is intended for non-branching L-systems; when brackets are present the returned polyline includes the jumps created by popping the stack. See Turtle for the command set.
func (Point2D) Rotate ¶
Rotate returns p rotated counterclockwise about the origin by angle radians.
type Segment ¶
type Segment struct {
X0, Y0, X1, Y1 float64
}
Segment is a directed line segment from (X0,Y0) to (X1,Y1), the drawing primitive produced by the turtle interpreter.
func Turtle ¶
func Turtle(commands string, cfg TurtleConfig) []Segment
Turtle interprets a command string as turtle graphics and returns the drawn line segments. The recognized commands are:
F, G : move forward by Step, drawing a segment f, g : move forward by Step without drawing + : turn left (counterclockwise) by AngleDeg - : turn right (clockwise) by AngleDeg | : turn around (180 degrees) [ : push the current state onto a stack ] : pop and restore the most recently pushed state
All other symbols are ignored, so L-system variables such as 'X' and 'Y' act as no-ops. Bracketed sections produce disconnected segment groups, allowing branching structures.
type Triangle ¶
type Triangle struct {
A, B, C Point2D
}
Triangle is a triangle with vertices A, B and C.
func SierpinskiTriangle ¶
SierpinskiTriangle returns the list of filled sub-triangles produced by recursively removing the central triangle from the triangle (a, b, c) to the given depth. Depth 0 returns the single input triangle; each level replaces every triangle by its three corner sub-triangles, so the result contains 3^depth triangles. It panics if depth is negative.
type TurtleConfig ¶
TurtleConfig parameterizes the turtle-graphics interpreter. Step is the forward move length; AngleDeg is the turn angle in degrees applied by the '+' and '-' commands; StartAngleDeg is the initial heading in degrees measured counterclockwise from the positive x-axis; Start is the initial pen position.
type TurtleState ¶
TurtleState is the pose of the turtle: its position and its heading in radians measured counterclockwise from the positive x-axis.
type Viewport ¶
type Viewport struct {
XMin, XMax, YMin, YMax float64
}
Viewport is an axis-aligned rectangle in the complex plane, used to map integer pixel coordinates onto complex values. XMin/XMax bound the real axis and YMin/YMax bound the imaginary axis.
func NewViewport ¶
NewViewport returns the square viewport centered at (centerRe, centerIm) with the given half-width (radius) along each axis.
func (Viewport) Aspect ¶
Aspect returns the width-to-height ratio of the viewport. It returns 0 when the height is zero.
func (Viewport) Center ¶
func (v Viewport) Center() complex128
Center returns the complex number at the center of the viewport.
func (Viewport) PixelToComplex ¶
func (v Viewport) PixelToComplex(px, py, width, height int) complex128
PixelToComplex maps the pixel at column px, row py of a width×height raster to the complex value it samples. Column 0 maps to XMin and column width-1 maps to XMax; row 0 maps to YMax (top) and row height-1 maps to YMin (bottom), so increasing the row index moves downward as is conventional for images. When width or height is 1 the corresponding axis collapses to its minimum edge.