Skip to content

Fractal Expansion Roadmap

Bradley Brown edited this page Aug 13, 2026 · 1 revision

Fractal Expansion Roadmap

Future work plan. Each family below is not yet rendered by Fracturing Fog as of v0.6.x. Grouped by engine reuse — items in same phase share infrastructure.

Existing extension points to reuse:

  • IFractalKernel struct-generic kernel (see FRACTAL_EXPANSION_PROMPTS.md Prompt 0)
  • FractalParameters record for per-family params
  • CalcGen 5-path pipeline (scalar / AVX2 / Pert / BLA / ILGPU) — auto-applies once kernel registered
  • 3D pipeline: UserBulb raymarcher + Vec3 / Quat triplex algebra
  • Theme system gates interior-cycle themes per FractalType; smooth-iter + distance themes work on any escape-time kernel

Phase A — 2D escape-time, kernel-only (cheapest wins)

Reuse existing IFractalKernel + per-pixel iteration loop. Each = one struct file + Type combo entry + Help → Mathematics tab. No new pipeline.

A.1 Magnet 1

  • Formula: z = ((z² + c - 1) / (2z + c - 2))²
  • Rational map; bailout 10² (slower grow), needs divide-safe Step
  • Risk: pole at 2z + c - 2 = 0 — clamp denom magnitude in Step
  • Params: none beyond c
  • Deliver: MagnetOneKernel.cs, Type combo, Math help tab, 1 region preset

A.2 Magnet 2

  • Formula: z = ((z³ + 3(c-1)z + (c-1)(c-2)) / (3z² + 3(c-2)z + c² - 3c + 3))²
  • Same risk as A.1; bigger expression
  • Deliver: MagnetTwoKernel.cs, Type combo, Math tab

A.3 Halley basins

  • Iterate Halley's method on user polynomial (default z³ - 1)
  • Step: z -= 2f·f' / (2f'² - f·f'')
  • Reuses Newton's NewtonPolyCoeffs param + derivative cache
  • Deliver: HalleyKernel.cs, polynomial param picker shared with Newton, Math tab

A.4 Secant basins

  • Two-point recurrence z_{n+1} = z_n - f(z_n)·(z_n - z_{n-1}) / (f(z_n) - f(z_{n-1}))
  • Needs prev-z slot — model after PhoenixKernel which already keeps prev
  • Deliver: SecantKernel.cs, Math tab

A.5 Glynn

  • Formula: z = z^1.5 + c with c ≈ -0.2
  • Fractional power → use Complex.Pow (log/exp)
  • Deliver: GlynnKernel.cs, default region at canonical Glynn coords

A.6 Spider

  • Two-state recurrence: z = z² + c; c = c/2 + z
  • c mutates per iteration — IFractalKernel.Step needs ref cx, ref cy overload, OR new sub-interface IMutatingKernel
  • Architecture cost: small — add overload; existing kernels ignore
  • Deliver: SpiderKernel.cs, kernel-interface extension, Math tab

A.7 Logistic / Feigenbaum bifurcation

  • Not escape-time. 1D map x_{n+1} = r·x_n·(1 - x_n)
  • Render: x-axis = r (3.0 – 4.0), y-axis = settled-x density
  • Needs own renderer path — histogram accumulator like Buddhabrot
  • Reuse: Buddhabrot's accumulation buffer + log-density tone-map
  • Deliver: LogisticRenderer.cs (sits alongside BuddhabrotRenderer), Type combo, Math tab
  • Themes: density-histogram only; gate interior themes off

Phase A exit: 7 new 2D families, no new pipeline beyond kernel-interface mutating-c overload + bifurcation density renderer.


Phase B — 3D escape-time, new fold families (Mandelbox + KIFS)

Reuse UserBulb raymarcher (DE-based sphere tracing, normal estimation, lighting). Add new fold-style DE functions.

B.1 Mandelbox

  • Box-fold + sphere-fold + scale: z = scale · sphereFold(boxFold(z)) + c
  • Tunables: scale (default 2.0; ≈ -1.5 / 2.0 / 3.0 are classics), fixedRadius (1), minRadius (0.5)
  • DE: length(z) / |dz| with dz tracked through folds
  • ILGPU: straightforward — folds are conditional negate/scale, no transcendentals
  • Deliver: MandelboxKernel.cs (3D), MandelboxParams struct, 4 region presets (-1.5, 2, 3, +negative scale), Math tab
  • Risk: scale near critical values blows up — clamp iters, raise bailout

