Exploring Recursive Function Systems with PNGwriter


Recursive Function systems are based on the philosophy that sometimes it is possible to generate complex patterns and structures from repeating, self-similar rules. In this case that is explored using recursive functions to create tree-like structures. Here are two images created with two different parameter files

afro.png
Parameter file used: params_afro.txt
tree.png
Parameter file used: params_tree.txt


Here's the code:
#include <pngwriter.h>
#include <math.h>
#include <fstream.h>

#define PI 3.141592653589793238462643383279

// This function will draw one branch, given the starting position, the length, 
// the level of recursion, the angle at which to draw it and some scale factors.
void branch(pngwriter * img, int startx, int starty, double  length, double angle, int reclevel, double kl, double kth)
{
   int endx = (int) (startx + length*cos(angle));
   int endy = (int) (starty + length*sin(angle));
   img->line(startx, starty, endx, endy, 0.0, 1.0, 0.0);

   // As long as we are below the max number of recursions:
   if(reclevel > 0)
     {
	int temp;
	temp = reclevel;
	temp--;
	int endx = (int) (startx + length*cos(angle));
	int endy = (int) (starty + length*sin(angle));
	img->line(startx, starty, endx, endy, 0.0, 1.0, 0.0);
	
	// Draw two more branches. Note that the function is calling itself again twice. 
	// Hence the name recursive.
	branch(img, endx, endy, length*kl, angle +kth, temp, kl, kth); 
	branch(img, endx, endy, length*kl, angle - kth, temp, kl, kth); 		
     }
   
}

int main()
{
   int width;
   int height;
   int recur_max;
   int length0;
   double angle0;
   double kl;
   double kth;
   
   // Read the branch parameters from a text file to make things easier to manage.
   ifstream params ("params.txt");
   if (! params.is_open())
     {
	std::cout << "Error opening file"; exit (1); 
     }
   params >> width;
   params >> height;
   params >> recur_max;
   params >> length0;
   params >> angle0;
   params >> kl;
   params >> kth;
   
   params.close();   
   
   std::cout << "Width is: " << width << std::endl;
   std::cout << "Height is: " << height << std::endl;
   std::cout << "Max recursion is: " << recur_max << std::endl;
   std::cout << "Initial length is: " << length0 << std::endl;
   std::cout << "Initial angle is: " << angle0 << std::endl;
   std::cout << "Length constant is: " << kl << std::endl;
   std::cout << "Angle constant is: " << kth << std::endl;
   
   int x0 = 30/*(int)(width/2.0)*/;
   int y0 =  (int)(height/2.0);
   angle0 = angle0*PI/180.0;
   kth = kth*PI/180.0;
   
   // Create the PNGwriter instance.
   pngwriter img(width, height, 0, "out.png");
   
   // Start the first branch.
   branch(&img, x0, y0, length0, angle0, recur_max, kl, kth);
   
   // Write the image to disk.
   img.close();
   
   return 0;
}




syntax highlighted by Code2HTML, v. 0.9.1
Valid CSS!


© 2002, 2003, 2004, 2005, 2006, 2007 Paul Blackburn