Visualizing Complex Numbers in Blender

Image for post
Image for post

Background

Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post

Notes on Implementation

Unary Operations, Pt. 1

Abs Sq / Modulus Sq / R Sq

Image for post
Image for post
abssq(a) := add(mult(re(a), re(a)), mult(im(a), im(a)))

Abs / Modulus / R

Image for post
Image for post
abs(a) := sqrt(abssq(a))

Phase / Arg / Phi

Image for post
Image for post
phase(a) := atan2(im(a), re(a))
Image for post
Image for post
Image for post
Image for post
phase(a) := mix(mult(pi, lt(re(a), 0.0)), mult(atan(div(im(a), add(abs(z), re(a)))), 2.0), max(gt(re(a), 0.0), neq(im(a), 0.0)))
Image for post
Image for post
neq(a, b) := max(gt(a, b), lt(a, b))
Image for post
Image for post
mix(a, b, fac) := add(mult(a, sub(1.0, fac)), mult(b, fac))

Conjugate

Image for post
Image for post
conj(a) := complex(re(a), mult(im(a), -1.0))
Image for post
Image for post
Image for post
Image for post

Reciprocal / Inverse

Image for post
Image for post
reciprocal(a) := complex(div(re(a), abssq(a), div(mult(im(a), -1.0), abssq(a)))
Image for post
Image for post

Conversions

Polar

Image for post
Image for post
polar(a) := abs(a), phase(a)

Rect

Image for post
Image for post
rect(a) := complex(mult(r, cos(phi)), mult(r, sin(phi)))

Binary Operations, Pt. 1

Add

Image for post
Image for post
add(a, b) := complex(add(re(a), re(b)), add(im(a), im(b)))

Sub

Image for post
Image for post
sub(a, b) := complex(sub(re(a), re(b)), sub(im(a), im(b)))

Mult

Image for post
Image for post
mult(a, b) := complex(sub(mult(re(a), re(b)), mult(im(a), im(b))), add(mult(re(a), im(b)), mult(im(a), re(b))))

Div

Image for post
Image for post
div(a, b) := mult(a, reciprocal(b))

Pow

Image for post
Image for post
pow(a, b) := exp(mult(log(a), b))

Unary Operations, Pt. 2

Exp

Image for post
Image for post
exp(a) := rect(pow(e, re(a)), im(a))

Log

Image for post
Image for post
log(a) := complex(log(r(polar(a)), e), phi(polar(a)))

Cos

Image for post
Image for post
complex(mult(cos(a.real), cosh(a.imag)), mult(mult(sin(a.real), -1.0), sinh(a.imag)))
Image for post
Image for post
cosh(a) := mult(add(pow(e, r), pow(e, mult(r, -1.0))), 0.5)
Image for post
Image for post
sinh(a) := mult(sub(pow(e, r), pow(e, mult(r, -1.0))), 0.5)
Image for post
Image for post

Sin

Image for post
Image for post
sin(a) := complex(mult(sin(a.real), cosh(a.imag)), mult(cos(a.real), sinh(a.imag)))

2D Patterns

Mobius Transformation

Image for post
Image for post
mobius(a, b, c, d, z) := div(add(mult(a, z), b), add(mult(c, z), d))
Image for post
Image for post
Image for post
Image for post
A 16x16 lattice, viewed from above.
Image for post
Image for post

Mandelbrot Set

Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Raised to the powers 2.0 (red, top-left), 7.0 (blue, top-right), 2.7 (purple, bottom-right).
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post

Julia Set

Image for post
Image for post
Julia set from seed (-0.8+0.156j). Left: detail. Right: Displacement from Fac.
Image for post
Image for post
Julia Set with seed (-0.8+0.156j).

Pickover Stalks

Image for post
Image for post
Pickover stalks for Julia set, left, and Mandelbrot set, right.
Image for post
Image for post

The Burning Ship

Image for post
Image for post
The burning ship fractal.
Image for post
Image for post

Tricorn / Mandelbar

Image for post
Image for post

3D Patterns

Image for post
Image for post
A mandelbulb raised to the power 2.0, rotated on its side and expressed with a volume shader.
Image for post
Image for post
A mandelbulb expressed with Pickover stalks as they intersect with a surface.

Spherical-Cartesian Conversion

Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Spherical-Cartesian diagnostic. Left, inclination. Right, azimuth.
Image for post
Image for post

The Mandelbulb

Image for post
Image for post
A mandelbulb, power 8.0, red, on the left; power 2.0, blue, on the right.
Image for post
Image for post
Image for post
Image for post

Mixing A Fractal With Other Patterns

Noise

Image for post
Image for post
4D simplex noise mixed with a 3D Julia set.
Image for post
Image for post

Vertex Weighting

Image for post
Image for post
Vertex weights can be viewed while in edit mode by bringing up the Overlays menu and ticking the check box Vertex Group Weights under the Shading header.
Image for post
Image for post
Image for post
Image for post

Vertex Colors

Image for post
Image for post
Image for post
Image for post
Left: a Mandelbulb, power 6, painted to simulate vertex weights. Right: a Julia set painted with vectors.
Image for post
Image for post

Conclusion

Creative coder from Wisconsin, USA.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store