B.2 Kaleidoscopic IFS (KIFS) — Menger sponge + Sierpinski tetra

  • Repeated fold + scale-from-pivot. Menger: 3 axis-folds + scale-3 from (1,1,1). Sierp tetra: 4 vertex reflections + scale-2.
  • DE: (length(z) - constant) / scale^n
  • Tunables: iteration count, scale, pivot, rotation matrix
  • Two presets share single KifsKernel parameterized by fold table
  • Deliver: KifsKernel.cs, 2 built-in fold-table presets (Menger / Sierp), Params dialog tab, Math tab

B.3 Hybrid 3D (Mandelbulber-style chain)

  • Reuse User Bulb's chain editor — already lets user stack multiple Step functions
  • Action: register Mandelbox-fold + KIFS-fold + Mandelbulb-power as chain primitives in UserBulbChainPrimitives.cs
  • Users compose hybrids without code; promoted entries become Type-combo fractals
  • Deliver: 3 chain primitives + 2 worked-example chains shipped as built-ins
  • Low risk — leverages existing system

B.4 Kleinian / inversive limit sets

  • Iterated Möbius transforms (sphere inversions) in 3D
  • Complex math — defer behind B.1–B.3
  • Deliver: KleinianKernel.cs, params = inversion-sphere list (radius + center per sphere), 1 preset (Apollonian-style packing)

Phase B exit: 4 new 3D families + Mandelbulber-class composability.


Phase C — 4D / hypercomplex

New algebra layer. Mandelbulb's triplex won't suffice — need true 4D number types.

C.1 Quaternion Julia

  • q_{n+1} = q_n² + c, q ∈ ℍ
  • Reuse existing Quat from User Bulb 4D mode
  • Render: raymarch a 3D slice (fix one quaternion component as "slice w")
  • UI: Params dialog adds slice-w slider — live re-render
  • Deliver: QuatJuliaKernel.cs, slice-w param, 3 classic c presets (-0.2+0.4i+0.4j+0.4k, etc.), Math tab

C.2 Quaternion Mandelbrot

  • Same algebra, vary c per pixel
  • Deliver: QuatMandelbrotKernel.cs, slice picker, Math tab
  • Share raymarch infra with C.1

C.3 Bicomplex / hypercomplex Mandelbrot

  • Tessarine algebra (commutative, zero-divisors present)
  • New Bicomplex struct in Abstractions/Numerics/
  • Deliver: Bicomplex.cs, BicomplexMandelbrotKernel.cs, slice picker, Math tab
  • Lower priority — visually similar to quat in many slices

Phase C exit: True 4D fractals with interactive slice control.


Phase D — Geometric / stochastic (own renderers)

These don't fit escape-time. Each needs dedicated renderer.

D.1 Apollonian gasket

  • Circle packing via Descartes Circle Theorem
  • Recursive: from 3 mutually tangent circles, generate 4th, recurse
  • Renderer: tree traversal until circle radius < pixel
  • Deliver: ApollonianRenderer.cs, depth-limit param, color-by-depth, 2D only, Math tab

D.2 DLA (diffusion-limited aggregation)

  • Stochastic. Seed pixel; random-walk particles stick on contact
  • Renderer: simulate N particles, accumulate hit map
  • Determinism: seedable PRNG; cache result per (seed, N, region) — slow to compute
  • Deliver: DlaRenderer.cs, particle-count + seed params, color-by-arrival-time, Math tab
  • Risk: zoom non-trivial — pre-render at fixed grid; pan/zoom = blit cached buffer until re-sim
  • Don't support: pan/zoom-aware live re-sim (deferred)

D.3 Plasma / diamond-square

  • Procedural noise terrain — not strictly fractal but renders as one
  • Renderer: square-step + diamond-step over 2D grid, recursive midpoint displacement
  • Deliver: PlasmaRenderer.cs, roughness + seed params, 2D, Math tab
  • Themes: full gradient palette works directly

