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 | // |