1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
#include "fractals.h"
#include <math.h>
#include "precision.h"
#include "grids.h"
/*
* Computes the number of iterations it takes for a point z0 to become unbounded
* if the return value is equal to max_iterations, the point lies within the mandelbrot set
* This is an implementation the escape algorithm
*/
size_t mandelbrot(const CBASE complex z0, const size_t max_iterations) {
CBASE complex z = z0;
size_t iteration = 0;
while (CABS(z) <= 2 && iteration < max_iterations) {
z = z * z + z0;
iteration++;
}
return iteration;
}
/*
* Fills a grid with mandelbrot values
*/
void mandelbrot_grid(grid_t* grid, const size_t max_iterations){
const size_t size = grid->size;
size_t* data = grid->data;
for(size_t i = 0; i < size; i++){
data[i] = mandelbrot(grid_to_complex(grid, i), max_iterations);
}
}
/*
* Computes the number of iterations it takes for a point z0 to become unbounded
* if the return value is equal to max_iterations, the point lies within the tricorn set
* This is nearly identical to mandelbrot, except for the complex conjugate
*/
size_t tricorn(const CBASE complex z0, const size_t max_iterations){
CBASE complex z = z0;
size_t iteration = 0;
while(CABS(z) <= 2 && iteration < max_iterations){
z = CONJ(z * z) + z0;
iteration++;
}
return iteration;
}
/*
* Fills a grid with tricorn values
*/
void tricorn_grid(grid_t* grid, const size_t max_iterations){
const size_t size = grid->size;
size_t* data = grid->data;
for(size_t i = 0; i < size; i++){
data[i] = tricorn(grid_to_complex(grid, i), max_iterations);
}
}
/*
* Computes the number of iterations it takes for a point z0 to become unbounded
* if the return value is equal to max_iterations, the point lies within the burningship set (oh no! I hope they have fire safety gear)
*/
size_t burning_ship(const CBASE complex z0, const size_t max_iterations) {
CBASE complex z = z0;
CBASE complex z_mod;
size_t iteration = 0;
while (CABS(z) <= 2 && iteration < max_iterations) {
z_mod = RABS(CREAL(z)) + RABS(CIMAG(z))*I;
z = z_mod * z_mod + z0;
iteration++;
}
return iteration;
}
/*
* Fills a grid with burning_ship values
*/
void burning_ship_grid(grid_t* grid, const size_t max_iterations){
const size_t size = grid->size;
size_t* data = grid->data;
for(size_t i = 0; i < size; i++){
data[i] = burning_ship(grid_to_complex(grid, i), max_iterations);
}
}
/*
* Computes the number of iterations it takes for a point z0 to become unbounded
* if the return value is equal to max_iterations, the point lies within the multibrot set
* This is implementation closely matches mandelbrot, but uses cpow which might degrade performance.
*/
size_t multibrot(const CBASE complex z0, const size_t max_iterations, const double d){
CBASE complex z = z0;
size_t iteration = 0;
while(CABS(z) <= 2 && iteration < max_iterations){
z = CPOW(z, d) + z0;
iteration++;
}
return iteration;
}
/*
* Fills a grid with multibrot values
*/
void multibrot_grid(grid_t* grid, const size_t max_iterations, const double d){
const size_t size = grid->size;
size_t* data = grid->data;
for(size_t i = 0; i < size; i ++){
data[i] = multibrot(grid_to_complex(grid, i), max_iterations, d);
}
}
/*
* Computes the number ofiterations it takes for a point z0 to become unbounded
* if the return value is equal to max_iterations, the point lies within the multicorn set
* This function is to tricorn as multibrot is to mandelbrot
*/
size_t multicorn(const CBASE complex z0, const size_t max_iterations, const double d){
CBASE complex z = z0;
size_t iteration = 0;
while(CABS(z) <= 2 && iteration < max_iterations){
z = CONJ(CPOW(z, d)) + z0;
iteration++;
}
return iteration;
}
/*
* Fills a grid with multicorn values
*/
void multicorn_grid(grid_t* grid, const size_t max_iterations, const double d){
const size_t size = grid->size;
size_t* data = grid->data;
for(size_t i = 0; i < size; i ++){
data[i] = multicorn(grid_to_complex(grid, i), max_iterations, d);
}
}
/*
* Computes ????? for a julia set
* implementation of https://en.wikipedia.org/wiki/Julia_set#Pseudocode
*
* This behaves weirdly, needs a very small number of iterations to be visibile
*/
size_t julia(const CBASE complex z0, const CBASE complex c, const size_t max_iterations, const double R){
double complex z = z0;
size_t iteration = 0;
while(CABS(z) < R && iteration < max_iterations){
z = z * z + c;
iteration++;
}
return iteration;
}
void julia_grid(grid_t* grid, const size_t max_iterations, const CBASE complex c, const double R){
const size_t size = grid->size;
size_t* data = grid->data;
for(size_t i = 0; i <size; i++){
data[i] = julia(grid_to_complex(grid, i), c, max_iterations, R);
}
}
|