AmendHub

Download

pfuentes69

/

FractalViewer

/

TPlasma.cp

 

(View History)

pfp   First commit Latest amendment: 1 on 2022-08-26

1 /*****
2 * TPlasma.cp
3 *
4 * Drawing clouds (Perlin noise?)
5 *
6 *****/
7
8 #include <Packages.h> // for NumToString prototype
9 #include "TFractalViewerWindow.h"
10 #include "TPlasma.h"
11 #include <stdlib.h>
12 #include <math.h>
13
14
15 /****
16 * TFractalViewerWindow constructor
17 *
18 * Create a bullseye window. This constructor relies
19 * on the TWindow constructor to place the window in
20 * in attractive place. Then it appends a number to the
21 * window title.
22 *
23 ****/
24
25
26 TPlasma::TPlasma(void)
27 {
28 PrepareStyles();
29 // Set the width, and show the window.
30 SetStyle(2);
31 Show();
32 }
33
34
35 /****
36 * Hit
37 *
38 * Handle a mouse down in the window.
39 * Bullseye window just force a refresh.
40 *
41 ****/
42
43
44
45
46 /****
47 * Noise calculations
48 *
49 *
50 ****/
51
52
53 // This code is adapted from a Javascript example found at perlin.mydevelops.com (unknown author)
54
55 int p[] = {
56 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36,
57 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0,
58 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56,
59 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166,
60 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55,
61 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132,
62 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109,
63 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126,
64 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183,
65 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43,
66 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112,
67 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162,
68 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106,
69 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205,
70 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180
71 };
72
73
74 int round(float f)
75 {
76 int fl = floor(f);
77 float d = f - (float)fl;
78 if (d > 0.5)
79 return fl + 1;
80 else
81 return fl;
82 }
83
84 int Perm(int x)
85 {
86 return p[(x & 255)];
87 }
88
89
90 int Index(int x, int y)
91 {
92 return Perm(x + Perm(y));
93 }
94
95
96 float Gradient(int vector,float x,float y)
97 {
98 //we will find the right gradient
99 float val = 0;
100 switch (vector % 4)
101 {
102 case 0:
103 val = x + y;
104 break;
105 case 1:
106 val = -x + y;
107 break;
108 case 2:
109 val = x - y;
110 break;
111 case 3:
112 val = -x - y;
113 break;
114 }
115
116 return val;
117 }
118
119
120 float Smooth(float t)
121 {
122 return t * t * t * (6 * t * t - 15.0 * t + 10.0);
123 }
124
125
126 float Interpolate(float t,float a,float b)
127 {
128 return a + t * ( b - a);
129 }
130
131 float Perlin2D(float x,float y)
132 {
133 float hX = floor(x);
134 float hY = floor(y);
135
136 float dX = x - hX;
137 float dY = y - hY;
138
139 //field for gradients
140 float gradients[4];
141
142 //now let's go through the vertices of the creator and their vectors
143 for (int i = 0; i < 4; i++) {
144 // 00, 01, 10, 11
145 int tmpX = (i & 2) ? 1: 0;
146 int tmpY = (i & 1);
147 int vector = Index(hX + tmpX, hY + tmpY);
148
149 gradients[i] = Gradient(vector, dX - tmpX, dY - tmpY);
150
151 }
152
153 //let's use the smoothing function
154 float smoothX = Smooth(dX);
155 float smoothY = Smooth(dY);
156
157 //we make a bilinear interpolation of the gradient of vectors first two and two
158 // and finally the results from the first and the second and we get the result
159 float x_prva = Interpolate(smoothX, gradients[0], gradients[2]);
160 double x_druha = Interpolate(smoothX, gradients[1], gradients[3]);
161
162 return Interpolate(smoothY, x_prva, x_druha);
163 }
164
165 int PerlinMapped(double value)
166 {
167 //we will scale it from -1 1 to 0 1 and then from it to 0 255
168 return round( ((value + 1.0) / 2.0) * 255.0);
169 }
170
171 int PerlinOctFrec(int x, int y, int oct, double frec)
172 {
173 double together = 0;
174 // int amp = 0;
175 double frek = 0;
176
177 for(int i = 1; i <= oct; i++) {
178 frek = frec * (double)i;
179 together += Perlin2D((double)x * frek, (double)y * frek);
180 }
181
182 return PerlinMapped((double)(together / oct));
183 }
184
185
186
187 /****
188 * DrawShape methods
189 *
190 *
191 ****/
192
193
194
195 void TPlasma::DrawShape(Rect *drawingRect)
196 {
197 RGBColor colPix;
198 double frekvencia = 0.004;
199 int oktava = 3;
200
201 short st = GetStyle() - 1;
202
203 sWidth = drawingRect->right - drawingRect->left + 1;
204 sHeigth = drawingRect->bottom - drawingRect->top + 1;
205
206 for(int x=0; x<sWidth; x++) {
207 for (int y=0; y<sHeigth; y++) {
208 int shade = PerlinOctFrec(x, y, oktava, frekvencia);
209 colPix = spec[st][shade];
210 SetCPixel(x, y, &colPix);
211 }
212 }
213
214
215
216 /* Test code to draw stuff using DrawPicture. It crashes for complex images (memory issues?)
217 OpenCPicParams myOpenCPicParams;
218 PicHandle myPic;
219 Rect rect;
220
221 rect.left = drawingRect->left;
222 rect.right = drawingRect->right;
223 rect.top = drawingRect->top;
224 rect.bottom = drawingRect->bottom;
225
226 myOpenCPicParams.srcRect = rect;
227 myOpenCPicParams.hRes = 0x00480000;
228 myOpenCPicParams.vRes = 0x00480000;
229 myOpenCPicParams.version = -2;
230 myOpenCPicParams.reserved1 = 0;
231 myOpenCPicParams.reserved2 = 0;
232
233 myPic = OpenCPicture(&myOpenCPicParams);
234
235 PenSize(style, style);
236 ClipRect(drawingRect);
237
238 while (drawingRect->left < drawingRect->right &&
239 drawingRect->top < drawingRect->bottom) {
240 MoveTo(drawingRect->left, drawingRect->bottom);
241 LineTo(drawingRect->right, drawingRect->bottom);
242 LineTo(drawingRect->left, drawingRect->top);
243 LineTo(drawingRect->left, drawingRect->bottom);
244 InsetRect(drawingRect, style*2, style*2);
245 }
246
247 ClosePicture();
248
249 DrawPicture(myPic, &rect);
250 */
251
252 }
253
254
255 //
256 // PREPARE STYLES METHODS
257 //
258
259
260 void TPlasma::PrepareStyles()
261 {
262 short ci;
263 // Style 1
264 for(ci=0; ci < 256; ci++) {
265 spec[0][ci].red = ci * 256;
266 spec[0][ci].green = ci * 256;
267 spec[0][ci].blue = 65535;
268 }
269 // Style 2
270 for(ci=0; ci < 256; ci++) {
271 spec[1][ci].red = 65535 - ci * 256;
272 spec[1][ci].green = 65535 - ci * 256;
273 spec[1][ci].blue = 65535;
274 }
275 // Style 3
276 for(ci=0; ci < 256; ci++) {
277 spec[2][ci].red = 65535 - ci * 256;
278 spec[2][ci].green = 65535 - ci * 256;
279 spec[2][ci].blue = 65535 - ci * 256;
280 }
281 // Style 4
282 for(ci=0; ci < 256; ci++) {
283 spec[3][ci].red = ci * 256;
284 spec[3][ci].green = ci * 256;
285 spec[3][ci].blue = ci * 256;
286 }
287 // Style 4
288 for(ci=0; ci < 256; ci++) {
289 spec[4][ci].red = 32768 - ci * 128;
290 spec[4][ci].green = ci * 256;
291 spec[4][ci].blue = 65535 - ci * 256;
292 }
293 }
294
295
296
297 //
298 // ZOOM CONTENT
299 //