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