works for distance estimates too, here are some nested units:

```

#version 460 core

#include "TwoD.frag"

vec3 color(vec2 p, vec2 dx, vec2 dy)

{

Dual1cf c = dual1cf(complexf(p), 0);

Dual1cf z = dual1cf(complexf(0));

c.d[0] = mul(c.d[0], length(vec4(dx, dy)));

float Rr = 1000.0;

float R = 0;

float rr = 0.2117;

float r;

float sr = 0.08;

float s = 0;

for (int i = 0; i < 1000; ++i)

{

if (Rr <= length(z.x) && R == 0.0)

{

R = tanh(clamp(2.0 * length(z.x) * log(length(z.x)) / length(z.d[0]), 0.0, 4.0));

break;

}

else

if (i % 3 == 0 && rr <= length(z.x) && r == 0.0)

{

r = tanh(clamp(2.0 *length(z.x)/rr * log(length(z.x)/rr) / length(z.d[0]), 0.0, 4.0));

}

else

if (i % 6 == 0 && sr <= length(z.x) && s == 0.0)

{

s = tanh(clamp(2.0 * length(z.x)/sr * log(length(z.x)/sr) / length(z.d[0]), 0.0, 4.0));

}

z = add(sqr(z), c);

}

if (length(z.x) <= Rr) return vec3(0.0);

if (0.0 < s && s < 0.5 && r < 0.5) return vec3(1.0, 1.0, 0.0);

if (0.0 < r && r < 0.5 && R < 0.5) return vec3(1.0, 0.0, 0.0);

if (0.0 < R && R < 0.5) return vec3(0.0, 0.0, 1.0);

return vec3(1.0);

}

```

Show thread

left side, binary decomposition of every 3rd iteration before z->z^2+c (starting from 0) escapes a tiny radius (~0.21) (I think this radius is related to the derivative w.r.t. z of the periodic attractor somehow)

right side, binary decomposition of every 1th iteration before z escapes a larger radius (2) (this radius is the minimal escape radius for the quadratic Mandelbrot set)

the image is of the period 3 island, rotated 90 degrees from the usual view

wondering if this might possibly be useful for computing external angles: going to the cusp on the left is .(0) and on the right is .(011) (where 0 is light and 1 is dark); the other angles of the minibrot are tuned by .(011) and .(100) relative to the top level set... dunno if it's possible to get better than O(n^2) cost though...

Got sound from Pd in UserLAnd TSVNC Xfce4 Debian Bullseye via Pulseaudio RTP VLC, all installed via f-Droid on an Android tablet. Using xvkbd to be able to type. Not yet tried patching, I expect it to be nightmarish...

Had to set latency really high and increase block size in Pd Portaudio settings to get a clean sound.

Starting to get back into practicing #livecoding in the #C programming language after months of absence.

The tones (everything but percussion) in this one are mostly:

```

samphold(&s->sh[0], sin(pow(2.0, k) * cos(30 * twopi * 64 * t +

pow(2, 4 * cos(twopi * t)) * sin(ceil(pow(4, 1 + cos(twopi * t + 0.25 * twopi *

sin(4 * twopi * t)))) * 64 * twopi * t)) * pow(2.0, cos(twopi * 16 * t) * 2.0)),

wrap(pow(4, 1 + cos(16 * twopi * t)) * wrap(400 * 64 * t)));

```

so a bit of wave shaping (first `sin()`), phase modulation (inside of first `cos()`), strange-rhythm sequencing (the `ceil()` of a wiggly function) and bitcrush (using `samphold()` to lower sample rate). Two UGENs (for want of a better concept): a 16 bar phasor for the `t` value in [0..1), and the samphold; the rest is stateless maths.

The code is duplicated with minor modifications for the other channel, and there's some simple percussion, all fed through a resonant high pass filter for the bass drone and then a multiband compressor.

Figured out how to plot wakes implicitly.

Given a wake with parameter ray angles $s_-, s_+$, for each pixel $c$ in the image trace the dynamic rays at those angles towards the Julia set: if and only if they land together, then $c$ is in the wake.

An application of Theorem 2.5 from https://arxiv.org/abs/1709.09869 "A survey on MLC, Rigidity and related topics" by Anna Miriam Benini.

Previously I had been tracing the two parameter rays into a polygonal boundary and filling that using rasterization, to do: benchmark and compare the two methods in various scenarios.

#MandelbrotSet #JuliaSet #fractal #maths #ComplexDynamics #ExternalRays

Managed to fractalize a variant based on a sheared stack of toruses (such that the ends join up into a helix). Still has assumptions about the rise per revolution being small, but it turned out well. Rendered with "Raymond", my physically-inspired raytracer, using a material similar to water but more extreme in both index of refraction and absorption coefficients.