D.4 Flame fractals (Apophysis-style)

  • IFS + per-map non-linear "variation" + log-density tone-map
  • Reuse existing IFS pipeline; extend AffineMapFlameMap adding variation enum (linear, sinusoidal, spherical, swirl, horseshoe, polar, handkerchief, heart, disc, spiral, hyperbolic, diamond, ex, julia, bent, waves, fisheye, popcorn, exponential, power, cosine, rings, fan, blob, pdj, fan2, rings2, eyefish, bubble, cylinder, perspective, noise, juliaN, juliascope, blur, gaussian, radial-blur, pie, ngon, curl, rectangles, arch, tangent, square, rays, blade, secant, twintrian, cross — Apophysis stock set, 49 variations)
  • Initial cut: 8 most-used variations (linear, sinusoidal, spherical, swirl, polar, heart, disc, julia)
  • Renderer: chaos game + log-density accumulation + gamma tone-map
  • Deliver: FlameRenderer.cs, FlameMap.cs, variation enum + lookup, 6 built-in flame presets, Math tab, theme integration via density palette
  • Big phase. Plan as 3 slices: core chaos-game → variation library → tone-map + palette.

D.5 Pythagoras tree, dragon curve, Hilbert curve

  • All L-System representable. Confirm before building dedicated path — likely just add new L-System presets.
  • Deliver: 5 new L-System presets in built-in library, no code change beyond preset JSON

Phase D exit: Stochastic + geometric coverage; flame fractals = biggest user-visible feature.


Implementation order (recommendation)

Order Phase Why this slot
1 A.1 + A.2 Magnet 1/2 Single-file kernels, classic missing pair
2 A.7 Logistic Reuses Buddhabrot accumulator, big visual variety
3 A.3–A.6 Halley/Secant/Glynn/Spider Batch the small kernels
4 B.1 Mandelbox Highest user-impact 3D add; well-trodden
5 B.3 Hybrid chain primitives Leverages B.1 + existing User Bulb
6 B.2 KIFS Menger / Sierp recognizable shapes
7 C.1 Quat Julia Reuses Quat from User Bulb 4D
8 D.5 L-System presets Cheap shipping win
9 D.3 Plasma Simple renderer, broad appeal
10 D.4 Flame fractals Largest phase; 3 sub-slices
11 C.2 Quat Mandelbrot Pairs with C.1
12 D.1 Apollonian Niche but iconic
13 B.4 Kleinian Complex; do after flame infra settles
14 C.3 Bicomplex Lowest visual differentiation vs C.1/C.2
15 D.2 DLA Stochastic — caching complexity

Cross-cutting work

Theme compatibility matrix

Each new family needs entry in theme-gating table. Default rules:

  • Smooth-iter + distance themes: enable on all escape-time families (A.1–A.6, B.1–B.4, C.1–C.3)
  • Interior cycle themes: Mandelbrot-only (existing rule, no change)
  • Density-histogram themes: enable on A.7, D.2, D.4
  • 3D Phong / PBR themes: enable on B.* + C.* only when DE + normal estimation present

Help → Mathematics tabs

Each new family = one new sub-tab. Current count: 18. Post-roadmap: ~33. Reorder Math tab as 2-level (Family group → specific tab) once > 25.

Region presets

Each family ships ≥ 1 built-in region. Total new built-ins: ~25.

CalcGen reach

Phase A families that fit f(z, c) shape (A.1, A.2, A.5, A.6) should auto-flow through CalcGen 5-path generator. Verify per-kernel; bailout-radius + cardioid-skip differ.

Persistence

No new JSON files. Existing regions.json + colorthemes.json cover everything.

CLI / batch

Each FractalType added to enum becomes immediately addressable from --batch --fractal=.... Audit batch help text after each phase.

Server protocol

User-code families stay blocked. New built-ins (A–D) are server-safe — whitelist in Server/FractalGuard.cs per phase.


Out of scope (do not implement)

  • Mandelbar — = Tricorn, already shipped
  • Cubic / Quartic Mandelbrot — covered by Multibrot exponent param
  • Strange attractor variants (Lorenz, Rossler, Clifford, De Jong, Pickover) — already shipped under StrangeAttractor
  • Buddhabrot variants (Nebulabrot, anti-Buddhabrot) — extend existing Buddhabrot, not new family
  • Pickover stalks, orbit traps — coloring, not fractals; live in theme system
  • Cantor set, Koch — too trivial as standalone; L-System covers

