 |
Author |
Topic: plasma fractal generator (Read 2776 times) |
|
mm Guest

|
plasma fractal generator
« on: Mar 21st, 2004, 9:16pm » |
|
here's a random midpoint displacement fractal generator (plasma) http://www.madmerv.com/proce55ing/plasma Code: // Plasma fractal generator // By Mad Merv - March 2004 // Original applet written January, 2002 by Justin Seyster /* A scientific name for this type of fractals would be: Random Midpoint Displacement Fractals. In fractint they are called plasma; another popular name for them is: fractal clouds. Here is a simplified explanation of the (recursive / iterative) algorithm: initialisation: generate random values for 4 corners of a rectangle A,B,C,D iteration: divide the rectangle in 4 smaller ones, calculate values for the 5 new points (midpoints on the sides and center): those values are a SUM (mean value of the endpoints defining the midpoint) PLUS (pos. or neg. random value proportional to size of segment) stop criteria: the previous step is repeated until the size of the subrectangles will be smaller than one pixel. */ float seed=1; BImage Buffer; //A buffer used to store the image //Randomly displaces color value for midpoint depending on size //of grid piece. float Displace(float num) { float max = num / (float)(width + height) * 3; return (random(seed) - 0.5f) * max; } //Returns a color based on a color value, c. color ComputeColor(float c) { float Red = 0; float Green = 0; float Blue = 0; if (c < 0.5f) { Red = c * 2; } else { Red = (1.0f - c) * 2; } if (c >= 0.3f && c < 0.8f) { Green = (c - 0.3f) * 2; } else if (c < 0.3f) { Green = (0.3f - c) * 2; } else { Green = (1.3f - c) * 2; } if (c >= 0.5f) { Blue = (c - 0.5f) * 2; } else { Blue = (0.5f - c) * 2; } Red *=255; Green *=255; Blue *=255; return color(Red, Green, Blue); } //This is something of a "helper function" to create an initial grid //before the recursive function is called. void drawPlasma(int width, int height) { float c1, c2, c3, c4; //Assign the four corners of the intial grid random color values //These will end up being the colors of the four corners of the applet. c1 = random(seed); c2 = random(seed); c3 = random(seed); c4 = random(seed); DivideGrid(0, 0, width , height , c1, c2, c3, c4); } //This is the recursive function that implements the random midpoint //displacement algorithm. It will call itself until the grid pieces //become smaller than one pixel. void DivideGrid(float x, float y, float width, float height, float c1, float c2, float c3, float c4) { float Edge1, Edge2, Edge3, Edge4, Middle; float newWidth = width / 2; float newHeight = height / 2; if (width > 2 || height > 2) { Middle = (c1 + c2 + c3 + c4) / 4 + Displace(newWidth + newHeight); //Randomly displace the midpoint! Edge1 = (c1 + c2) / 2; //Calculate the edges by averaging the two corners of each edge. Edge2 = (c2 + c3) / 2; Edge3 = (c3 + c4) / 2; Edge4 = (c4 + c1) / 2; //Make sure that the midpoint doesn't accidentally "randomly displaced" past the boundaries! if (Middle < 0) { Middle = 0; } else if (Middle > 1.0f) { Middle = 1.0f; } //Do the operation over again for each of the four new grids. DivideGrid(x, y, newWidth, newHeight, c1, Edge1, Middle, Edge4); DivideGrid(x + newWidth, y, newWidth, newHeight, Edge1, c2, Edge2, Middle); DivideGrid(x + newWidth, y + newHeight, newWidth, newHeight, Middle, Edge2, c3, Edge3); DivideGrid(x, y + newHeight, newWidth, newHeight, Edge4, Middle, Edge3, c4); } else //This is the "base case," where each grid piece is less than the size of a pixel. { //The four corners of the grid piece will be averaged and drawn as a single pixel. float c = (c1 + c2 + c3 + c4) / 4; set((int)x, (int)y, ComputeColor(c)); } } //Draw a new plasma fractal whenever the applet is clicked. void mousePressed() { //seed = random(seed); drawPlasma(width, height); } //Whenever something temporarily obscures the applet, it must be redrawn manually. //Since the fractal is stored in an offscreen buffer, this function only needs to //draw the buffer to the screen again. void loop() { // image(Buffer, 0, 0); drawPlasma(width, height); delay(15); } public void setup() { size(640,480); noStroke(); Buffer = new BImage(width, height); //Set up the graphics buffer and context. drawPlasma(width, height); //Draw the first plasma fractal. } |
|
|
|
|
|
|