Skip to content

Commit e44da19

Browse files
authored
Add files via upload
1 parent e7a3056 commit e44da19

File tree

6 files changed

+307
-0
lines changed

6 files changed

+307
-0
lines changed

cellular_automata/cellular_automata.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#include <stdlib.h>
2+
#include <stdbool.h>
3+
#include "cellular_automata.h"
4+
5+
bool is_within_map_bounds(int y, int x, bool ** map, int size){
6+
if (y < 0 || x < 0 || y >= size || x >= size){
7+
return false;
8+
}
9+
return true;
10+
}
11+
12+
void copy_bool_map(bool ** dest, bool ** src, int size){
13+
for (int i = 0; i < size; i ++){
14+
for (int j = 0; j < size; j ++){
15+
dest[i][j] = src[i][j];
16+
}
17+
}
18+
}
19+
20+
void cellular_automata(bool ** map, int size, int iterations){
21+
int f_count;
22+
bool ** temp_map = (bool **)calloc(size, sizeof(bool *));
23+
for (int i = 0; i < size; i ++){
24+
temp_map[i] = (bool *)calloc(size, sizeof(bool));
25+
}
26+
27+
for (int i = 0; i < iterations; i ++){
28+
copy_bool_map(temp_map, map, size);
29+
for (int j = 0; j < size; j ++){
30+
for (int k = 0; k < size; k ++){
31+
f_count = 0;
32+
for (int y = j - 1; y <= j + 1; y ++){
33+
for (int x = k - 1; x <= k + 1; x ++){
34+
if (is_within_map_bounds(y, x, map, size)){
35+
if (y != j || x != k){
36+
if (!temp_map[y][x]){
37+
f_count ++;
38+
}
39+
}
40+
}
41+
else {
42+
f_count ++;
43+
}
44+
}
45+
}
46+
if (f_count > 4){
47+
map[j][k] = 0;
48+
}
49+
else {
50+
map[j][k] = 1;
51+
}
52+
}
53+
}
54+
}
55+
for (int i = 0; i < size; i ++){
56+
free(temp_map[i]);
57+
}
58+
free(temp_map);
59+
}
60+
61+
bool ** generate_cellular_automata(int seed, int density, int size, int iterations){
62+
srand(seed);
63+
bool ** map = (bool **)calloc(size, sizeof(bool *));
64+
for (int i = 0; i < size; i ++){
65+
map[i] = (bool *)calloc(size, sizeof(bool));
66+
for (int j = 0; j < size; j ++){
67+
map[i][j] = rand()%101 > density;
68+
}
69+
}
70+
cellular_automata(map, size, iterations);
71+
return map;
72+
}

cellular_automata/cellular_automata.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <stdbool.h>
2+
3+
#ifndef CELLULAR_AUTOMATA_H
4+
#define CELLULAR_AUTOMATA_H
5+
6+
bool is_within_map_bounds(int, int, bool **, int);
7+
void copy_bool_map(bool **, bool **, int);
8+
void cellular_automata(bool **, int, int);
9+
bool ** generate_cellular_automata(int, int, int, int);
10+
11+
#endif // !CELLULAR_AUTOMATA_H

