-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsamm.c
311 lines (204 loc) · 7.01 KB
/
samm.c
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
/*
c program: console, 1-file
samm.c
algorithms:
- escape time
- DEM/M = distance estimation
- SAC/M = SAM/M
samm = Stripe Average Method =
Stripe Average coloring = sac
with :
- skipping first (i_skip+1) points from average
- linear interpolation
https://en.wikibooks.org/wiki/Fractals/Iterations_in_the_complex_plane/stripeAC
--------------------------------
1. draws Mandelbrot set for complex quadratic polynomial
Fc(z)=z*z +c
using samm = Stripe Average Method/Coloring
-------------------------------
2. technique of creating ppm file is based on the code of Claudio Rocchini
http://en.wikipedia.org/wiki/Image:Color_complex_plot.jpg
create 24 bit color graphic file , portable pixmap file = PPM
see http://en.wikipedia.org/wiki/Portable_pixmap
to see the file use external application ( graphic viewer)
-----
it is example for :
https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set
-------------
compile :
gcc samm.c -lm -Wall
./a.out
convert samm.ppm -resize 800x800 samm.png
-------- git --------
cd existing_folder
git init
git remote add origin git@gitlab.com:adammajewski/mandelbrot_wiki_ACh.git
git add samm.c
git commit -m "samm + linear interpolation "
git push -u origin master
*/
#include <stdio.h>
#include <math.h>
#include <complex.h> // https://stackoverflow.com/questions/6418807/how-to-work-with-complex-numbers-in-c
#include <omp.h> //OpenM
#define M_PI 3.14159265358979323846 /* pi */
/* screen ( integer) coordinate */
int iX,iY;
const int iXmax = 8000;
const int iYmax = 8000;
/* world ( double) coordinate = parameter plane*/
double Cx,Cy;
// c = -0.355298979690605 +1.178016112830515 i period = 0
// c = 0.213487557597331 +0.604701020309395 i period = 0
const double CxMin=-2.25;
const double CxMax=0.75;
const double CyMin=1.5;
const double CyMax= -1.5;
/* */
double PixelWidth; //=(CxMax-CxMin)/iXmax;
double PixelHeight; // =(CyMax-CyMin)/iYmax;
/* color component ( R or G or B) is coded from 0 to 255 */
/* it is 24 bit color RGB file */
const int MaxColorComponentValue=255;
FILE * fp;
char *filename="samm.ppm"; // https://commons.wikimedia.org/wiki/File:Mandelbrot_set_-_Stripe_Average_Coloring.png
char *comment="# ";/* comment should start with # */
static unsigned char color[3]; // 24-bit rgb color
unsigned char s = 7; // stripe density
const int IterationMax=2500; // N in wiki
int i_skip = 2; // exclude (i_skip+1) elements from average
/* bail-out value for the bailout test for exaping points
radius of circle centered ad the origin, exterior of such circle is a target set */
const double EscapeRadius=1000000; // = ER big !!!!
double lnER; // ln(ER)
double complex give_c(int iX, int iY){
double Cx,Cy;
Cy=CyMax - iY*PixelHeight; // reverse Y axis
Cx=CxMin + iX*PixelWidth;
return Cx+Cy*I;
}
// the addend function
// input : complex number z
// output : double number t
double Give_t(double complex z){
return 0.5+0.5*sin(s*carg(z));
}
/*
input :
- complex number
- intege
output = average or other estimators, like distance or interior
*/
double Give_Arg(double complex C , int iMax)
{
int i=0; // iteration
double complex Z= 0.0; // initial value for iteration Z0
double A = 0.0; // A(n)
double prevA = 0.0; // A(n-1)
double R; // =radius = cabs(Z)
double d; // smooth iteration count
double complex dC = 0; // derivative
double de; // = 2 * z * log(cabs(z)) / dc;
// iteration = computing the orbit
for(i=0;i<iMax;i++)
{
dC = 2 * Z * dC + 1;
Z=Z*Z+C; // https://en.wikibooks.org/wiki/Fractals/Iterations_in_the_complex_plane/qpolynomials
if (i>i_skip) A += Give_t(Z); //
R = cabs(Z);
if(R > EscapeRadius) break; // exterior of M set
prevA = A; // save value for interpolation
} // for(i=0
if (i == iMax)
A = -1.0; // interior
else { // exterior
de = 2 * R * log(R) / cabs(dC);
if (de < PixelWidth) A = FP_ZERO; // boundary
else {
// computing interpolated average
A /= (i - i_skip) ; // A(n)
prevA /= (i - i_skip - 1) ; // A(n-1)
// smooth iteration count
d = i + 1 + log(lnER/log(R))/M_LN2;
d = d - (int)d; // only fractional part = interpolation coefficient
// linear interpolation
A = d*A + (1.0-d)*prevA;
}
}
return A;
}
/*
input = complex number
output
- color array as Formal parameters
- int = return code
*/
int compute_color(complex double c, unsigned char color[3]){
double arg;
unsigned char b;
// compute
arg = Give_Arg( c, IterationMax);
//
if (arg < 0.0)
/* interior of Mandelbrot set = inside_color = */
b = 0;
else // exterior and boundary
{
if (arg == FP_ZERO) b= 255; // boundary
else b = (unsigned char) (255 - 255*arg ); // exterior
};
// gray gradient
color[0]= b; /* Red*/
color[1]= b; /* Green */
color[2]= b; /* Blue */
return 0;
}
void setup(){
//
PixelWidth=(CxMax-CxMin)/iXmax;
PixelHeight=(CyMax-CyMin)/iYmax;
lnER = log(EscapeRadius); // ln(ER)
/*create new file,give it a name and open it in binary mode */
fp= fopen(filename,"wb"); /* b - binary mode */
/*write ASCII header to the file*/
fprintf(fp,"P6\n %s\n %d\n %d\n %d\n",comment,iXmax,iYmax,MaxColorComponentValue);
}
void info(){
double distortion;
// widt/height
double PixelsAspectRatio = (double)iXmax/iYmax; // https://en.wikipedia.org/wiki/Aspect_ratio_(image)
double WorldAspectRatio = (CxMax-CxMin)/(CyMax-CyMin);
printf("PixelsAspectRatio = %.16f \n", PixelsAspectRatio );
printf("WorldAspectRatio = %.16f \n", WorldAspectRatio );
distortion = PixelsAspectRatio - WorldAspectRatio;
printf("distortion = %.16f ( it should be zero !)\n", distortion );
printf("\n");
printf("bailut value = Escape Radius = %.0f \n", EscapeRadius);
printf("IterationMax = %d \n", IterationMax);
printf("i_skip = %d = number of skipped elements ( including t0 )= %d \n", i_skip, i_skip+1);
// file
printf("file %s saved. It is called .... in A Cheritat wiki\n", filename);
}
void close(){
fclose(fp);
info();
}
// ************************************* main *************************
int main()
{
complex double c;
setup();
printf(" render = compute and write image data bytes to the file \n");
//#pragma omp parallel for schedule(static) private(iY, iX, c, color)
for(iY=0;iY<iYmax;iY++)
for(iX=0;iX<iXmax;iX++)
{ // compute pixel coordinate
c = give_c(iX, iY);
/* compute pixel color (24 bit = 3 bytes) */
compute_color(c,color);
/*write color to the file*/
fwrite(color,1,3,fp);
}
close();
return 0;
}