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