/* 2022-11-04 * * inspired by https://arxiv.org/abs/2210.17320 * The Kochawave curve, a variant of the Koch curve * Rémy Sigrist * * gcc -Wall -o koch koch.c -lm * ./koch |./gui -w 160 -h 90 -scale4 -bgra -stdout > XX * ffmpeg -f rawvideo -s 640x360 -r 25 -pix_fmt bgra -i XX -vf palettegen palette.png * ffmpeg -f rawvideo -s 640x360 -r 25 -pix_fmt bgra -i XX -i palette.png -filter_complex paletteuse koch.gif * * gui.c is at http://sedcore.eu.org/small/gui.c */ #include #include typedef struct { unsigned char r, g, b; } color_t; unsigned char screen[160*90*4]; void point(int x, int y, color_t color) { y = 90 - y; if (x < 0 || x > 159 || y < 0 || y > 89) return; screen[(y * 160 + x) * 4] = color.b; screen[(y * 160 + x) * 4 + 1] = color.g; screen[(y * 160 + x) * 4 + 2] = color.r; } void koch(float x1, float y1, float x2, float y2, int frame) { float x3, y3; float x4, y4; float x5, y5; if (fabs(x1-x2) < .5 && fabs(y1-y2) < .5) { point(x1, y1, (color_t){192,0,0}); return; } x3 = x1 + (x2 - x1) / 3; y3 = y1 + (y2 - y1) / 3; x5 = x2 - (x2 - x1) / 3; y5 = y2 - (y2 - y1) / 3; x4 = x5 - x3; y4 = y5 - y3; /* cos + isin * x + iy = cos x - sin y + i sin x + cos y */ float c = 1. / 2; float s = sqrt(3) / 2; float x4n = c * x4 - s * y4; float y4n = s * x4 + c * y4; x4 = x4n + x3; y4 = y4n + y3; double angle = atan2(y2-y1, x2-x1); double length = sqrt((y2-y1)*(y2-y1) + (x2-x1)*(x2-x1)) * 2./3; float f = cos(2 * M_PI * frame / 100); float g = sin(2 * M_PI * frame*2 / 100); float x = f * length / 2; float y = g * length / 2. / 4.; c = cos(angle); s = sin(angle); float xn = c * x - s * y; float yn = s * x + c * y; x4 += xn; y4 += yn; koch(x1, y1, x3, y3, frame); koch(x3, y3, x4, y4, frame); koch(x4, y4, x5, y5, frame); koch(x5, y5, x2, y2, frame); } void clear(void) { unsigned char *s = screen; int i; for (i = 0; i < 160*90; i++, s+=4) { s[0] = 203; s[1] = 192; s[2] = 255; s[3] = 255; } } void dump(void) { fwrite(screen, 160*90*4, 1, stdout); } int main(void) { int frame = 0; while (frame < 100) { clear(); koch(0, 10, 160, 10, frame); dump(); frame++; } fflush(stdout); return 0; }