value_noise/value_noise.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include <stdlib.h>
2+
#include <math.h>
3+
#include "value_noise.h"
4+
5+
// returns a value between a and b
6+
// x is a floating point number between 0 and 1
7+
// x = 0 returns a and x = 1 returns b
8+
float interpolation_cosine(float a, float b, float x){
9+
float ft = x * M_PI;
10+
float f = (1 - cos(ft)) * .5;
11+
12+
return a * (1 - f) + b * f;
13+
}
14+
15+
// function for initializing a square consisting of points gained by interpolating between the (known) corner values
16+
// uses the method for bilinear interpolation but with cosine interpolation instead of linear interpolation
17+
// initializes values on 2 axes (every vertical value for start_x and end_x) and interpolates between them
18+
void interpolation_2D(float ** map, int start_y, int start_x, int end_y, int end_x){
19+
for (int i = start_y; i <= end_y; i ++){
20+
map[i][start_x] = interpolation_cosine(map[start_y][start_x], map[end_y][start_x], (double)(i - start_y)/(end_y - start_y));
21+
map[i][end_x] = interpolation_cosine(map[start_y][end_x], map[end_y][end_x], (double)(i - start_y)/(end_y - start_y));
22+
for (int j = start_x; j <= end_x; j ++){
23+
map[i][j] = interpolation_cosine(map[i][start_x], map[i][end_x], (double)(j - start_x)/(end_x - start_x));
24+
}
25+
}
26+
}
27+
28+
// sometimes some values in the final generated noise map may be greater than one
29+
// we don't want that, since it makes the map quite inconvenient to display
30+
// this functions takes the generated noise map and normalises the values
31+
// the biggest value found in the map is set to 1 and the smallest to 0
32+
// all other values are asigned accordingly
33+
void normalize_noise(float ** map, int size){
34+
float maxi = map[0][0];
35+
float mini = map[0][0];
36+
for (int i = 0; i < size; i ++){
37+
for (int j = 0; j < size; j ++){
38+
if (map[i][j] > maxi){
39+
maxi = map[i][j];
40+
}
41+
if (map[i][j] < mini){
42+
mini = map[i][j];
43+
}
44+
}
45+
}
46+
float dif = maxi - mini;
47+
for (int i = 0; i < size; i ++){
48+
for (int j = 0; j < size; j ++){
49+
map[i][j] = (map[i][j] - mini)/dif;
50+
}
51+
}
52+
}
53+
54+
// initializes the value noise 2D array
55+
float ** value_noise(float ** noise_map, int size, int octaves, double scaling_factor){
56+
float ** gen_map = (float **)calloc(size, sizeof(float *));
57+
for (int i = 0; i < size; i ++){
58+
gen_map[i] = (float *)calloc(size, sizeof(float));
59+
}
60+
61+
int pitch;
62+
double persistance = 1;
63+
64+
for (int o = 0; o <= octaves; o ++){
65+
pitch = (int)(size - 1)/pow(2, o);
66+
for (int i = 0; i < size; i += pitch){
67+
for (int j = 0; j < size; j += pitch){
68+
gen_map[i][j] += noise_map[i][j] * persistance;
69+
}
70+
}
71+
for (int i = 0; i < size - pitch; i += pitch){
72+
for (int j = 0; j < size - pitch; j += pitch){
73+
interpolation_2D(gen_map, i, j, i + pitch, j + pitch);
74+
}
75+
}
76+
persistance /= scaling_factor;
77+
}
78+
normalize_noise(gen_map, size);
79+
return gen_map;
80+
}
81+
82+
// generates a square 2D value noise array (the array size has to be equal to 2^n + 1 and the octave count must be <= n)
83+
// couldn't be bothered to implement error handling, so for the love of God input the right values!
84+
float ** generate_value_noise(int seed, int size, int octaves, double scaling_factor){
85+
srand(seed);
86+
float ** nmap = (float **)calloc(size, sizeof(float *));
87+
for (int i = 0; i < size; i ++){
88+
nmap[i] = (float *)calloc(size, sizeof(float));
89+
for (int j = 0; j < size; j ++){
90+
nmap[i][j] = rand()%10001/1000.;
91+
}
92+
}
93+
float ** gmap = value_noise(nmap, size, octaves, scaling_factor);
94+
for (int i = 0; i < size; i ++){
95+
free(nmap[i]);
96+
}
97+
free(nmap);
98+
99+
return gmap;
100+
}

value_noise/value_noise.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef VALUE_NOISE_H
2+
#define VALUE_NOISE_H
3+
4+
float interpolation_cosine(float, float, float);
5+
void interpolation_2D(float **, int, int, int, int);
6+
void normalize_noise(float **, int);
7+
float ** value_noise(float **, int, int, double);
8+
float ** generate_value_noise(int, int, int, double);
9+
10+
#endif // !VALUE_NOISE_H