Risk register

Risk Mitigation
Magnet pole instability Denominator-magnitude clamp; bailout 10² not 4
Mandelbox scale critical points Iter clamp + diagnostic overlay in dev
Flame fractal scope creep 3-slice plan: core / variations / tone-map. Ship slice 1 even if 2/3 deferred.
DLA pan/zoom UX Render to fixed grid; live re-sim deferred
4D slice UI complexity Single slice-w slider in Params dialog; defer arbitrary-plane slicing
Theme combinatorial explosion Auto-gate via family-tag set on each theme + family
Math help tab proliferation Two-level grouping after count > 25

Tracking

  • Branch per phase: feature/fractals-phase-a, etc.
  • Each family = own slice commit within phase branch (mirrors current Cross-platform: Phase X.2 Slice N.M convention)
  • FEATURES.md "20+ fractal families" line updates per phase
  • README badge counter for fractal count

Completion log

Implementation landed on feature/cross-platform-full rather than the per-phase branches originally planned — all 15 slices in the recommendation table merged sequentially into one branch.

Slice Status Commit Notes
A.1 Magnet 1 (Phase A bundle)
A.2 Magnet 2 (Phase A bundle)
A.3 Halley 44ff899
A.4 Secant f2a26d2
A.5 Glynn (Phase A bundle)
A.6 Spider 9b87e83 Adds IMutatingKernel overload for ref-c kernels
A.7 Logistic (Phase A bundle) Density-histogram renderer alongside Buddhabrot
B.1 Mandelbox 43d57e7 Includes AnyCPU standardisation + 3D input parity
B.2 KIFS 0f50a62 Menger + Sierpinski folds; two follow-up fixes (d91a6ab, 30a77d9)
B.3 Hybrid chain 96c310f UserBulb chain primitives
B.4 Kleinian 4316932 Tetrahedral 4-sphere preset only — see deferred section
C.1 Quat Julia 5b32fd2
C.2 Quat Mandelbrot 89beab5
C.3 Bicomplex 2532e3d Tessarine algebra inlined in calculator (no separate Bicomplex struct)
D.1 Apollonian d1261a9
D.2 DLA cb81f1b Fixed-grid render only — see deferred section
D.3 Plasma 7ad0e32
D.4 Flame 5 commits (0923d7d464d3e7) Variation library + tone-map + per-map palette + post-affine + presets
D.5 L-System presets 7c63333

Total: 19 new fractal types landed since the roadmap was written.


Deferred work (off-roadmap, lower priority)

These items are out of scope for the now-complete recommendation table but remain useful follow-ups. Capture here so a later session can pick them up without re-deriving context.

Cross-cutting (per "Cross-cutting work" section above)

  • Theme compatibility matrix audit. New families (A.1–A.7, B.1–B.4, C.1–C.3, D.1, D.2) were added without a sweep of the theme-gating table. Verify that each family's theme set matches the defaults in the existing rules (smooth-iter + distance on escape-time; density on A.7/D.2/D.4; 3D Phong on B./C. with DE). Concretely: enumerate IColorMap entries, walk each new FractalType, check the family-tag set actually gates correctly in the theme picker, and note any rules that need extending.
  • Region preset coverage audit. Roadmap target was ≥ 1 built-in region per family. Most slices ship 1–2; spot-check the count and add missing presets for any family that's bare (visual: open the Regions panel, filter by family). Total built-in regions added this round: ~25.
  • Math help tab two-level grouping. Roadmap called for two-level grouping once count > 25. Current count is ~34 sub-tabs in HostHelpContentProvider
    • matching WinForms FloatingHelp. Group by family (escape-time / fold / 4D / geometric / stochastic) so the tab strip stops scrolling off the edge of typical window widths.
  • FEATURES.md "20+ fractal families" line. Bump to ~38 (existing 20 + 19 new). Same for the README badge counter.
  • CalcGen reach verification. A.1 (Magnet 1), A.2 (Magnet 2), A.5 (Glynn), A.6 (Spider) should auto-flow through the CalcGen 5-path generator if their kernel shape matches f(z, c). Verify per kernel: bailout radius differs (10² for Magnet vs the usual 4); cardioid-skip likely off for these. If a path is missing, decide whether to add the generated calculator or document the family as scalar-only.

