the boundary conditions also constrain it within the frame. can also add additional constraints, like the hole in this one. obvious next step is reading a mask from a bitmap graphic file instead of defining it with code.

Show thread

Part of the algorithm is solving the Laplace equation for electric field strength. I do this by repeatedly applying boundary conditions, blurring, and normalizing. Typically I do 16 or more iterations of this between each next point selection and plotting, because when doing only 2 the image looks weird. But I somehow like the effect, not sure how to control it better...

Show thread

tweaked some parameters and it went all weird - this one adds (alpha * (number of boundary pixels) ^ beta) new points each step, with alpha = 0.5 and beta = 0.25.

Show thread

something went bad in this one (power 10), don't know why the thicker vertical/horizontal lines are there... they're not there in the previous image with 1/2 the iterations, but the texture is not so full....

Show thread

./ts i.wav o.wav

#include <complex.h>

#include <math.h>

#include <sndfile.h>

#include <fftw3.h>

#define C 2

#define F 65536

#define A 2048

#define J 1

#define O (A/4)

double w[A],a[A][C],b[A][C];double _Complex p[F],q[F],r[C][F],u[C][F],v[C][F];int main(int K,char**V){SF_INFO m={0};SNDFILE*f=sf_open(V[1],SFM_READ,&m);SF_INFO n={0,m.samplerate,m.channels,SF_FORMAT_WAV|SF_FORMAT_FLOAT,0,0};SNDFILE*g=sf_open(V[2],SFM_WRITE,&n);fftw_plan T=fftw_plan_dft_1d(F,p,q,FFTW_FORWARD,FFTW_PATIENT|FFTW_DESTROY_INPUT);fftw_plan S=fftw_plan_dft_1d(F,q,p,FFTW_BACKWARD,FFTW_PATIENT|FFTW_DESTROY_INPUT);for(int i=0;i<A;++i)w[i]=(0.5-0.5*cos(6.283185307179586*i/A))*8.2e-3;for(int c=0;c<C;++c)for(int i=0;i<F;++i){r[c][i]=0;u[c][i]=0;v[c][i]=1;}while(A==sf_readf_double(f,&a[0][0],A)){sf_seek(f,J-A,SEEK_CUR);for(int c=0;c<C;++c){for(int i=0;i<A;++i){if(i<A-O)b[i][c]=b[i+O][c];else b[i][c]=0;}for(int i=0;i<A;++i)p[i]=w[i]*a[i][c];for(int i=A;i<F;++i)p[i]=0;fftw_execute(T);for(int i=0;i<F;++i){r[c][i]=u[c][i];u[c][i]=q[i];double _Complex l0=u[c][i]/r[c][i];l0/=cabs(l0);double _Complex l=l0;for(int s=O/J;s>1;s>>=1)l*=l;v[c][i]*=l;v[c][i]/=cabs(v[c][i]);if(v[c][i]==0||!(v[c][i]==v[c][i])||isinf(cabs(v[c][i])))v[c][i]=1;q[i]=cabs(u[c][i])*v[c][i];}fftw_execute(S);for(int i=0;i<A;++i)b[i][c]+=w[i]*p[i];}sf_writef_double(g,&b[0][0],O);}return 0;}

Seaside sunrise at the end of July.

Process: In GNU IMP: downscale photo to 10%, convert to indexed palette with 6 colours, convert back to RGB, perform edge detection with Laplace operator (border policy white), invert colours, threshold at (1,255) to black and white (as much white as possible). Then save as PPM and run potrace from the command line, without any options, giving an EPS file with the same stem. Load this back into GNU IMP, at 600dpi with strong antialiasing settings. Downscale to 720p greyscale JPEG for web, keep the high resolution for printing (445dpi fits nicely on A4 paper, with 15mm border on left/right/top (bigger bottom border).

Working on some music stuff, thinking of algorithms that might work nicely on an #Amiga #A500 or #A500Plus (currently implemented in C on a modern machine, but it uses 16bit integer maths for the most part, probably needs optimisations to replace divisions with faster things).

There are 3 tables of 16384 signed 8-bit audio data, which get repeatedly filtered in-place by some hacky moving average stuff while they are played in a loop.

For the final version I'll probably end up reimplementing it in inline-assembler in Amiga E.

Number of walks within N^3 (the first octant of Z^3) starting at (0,0,0) and consisting of n steps taken from {(-1, -1, 1), (-1, 0, 0), (0, 1, 1), (1, 0, -1), (1, 0, 1)}.

a(6) = 2021

#TwentyTwentyOne #calendar #anaglyph #stereoscopic

Show thread

making art with maths and algorithms

Joined May 2018