voronoi/voronoi.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#include <stdlib.h>
2+
#include <math.h>
3+
#include <stdbool.h>
4+
#include "voronoi.h"
5+
6+
float minkowski_distance(int ay, int ax, int by, int bx, int p){
7+
switch (p){
8+
case 1:
9+
return abs(by - ay) + abs(bx - ax);
10+
case 2:
11+
return sqrt(pow(by - ay, 2) + pow(bx - ax, 2));
12+
default:
13+
return pow(pow(abs(ay - by), p) + pow(abs(ax - bx), p), 1./p);
14+
}
15+
}
16+
17+
site get_center(int start_y, int start_x, int pitch){
18+
site result;
19+
result.y = abs(2 * start_y + pitch) / 2;
20+
result.x = abs(2 * start_x + pitch) / 2;
21+
return result;
22+
}
23+
24+
site * get_center_array(int size, int divisions){
25+
site * center_array = (site *)calloc(pow(4, divisions), sizeof(site));
26+
int pitch = (size - 1)/pow(2, divisions);
27+
int index = 0;
28+
for (int i = 0; i < size - pitch; i += pitch){
29+
for (int j = 0; j < size - pitch; j += pitch){
30+
center_array[index].y = (2 * i + pitch)/2;
31+
center_array[index].x = (2 * j + pitch)/2;
32+
index ++;
33+
}
34+
}
35+
return center_array;
36+
}
37+
38+
void move_centers(int seed, site * center_array, int center_quantity){
39+
srand(seed);
40+
bool movement_down;
41+
bool movement_right;
42+
int max_movement = center_array[0].x;
43+
for (int i = 0; i < center_quantity; i ++){
44+
movement_down = rand()%101 > 50;
45+
movement_right = rand()%101 > 50;
46+
if (movement_down){
47+
center_array[i].y += rand()%max_movement;
48+
}
49+
else{
50+
center_array[i].y -= rand()%max_movement;
51+
}
52+
if (movement_right){
53+
center_array[i].x += rand()%max_movement;
54+
}
55+
else{
56+
center_array[i].x -= rand()%max_movement;
57+
}
58+
}
59+
}
60+
61+
short get_closest_site(int y, int x, site * sites, int site_quantity, int p){
62+
float min;
63+
short index;
64+
float * distances = (float *)calloc(site_quantity, sizeof(float));
65+
min = minkowski_distance(y, x, sites[0].y, sites[0].x, p);
66+
index = 0;
67+
for (int i = 0; i < site_quantity; i++){
68+
distances[i] = minkowski_distance(y, x, sites[i].y, sites[i].x, p);
69+
if (distances[i] < min){
70+
min = distances[i];
71+
index = i;
72+
}
73+
}
74+
return index;
75+
}
76+
77+
void voronoi_diagram(short ** map, int size, site * sites, int site_quantity, int p){
78+
for (int i = 0; i < size; i ++){
79+
for (int j = 0; j < size; j ++){
80+
map[i][j] = get_closest_site(j, i, sites, site_quantity, p);
81+
}
82+
}
83+
}
84+
85+
short ** generate_voronoi_diagram(int seed, int size, int divisions, int p){
86+
srand(seed);
87+
short ** map = (short **)calloc(size, sizeof(short *));
88+
for (int i = 0; i < size; i ++){
89+
map[i] = (short *)calloc(size, sizeof(short));
90+
}
91+
site * centarr = get_center_array(size, divisions);
92+
int cent_q = pow(4, divisions);
93+
move_centers(seed, centarr, cent_q);
94+
voronoi_diagram(map, size, centarr, cent_q, p);
95+
96+
free(centarr);
97+
return map;
98+
}

voronoi/voronoi.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef VORONOI_H
2+
#define VORONOI_H
3+
4+
typedef struct site{
5+
int y;
6+
int x;
7+
} site;
8+
9+
site get_center(int, int, int);
10+
site * get_center_array(int, int);
11+
void move_centers(int, site *, int);
12+
short get_closes_site(int, int, site *, int, int);
13+
void voronoi_diagram(short **, int, site *, int, int);
14+
short ** generate_voronoi_diagram(int, int, int, int);
15+
16+
#endif // !VORONOI_H

0 commit comments

Comments
 (0)