FAQ
Cover
This is the archive Discourse for the Processing (ALPHA) software.
Please visit the new Processing forum for current information.

   Processing 1.0 _ALPHA_
   Topics & Contributions
   Information Visualization
(Moderators: forkinsocket, REAS)
   plasma fractal generator
« Previous topic | Next topic »

Pages: 1 
   Author  Topic: plasma fractal generator  (Read 2776 times)
mm
Guest
Email
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.
}
 
Pages: 1 

« Previous topic | Next topic »