commit b85f911e3e4e8ba837d55cf79a8af395fcf1b3d6ccad3e951650371a9c2a2fd2 Author: dxrknesss Date: Wed Nov 5 13:54:55 2025 +0200 batman diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..f51586f --- /dev/null +++ b/.clangd @@ -0,0 +1,6 @@ +CompileFlags: + Add: + - "-std=c23" + - "-xc" + Remove: + - "-std=c++*" diff --git a/main b/main new file mode 100755 index 0000000..7811caf Binary files /dev/null and b/main differ diff --git a/main.c b/main.c new file mode 100644 index 0000000..39db739 --- /dev/null +++ b/main.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include +#include +#include + +float noise(float x, float y); +float linear_interpolation(float a, float b, float t); +float quintic_curve(float t); +float dot_product(float a[], float b[]); +float *pseudo_random_gradient_vector_get(float x, float y); + +static unsigned char random_bytes[1024]; + +int main() { + int n = getrandom(random_bytes, 1024, 0); + if (n != 1024) { + fprintf(stderr, "err: getrandom didn't work out as planned\n"); + return 1; + } + + int width = 1024, height = 1024; + + png_image img; + memset(&img, 0, sizeof(img)); + img.format = PNG_FORMAT_GRAY; + img.width = width; + img.height = height; + img.version = PNG_IMAGE_VERSION; + + unsigned char *buffer; + printf("PNG IMAGE SIZE: %u\n", PNG_IMAGE_SIZE(img)); + buffer = malloc(PNG_IMAGE_SIZE(img)); + + for (int x = 0; x < height; ++x) { + for (int y = 0; y < width; ++y) { + float noise_val = noise(x * 0.05, y * 0.05); + unsigned char pixel = (unsigned char)((noise_val + 1.0f) * 127.5f); + + buffer[y + x * width] = pixel; + } + } + + png_image_write_to_file(&img, "noise.png", 0, buffer, 0, NULL); + + free(buffer); +} + +float noise(float x, float y) { + int left = floorf(x); + int top = floorf(y); + + float point_in_quad_x = x - left; + float point_in_quad_y = y - top; + + float *top_left_gradient = pseudo_random_gradient_vector_get(left, top); + float *top_right_gradient = pseudo_random_gradient_vector_get(left + 1, top); + float *bottom_left_gradient = + pseudo_random_gradient_vector_get(left, top + 1); + float *bottom_right_gradient = + pseudo_random_gradient_vector_get(left + 1, top + 1); + + float distance_to_top_left[] = {point_in_quad_x, point_in_quad_y}; + float distance_to_top_right[] = {point_in_quad_x - 1, point_in_quad_y}; + float distance_to_bottom_left[] = {point_in_quad_x, point_in_quad_y - 1}; + float distance_to_bottom_right[] = {point_in_quad_x - 1, point_in_quad_y - 1}; + + float tx1 = dot_product(distance_to_top_left, top_left_gradient); + float tx2 = dot_product(distance_to_top_right, top_right_gradient); + float bx1 = dot_product(distance_to_bottom_left, bottom_left_gradient); + float bx2 = dot_product(distance_to_bottom_right, bottom_right_gradient); + + point_in_quad_x = quintic_curve(point_in_quad_x); + point_in_quad_y = quintic_curve(point_in_quad_y); + + float tx = linear_interpolation(tx1, tx2, point_in_quad_x); + float bx = linear_interpolation(bx1, bx2, point_in_quad_x); + float tb = linear_interpolation(tx, bx, point_in_quad_y); + + free(top_left_gradient); + free(top_right_gradient); + free(bottom_left_gradient); + free(bottom_right_gradient); + + return tb; +} + +float linear_interpolation(float a, float b, float t) { + return a + (b - a) * t; +} + +float quintic_curve(float t) { return t * t * t * (t * (t * 6 - 15) + 10); } + +float dot_product(float a[2], float b[2]) { return a[0] * b[0] + a[1] * b[1]; } + +float *pseudo_random_gradient_vector_get(float x, float y) { + float *a; + a = malloc(sizeof *a * 2); + + int xi = (int)x & 1023; + int yi = (int)y & 1023; + + int hash = random_bytes[(random_bytes[xi] + yi) & 1023]; + int v = hash & 3; + + switch (v) { + case 0: + a[0] = 1; + a[1] = 0; + break; + case 1: + a[0] = -1; + a[1] = 0; + break; + case 2: + a[0] = 0; + a[1] = 1; + break; + case 3: + a[0] = 0; + a[1] = -1; + break; + } + + return a; +}