Render at 3840x2160 with 256 subframes took about 1.5 hours. Exported from FragM in EXR format, colour balance adjusted in Darktable, cropped/framed in GNU IMP.

Show thread

If you need a lot of harmonics, it can be done in parallel (SIMD? FPGA?) by using the relations:

$$

T_{2n} = T_n^2 - 1

T_{2n+1} = T_{n+1} T_n - x

$$

For the second kind, I think you can use these ones:

$$

U_{2n-1} = 2 T_n U_{n-1}

U_{2n} = T_{2n} + x U_{2n-1}

$$

(hope I didn't make any mistakes working that out)

Show thread

Implemented bandlimited PWM via difference of two bandlimited saws (constructed by additive synthesis):

```

vec2 saw(float t)

{

float s = sin(t);

float c = cos(t);

float su = 1.0;

float sv = 2.0 * c;

float cu = 1.0;

float cv = c;

float sgn = 1.0;

int k = 1;

float sum = 0.0;

float dsum = 0.0;

while (k <= 16)

{

float term = sgn * su / float(k++);

float dterm = sgn * cu;

sum += term;

dsum += dterm;

sgn = -sgn;

float sw = 2.0 * c * sv - su; su = sv; sv = sw;

float cw = 2.0 * c * cv - cu; cu = cv; cv = cw;

}

return vec2(s * sum, dsum);

}

```

(This computes the derivative too for waveform plotting purposes.)

Show thread

Experimenting with Chebyshev polynomials to do additive synthesis based on a single sine and cosine value pair.

Rough estimate 5 floating point arithmetic operations for each additional next harmonic, of which 3 are for the polynomial recurrence and 2 are for gain and accumulation. Compared to 3 flops and 1 `sin()` call for the obvious way. The `sin()` call way can do sparse harmonics much more easily though.

Figured out the single helix version, by realizing that the line through a point to the nearest point on the surface must lie on a plane containing the axis of the helix. There are three candidate points, conceptualized as the two neighbouring arcs above and below, and the arc opposite:

```

#version 330 compatibility

#define providesColor

#include "MathUtils.frag"

#include "Complex.frag"

#include "DE-Raytracer.frag"

#group Helix

uniform float HelixD; slider[0.0,2.0,10.0]

uniform float HelixR; slider[0.0,1.0,10.0]

uniform float Helixr; slider[0.0,0.5,10.0]

uniform float time;

float DE(vec3 q)

{

q.z += time * 2.0 * PI * HelixD;

float dz = mod(q.z + HelixD * atan(q.y, q.x) + PI * HelixD, 2.0 * PI * HelixD) - PI * HelixD;

float xy = length(q.xy);

float d1 = length(vec2(xy - HelixR, dz - PI * HelixD));

float d2 = length(vec2(xy + HelixR, dz));

float d3 = length(vec2(xy - HelixR, dz + PI * HelixD));

return min(min(d1, d2), d3) - Helixr;

}

vec3 baseColor(vec3 q, vec3 n)

{

return vec3(0.5) + 0.5 * cross(n, normalize(vec3(-1.0, 1.0, -1.0)));

}

```

Show thread

Implemented a double helix #DistanceEstimate based on an idea from #FragM's `Knot.frag` (not knighty's, the other one, based on forum posts by DarkBeam).

Not sure how to #fractal-ize it, wanted to turn it into a #helix of helices of helices etc. Nor how to make it a single helix (I only managed to colour the two halves individually...).

I think each strand is an Archimedean Serpentine, but I'm not 100% sure on terminology..

```

#version 330 compatibility

#define providesColor

#include "MathUtils.frag"

#include "Complex.frag"

#include "DE-Raytracer.frag"

#group Helix

uniform float HelixD; slider[0.0,2.0,10.0]

uniform float HelixR; slider[0.0,1.0,10.0]

uniform float Helixr; slider[0.0,0.5,10.0]

uniform float time;

float DE(vec3 q)

{

q.z += HelixD * time;

float t = (mod(q.z / HelixD + 0.5, 1.0) - 0.5) * 2.0 * PI;

q.xy *= mat2(cos(t), sin(t), -sin(t), cos(t));

q.z = 0;

float s = atan(HelixD / (2.0 * PI), HelixR);

q.yz *= mat2(cos(s), -sin(s), sin(s), cos(s));

return length(vec2(length(q.xy) - HelixR, q.z)) - Helixr;

}

vec3 baseColor(vec3 q, vec3 n)

{

q.z += HelixD * time;

float t = (mod(q.z / HelixD + 0.5, 1.0) - 0.5) * 2.0 * PI;

q.xy *= mat2(cos(t), sin(t), -sin(t), cos(t));

return vec3(0.5) + 0.5 * sign(q.x) * n;

}

```

#noisevember #novembeat #noisevembeat 18th

rhythmic beeping

source code composed in https://mathr.co.uk/barry/v2/ , rendered to WAV using barry command line version, trimmed to first 2^22 samples using Audacity, encoded with LAME.

```

: audio { c t -- o }

t t 0x401 c 2 * - * 17 t 16 >> 3 & + >> 0x11 t 18 >> 0xF & 1 + * & <<

i8

;

RUN audio

1 -> increment

0 -> time

```

Show thread

#noisevember #novembeat #noisevembeat 17th

modulating PWM drone with echoed high pitched things and various fast kicks (with a bit of DC offset, sorry)

source code composed in https://mathr.co.uk/barry/v2/ , rendered to WAV using barry command line version.

```

: dup { x -- x x }

x x

;

: env { a t -- a }

a t ~ 0x7FFF & dup * 15 >> dup * 15 >> * 15 >>

;

: audio { c t | r s -- o }

t 15 >> 3 2 c * + * 7 & 6 % 1 + -> r

t 256 r + * 9 >> 0xFF & t 256 r - * 9 >> 0xFF & - 1 >>

r t t t * * * 0xFF & i8 i64 -> s

s 2 * 0xFF & i8 i64 t 0x4000 - env 0 >>

s 3 * 0xFF & i8 i64 t 0x7000 - env 1 >>

s 5 * 0xFF & i8 i64 t 0xA000 - env 2 >>

+ + t 14 >> 7 & 7 != *

r t * ~ 0x3FFF & dup * 15 >> dup * 15 >> 0x7F & 0x40 - t 20 >> 3 & 0 != *

+ t 19 >> 3 & 0 != *

+ 1 >>

i8

;

RUN audio

1 -> increment

0 -> time

```

(Previous one was 14th.)

Show thread

#noisevember 14th

(Loud noise with some high frequencies and no dynamic variation.)

Composed in https://mathr.co.uk/barry/v2/ , rendered in barry command line.

Reminds me of an electric train changing up gears when leaving a station.

Attached is just an excerpt of the start (first 2^23 samples), it continues indefinitely (technically, it will repeat after at most 2^64 samples, due to arbitrary computational limit).

Source code:

```

: wave { c t n -- o }

t t 1 n << 1 2 c * - - * n >> c 0 ~ * ^ * 1 n << 1 2 c * - + * n >> i8

;

: audio { c t -- o }

c t 19 wave

c t 18 wave

c t 17 wave

c t 16 wave

^ ^ ^

;

RUN audio

1 -> increment

0 -> time

```

(Last one I did was on the 3rd, not made enough time for noisevember this year...)

Show thread

#kf 2.15.1.3 (prerelease, not yet final) running on #ReactOS 0.4.13 (all 32bit, in VirtualBox, single core).

Getting ReactOS working was a chore until I followed their instructions precisely (had no joy with QEMU at all).

Tempted to try it on an old Pentium4 desktop I have here, will see if there are Windows XP-era drivers for its graphics card still available from reputable sites...

Show thread

#noisevember #novembeat #noisevembeat 3rd

```

: audio { c t -- o } t t 3 >> c 0 ~ * ^ + 0xF & t t 7 >> 3 & 1 + >> t 16 t 18 >> 7 & - >> 3 & 4 + & 3 * 7 & 1 + * t ~ 10 >> 0xF & * 4 >> t 0xFF & t ~ 7 t 18 >> 7 & + >> 0x1F & * 6 >> + 1 >> i8 ;

RUN audio

1 -> increment

0 -> time

```

composed with https://mathr.co.uk/barry/v2/

recorded with barry command line tool (fixed the bug that had broken it)

trimmed and DC offset removed with Audacity

encoded with LAME

(I made no noisevembeat 2nd)

Show thread

#noisevember #novembeat #noisevembeat 1st

```

: audio { c t -- o } t t 14 >> c 0 ~ * ^ + 0x3F & t t 15 >> 3 & 13 + >> 7 & 5 * 7 & 1 + * t ~ 8 >> 0x3F & * 6 >> t t ~ 8 >> 0x3F & * 6 >> ^ i8 ;

RUN audio

1 -> increment

0 -> time

```

composed with

https://mathr.co.uk/barry/v2/

recorded from Firefox with parec

trimmed with Audacity

encoded with LAME

https://mathr.co.uk/zoomasm

I released #zoomasm version 1.0 "felicitats" yesterday. It's a tool for assembling #fractal #zoom #animation #video from exponential strip keyframes with RGB and/or raw iteration data in EXR format - the colouring is controlled by an #OpenGL #GLSL #fragment #shader snippet with a few presets included (or write your own).

(However, the only software I know of that can export keyframes for input to zoomasm, is #kf 2.15 branch which is not yet released... so getting that done is my new focus.)

making art with maths and algorithms

Joined May 2018