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

```
460 core

"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));
}
}
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);
}
```

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...

Clive works too, but the latency is huge.

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.

I got my fractal explorer working on my tablet. Was not easy. UI is a bit laggy and its hard to use as fingers obscure the screen. Maybe a stylus would help.

Starting to get back into practicing in the 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 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.

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.

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)

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.)

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:

```
330 compatibility

providesColor
"MathUtils.frag"
"Complex.frag"
"DE-Raytracer.frag"

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)));
}
```

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

Not sure how to -ize it, wanted to turn it into a 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..

```
330 compatibility

providesColor
"MathUtils.frag"
"Complex.frag"
"DE-Raytracer.frag"

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;
}
```

rhythmic beeping

source code composed in 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
```

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

source code composed in 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.)

14th

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

Composed in 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...)

2.15.1.3 (prerelease, not yet final) running on 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...

```
: 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 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

```
: 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
mathr.co.uk/barry/v2/
recorded from Firefox with parec
trimmed with Audacity
encoded with LAME

mathr.co.uk/zoomasm
I released version 1.0 "felicitats" yesterday. It's a tool for assembling from exponential strip keyframes with RGB and/or raw iteration data in EXR format - the colouring is controlled by an 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 2.15 branch which is not yet released... so getting that done is my new focus.)