Per-family deferred follow-ups

  • B.4 Kleinian.

    • User-editable inversion-sphere list (currently hard-coded tetrahedral 4-sphere).
    • Alternate Schottky configurations: necklace (Indra's Pearls "tree" / "limit-circle" presets), Klein-bottle 6-sphere, Apollonian-extrusion (gasket-style limit set built from a circle inversion stack).
    • Full Möbius-group composition path so users can compose arbitrary inversion+rotation sequences and view the limit set of the resulting group, not just the inversion-only path the current calculator runs.
    • True analytic DE (vs the inversion-scale heuristic) for crisper cusps under deep zoom.
  • D.2 DLA.

    • Cached-blit pan/zoom: keep the produced grid, recompose the colour buffer when only CenterX/Y/Zoom change so the user can frame the aggregate without paying the simulation cost again.
    • Pan/zoom-aware live re-sim (continuous-domain DLA): expensive, deferred indefinitely — only worth doing if the cached-blit path proves insufficient for the user.
    • Multi-seed DLA: place several seed cells (e.g. tetrahedral on the grid corners) and let the aggregates collide. Trivial extension.
    • Sticky-coefficient mode: probability < 1 of sticking on contact, walks past attached cells. Lower stickiness → bulkier aggregate (less branched). Worthwhile parameter for visual variety.
  • C.3 Bicomplex. Visual differentiation against quaternion-Mandelbrot is low on most slices (roadmap noted this up front). If a clearer visual identity is needed, expose the second slice axis (currently hard-pinned to the k component) so the user can pick which 4D axis routes to the slice constant. Also: split-complex / coquaternion variant (k² = +1, ij = -ji = k — non-commutative) reuses the same raymarcher with a swapped product table.

  • B.2 KIFS. Only Menger and Sierpinski fold tables ship. Mandelbox- with-rotation, Octahedron, Dodecahedron folds all fit the same KifsFoldKind enum. Each is one struct field + one switch arm.

  • D.4 Flame. Eight variations of the Apophysis stock 49 ship. Adding more is mechanical (extend FlameVariation + ApplyVariation). Slice 4 of the originally-planned 3 would add the next 8–16 most-used variations and ship them as preset library updates.

  • D.1 Apollonian. The (−1, 2, 2, 3) seed packs the curvilinear cusps between the seed circles but does NOT generate circles inside the seed circles themselves — that is a property of the gasket definition, not an algorithm bug. If a "filled" rendering (sub-gaskets inside each disk) is desired, a separate seeding pass per disk would reproduce the integral packing recursively. Likely not worth the complexity vs the canonical gasket image users expect.

  • D.5 L-System. Five new presets shipped (Pythagoras tree, Dragon, Hilbert, etc.). The roadmap's full preset list called for ~10. Adding more is preset-JSON only, no code.

Slices intentionally NOT done (per "Out of scope")

These were ruled out in the original roadmap and remain so:

  • Mandelbar (= Tricorn, already shipped)
  • Cubic / Quartic Mandelbrot (covered by Multibrot exponent param)
  • Strange-attractor variants (already shipped under StrangeAttractor)
  • Buddhabrot variants (extend existing Buddhabrot, not new family)
  • Pickover stalks, orbit traps (coloring, not fractals; live in theme)
  • Cantor set, Koch curve standalone (L-System covers)

Operational follow-ups (post-implementation)

  • No allowlist failure tests for the new types yet. All 19 new types pass AllowedTypes_AreAllowed but there is no negative test for any new type — the negative path only covers UserEquation/Sandbox/ UserBulb. Probably fine because the allowlist is exclusion-based, but a single "negative test for a non-existent fractal name" would catch regressions where someone accidentally blocks a built-in.
  • No headless visual-regression baseline. The smoke renders run in CI as build-only; a per-type golden PNG (hashed pixel-count by colour bucket) would catch silent visual regressions. Worth doing once the test infrastructure for image-fixture comparisons lands.
  • CLAUDE.md UI-policy bypass risk. FractalParamsView.axaml has grown to ~600 lines of per-type IsVisible-gated panels. A future refactor could extract per-type user controls into separate *ParamsControl.axaml files. Not urgent — current layout works, just reads dense.

Clone this wiki locally