batman
This commit is contained in:
@@ -0,0 +1,127 @@
|
|||||||
|
#include <math.h>
|
||||||
|
#include <png.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/random.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user