Fractal Seasons Project

Images | C++ code

Images


Summer


Fall

C++ code

//John Lynch, Betsy Savare, Akemi Shinkai

//Fractal Seasons

/**************************************include files*****************************************/

#include<windows.h>

#include<glut.h>

#include<cstdlib>

//#include<iostream.h>

#include<time.h>

#include<math.h>

#define NUM_TREES 20

#define NUM_LEAVES 2881			//144 leaves per tree + one more

#define LEAFSIZE 8


/**************************************global constants*****************************************/

//change these values for differnt screens sizes
const int screenWidth = 640;
const int screenHeight = 480;
const int outerdelay = 1000;
const int innerdelay = 1000000;

/**************************************data structures*****************************************/



class Point2{
public:

	Point2 () {x = y = 0.0f;}

	Point2 (float xx, float yy) {x = xx; y = yy;}

	void set(float xx, float yy) {x = xx; y = yy;}

	float getX() {return x;}

	float getY() {return y;}

	float x, y;

private:
};
//Point2




class Leaf{
public:

	Leaf() {angle = 0;}

	void drawLeaf();

	Point2 getStart() {return startpoint;}

	Point2 getEnd() {return endpoint;}

	Point2 startpoint;

	Point2 endpoint;

	float angle;

	float width;

	float dropped;

	float c1;

	float c2;

	float c3;

private:
};
//leaf


void Leaf:: drawLeaf(){
	float x1, y1, x2, y2;

	x1 = startpoint.getX();

	y1 = startpoint.getY();

	x2 = endpoint.getX();

	y2 = endpoint.getY();

	glLineWidth(width);

	glBegin (GL_LINES);

		glVertex2f ((GLfloat)x1, (GLfloat)y1);

		glVertex2f ((GLfloat)x2, (GLfloat)y2);

	glEnd();
}
//drawleaf


struct Node{

	Point2 x;

	float angle;

	Node *next;

};
//Node



typedef struct Node NodeType;


class Stack{
public:

	Stack() {head_ptr = NULL;}

	void addToStack(Point2 x, float angle);

	Node retrieveFromStack();

private:

	Node *head_ptr;
};
//stack


class Canvas{
public:

	Canvas();

	Canvas(Point2 p, float angle);

	void turnTo(float angle) {CD+=angle;}

	void lineTo(float x, float y);

	void lineTo(Point2 P);

	void forward(float dist, int isVisible);

	void backward(float dist, int isVisible);

	void moveTo(float x, float y);

	void moveTo(Point2 P);

	void savePosition();

	void retrievePosition();

	void reset_idx() {idx = 0;}

	Point2 getPosition() {return CP;}

	float getDirection() {return CD;}

private:

	Point2 CP;

	float CD;

	int idx;

	Stack stack;

	NodeType one_node;

};
//canvas


void Stack:: addToStack(Point2 xx, float aangle){

	NodeType *insert_ptr;

	insert_ptr = new Node;

	insert_ptr->x = xx;

	insert_ptr->angle = aangle;

	insert_ptr->next = head_ptr;

	head_ptr = insert_ptr;

}
//addToStack


NodeType Stack:: retrieveFromStack(){

	NodeType *temp_ptr;

	NodeType saved_values;

	temp_ptr = head_ptr;

	saved_values.x = temp_ptr->x;

	saved_values.angle = temp_ptr->angle;

	head_ptr = head_ptr->next;

	free(temp_ptr);

	return saved_values;

}
//rettrieveFromStack



Canvas:: Canvas(Point2 p, float angle){

	float x = p.getX();

	float y = p.getY();

	CP.set(x, y);

	CD = angle;

	reset_idx();
}
//canvas



void Canvas:: lineTo(float x, float y){

	glBegin (GL_LINES);

		glVertex2f ((GLfloat)CP.x, (GLfloat)CP.y);

		glVertex2f ((GLfloat) x, (GLfloat) y);

	glEnd();

	CP.set (x,y);

	//glFlush();

}
//lineTo


void Canvas:: moveTo(float x, float y){

	CP.set(x, y);

}
//moveTo



void Canvas:: forward(float dist, int isVisible){	

	const float RadPerDeg=0.017453393;



	float x = CP.x + dist * cos(RadPerDeg * CD);

	float y = CP.y + dist * sin(RadPerDeg * CD);

	if(isVisible)

		lineTo(x, y);

	else

		moveTo(x, y);

	CP.set(x, y);

}
//forward


void Canvas:: backward(float dist, int isVisible){	

	const float RadPerDeg=0.017453393;

	float x = CP.x - dist * cos(RadPerDeg * CD);

	float y = CP.y - dist * sin(RadPerDeg * CD);

	if(isVisible)

		lineTo(x, y);

	else

		moveTo(x, y);

	CP.set(x, y);

}
//backward


void Canvas:: savePosition(){

	stack.addToStack(CP, CD);

}
//savePosition



void Canvas:: retrievePosition(){

	one_node = stack.retrieveFromStack();

	CP = one_node.x;

	CD = one_node.angle;
}
//retrievePosition


int ctr = 0;


// array to hold leaves
Leaf each_leaf[NUM_LEAVES];

Point2 each_tree[NUM_TREES+1];



void drawBranch(Canvas &turtle, float scale){

		Leaf leaf;



		glLineWidth(2.5);				//set line width to 2.5 pixels

		glColor3f(0.65f, 0.16f, 0.16f);				//brown

		turtle.forward(scale * LEAFSIZE, 1);		//first part of the branch

		turtle.turnTo(-15);			

		leaf.startpoint = turtle.getPosition();

		leaf.angle = turtle.getDirection();

		glColor3f(1.0f, 1.0f, 1.0f);				//white

		glLineWidth(6.0);

		turtle.forward(scale * LEAFSIZE, 1);		//first leaf

		leaf.endpoint = turtle.getPosition();

		leaf.width = 6.0;

		leaf.dropped = 0;

		ctr++;

		each_leaf[ctr] = leaf;

		glLineWidth(2.5);

		



		turtle.backward(scale * LEAFSIZE, 0);

		turtle.turnTo(+15);

		glLineWidth(2.0);				//set line width to 2.0 pixels

		glColor3f(0.65f, 0.16f, 0.16f);				//brown

		turtle.forward(scale * LEAFSIZE, 1);		//second part of the branch



		turtle.turnTo(+15);			

		leaf.startpoint = turtle.getPosition();

		leaf.angle = turtle.getDirection();

		glColor3f(1.0f, 1.0f, 1.0f);				//white

		glLineWidth(6.0);

		turtle.forward(scale * LEAFSIZE, 1);		//second leaf

		leaf.endpoint = turtle.getPosition();

		leaf.width = 6.0;

		leaf.dropped = 0;

		ctr++;

		each_leaf[ctr] = leaf;

		glLineWidth(2.0);



		turtle.backward(scale * LEAFSIZE, 0);

		turtle.turnTo(-15);

		glLineWidth(1.5);				//set line width to 1.5 pixels

		glColor3f(0.65f, 0.16f, 0.16f);				//brown

		turtle.forward(scale * LEAFSIZE, 1);		//third part of the branch



		turtle.turnTo(-15);			

		leaf.startpoint = turtle.getPosition();

		leaf.angle = turtle.getDirection();

		glColor3f(1.0f, 1.0f, 1.0f);				//white

		glLineWidth(6.0);

		turtle.forward(scale * LEAFSIZE, 1);		//third leaf

		leaf.endpoint = turtle.getPosition();

		leaf.width = 6.0;

		leaf.dropped = 0;

		ctr++;

		each_leaf[ctr] = leaf;

		glLineWidth(1.5);



		turtle.backward(scale * LEAFSIZE, 0);

		turtle.turnTo(+15);

		glLineWidth(1.0);				//set line width to 1.0 pixels

		glColor3f(0.65f, 0.16f, 0.16f);				//brown

		turtle.forward(scale * LEAFSIZE, 1);		//fourth part of branch



		turtle.turnTo(+15);			

		leaf.startpoint = turtle.getPosition();

		leaf.angle = turtle.getDirection();

		glColor3f(1.0f, 1.0f, 1.0f);				//white

		glLineWidth(6.0);

		turtle.forward(scale * LEAFSIZE, 1);		//fourth leaf

		leaf.endpoint = turtle.getPosition();

		leaf.width = 6.0;

		leaf.dropped = 0;

		ctr++;

		each_leaf[ctr] = leaf;

		glLineWidth(1.0);

		glColor3f(0.65f, 0.16f, 0.16f);				//brown

		turtle.backward(scale * LEAFSIZE, 0);

		turtle.turnTo(-15);

}



void Branch(Point2 p, float angle, float scale, float level){

	Canvas turtle(p, angle);

	glLineWidth(3.5);					//set line width to 3.5 pixels

	turtle.forward(scale * 2 * LEAFSIZE, 1);		//trunk

	turtle.turnTo(-22);

	turtle.savePosition();

	turtle.turnTo(-22);

	if(level==0){

		drawBranch(turtle, scale);

	}
	else
		Branch(turtle.getPosition(), turtle.getDirection(), scale, level - 1);

	turtle.turnTo(+22);

	if(level==0){

		drawBranch(turtle, scale);

	}

	else

		Branch(turtle.getPosition(), turtle.getDirection(), scale, level - 1);

	turtle.turnTo(+22);

	if(level==0){

		drawBranch(turtle, scale);

	}

	else

		Branch(turtle.getPosition(), turtle.getDirection(), scale, level - 1);



	turtle.retrievePosition();



	turtle.turnTo(+22);



	turtle.savePosition();



	turtle.turnTo(+22);



	if(level==0){

		drawBranch(turtle, scale);

	}

	else

		Branch(turtle.getPosition(), turtle.getDirection(), scale, level - 1);



	turtle.turnTo(-22);



	if(level==0){

		drawBranch(turtle, scale);

	}

	else

		Branch(turtle.getPosition(), turtle.getDirection(), scale, level - 1);



	turtle.turnTo(-22);



	if(level==0){

		drawBranch(turtle, scale);

	}

	else

		Branch(turtle.getPosition(), turtle.getDirection(), scale, level - 1);
	turtle.retrievePosition();
}

/********************makeBackground*************************************************/
/* this function draws a dark green rectangle to represent the ground 
   then uses nested for loops to traverse the screen drawing grass
   it the draws a blue rectangle a the upper 1/3 of the screen to represent the sky
*/
void makeBackground(void)
{
	glColor3f(0.0,0.0,0.2);
	glRecti(0,0,screenWidth,2*screenHeight/3);

	for(int f=1; f < screenWidth; f=f+4)
	{
		for(int g=1; g < screenHeight; g=g+4)
		{
			int color = rand()%3;

			switch(color){

			case 0: 	
				glColor3f(0.0f, 0.7f, 0.0f);	//light green
				break;

			case 1:		
				glColor3f(0.0f, 0.5f, 0.0f);	//dark green
				break;

			case 2:		
				glColor3f(0.0f, 0.3f, 0.0f);	//darker still
				break;
			}//switch
			
			glLineWidth(1.0);
			//draw a blade
			glBegin(GL_LINES);
				glVertex2i(f, g);
				glVertex2i(f+ (rand()%10), g+5);
			glEnd();
			
		}//for
	
	}//for
	
	//added rectangle
	//this draws in a rectangle to represent the sky
	//if you want clouds put your bmp code here
	glColor3f(0.0,0.0,0.6);
	glRecti(0,screenHeight,screenWidth, screenHeight-screenHeight/3);

}//makeBackground


void spring(void){
//*******randomly turn the leaves green***Spring


	glLineWidth(6.0);					//set line width to 6 pixels

	glColor3f(0.0f, 0.7f, 0.0f);		//green

	for(int i = 1; i < NUM_LEAVES; i++){

		ctr = (rand()%NUM_LEAVES) +1;

		if(ctr > NUM_LEAVES)

			ctr = NUM_LEAVES;

		each_leaf[ctr].drawLeaf();

		for(float j = 0; j < 300000; j++);		//delay loop
		//added glflush
		glFlush();
	}

}
//spring



//*******turn all of the leaves green*****Summer
void summer(void){


	glLineWidth(6.0);					//set line width to 6 pixels

	glColor3f(0.0f, 0.5f, 0.0f);		//green

	ctr = 0;

	for(int i = 1; i <= NUM_LEAVES; i++){

		ctr++;

		each_leaf[ctr].drawLeaf();



		for(float j = 0; j < 50000; j++);		//delay loop
		//added glflush
		glFlush();


	}



}
//summer


void fall(void){


//*******turn all of the leaves red, yellow or orange**Fall

	int color;

	glLineWidth(6.0);					//set line width to 6 pixels

	for(int i = 0; i <= NUM_LEAVES; i++){

		color = rand()%3;

		switch(color){

		case 0: 	glColor3f(1.0f, 0.0f, 0.0f);	//red

			each_leaf[i].c1 = 1.0;

			each_leaf[i].c2 = 0.0;

			each_leaf[i].c3 = 0.0;

			break;

		case 1:		glColor3f(1.0f, 0.65f, 0.0f);	//orange

			each_leaf[i].c1 = 1.0;

			each_leaf[i].c2 = 0.65;

			each_leaf[i].c3 = 0.0;

			break;

		case 2:		glColor3f(1.0f, 1.0f, 0.0f);	//yellow

			each_leaf[i].c1 = 1.0;

			each_leaf[i].c2 = 1.0;

			each_leaf[i].c3 = 0.0;

			break;

		}

		

		each_leaf[i].drawLeaf();
		//added glflush
		glFlush();



		for(float j = 0; j < 50000; j++);		//delay loop

	}



	float drop_point = screenHeight/6 - 50;

	float bottom = screenHeight - 10;

	Point2 start;

	Point2 end;

	float x1, y1, x2, y2;

	int odd_even;

	Leaf leaf;



	for(int a = 0; a< 1000; a++);				//delay loop


	for(int i = 1; i <= NUM_LEAVES; i++){

		ctr = (rand()%NUM_LEAVES) +1;

		if(ctr > NUM_LEAVES)

			ctr = NUM_LEAVES;

    	leaf = each_leaf[ctr];

		start = leaf.getStart();

		end = leaf.getEnd();

		x1 = start.getX();

		y1 = start.getY();

		x2 = end.getX();

		y2 = end.getY();

		glColor3f(1.0f, 1.0f, 1.0f);		//white

		each_leaf[ctr].drawLeaf();



		glColor3f(leaf.c1, leaf.c2, leaf.c3);



		if(ctr%2==0)

			odd_even = ctr*5;

		else

			odd_even = ctr*3;



		if(leaf.dropped == 0){

			y1 = drop_point+rand()%odd_even;

			Point2 new_start(x1, y1);

			Canvas turtle(new_start, leaf.angle);

			turtle.forward(LEAFSIZE, 1);

			leaf.startpoint = new_start;

			leaf.endpoint = turtle.getPosition();

			leaf.dropped = 1;

			each_leaf[ctr]= leaf;

		}

		else if(leaf.dropped == 1);



			else{

				y1 = y1 - 60+ rand()%50;

				Point2 new_start(x1, y1);

				Canvas turtle(new_start, leaf.angle);

				turtle.forward(LEAFSIZE, 1);

				leaf.startpoint = new_start;

				leaf.endpoint = turtle.getPosition();

				leaf.dropped++;

				each_leaf[ctr]= leaf;

			}



		for( int a = 0; a< 100000; a++);
	}



	ctr = 0;



	glColor3f(0.65f, 0.16f, 0.16f);			//set drawing color to brown

	int tree_ctr = 0;

	int x = (NUM_TREES / 3) + 3;

	int y = (NUM_TREES / 3) + 0;

	int z = (NUM_TREES / 3) - 3;


	for(int i = 1; i <= x; i++){

		tree_ctr++;

		Point2 init = each_tree[tree_ctr];

		int xx = init.getX();

		int yy = init.getY();

		Branch(init, 90, 1.5, 1);			//init point, angle, scale, levels

	}

	for(int i = 1; i <= y; i++){

		tree_ctr++;

		Point2 init = each_tree[tree_ctr];

		int xx = init.getX();

		int yy = init.getY();

		Branch(init, 90, 2.5, 1);			

	}

	for(int i = 1; i <= z; i++){

		tree_ctr++;

		Point2 init = each_tree[tree_ctr];

		int xx = init.getX();

		int yy = init.getY();

		Branch(init, 90, 3, 1);			

	}
		//added glflush
		glFlush();


}//fall



void Br(void)

{

	glClear(GL_COLOR_BUFFER_BIT);



//*******draw  trees**********************Winter

	int i;

	int x, y, z;

	int tree_ctr = 0;

	

	float xx, yy;

	x = (NUM_TREES / 3) + 3;

	y = (NUM_TREES / 3) + 0;

	z = (NUM_TREES / 3) - 3;

	//put in grass and sky
	makeBackground();

	for(i = 1; i <= x; i++){

		tree_ctr++;

		Point2 init(rand()%25 + (i * screenWidth / (x + 3)), 

											(3*screenHeight/4.5) + rand()%40);

		each_tree[tree_ctr] = init;

		xx = init.getX();

		yy = init.getY();

		Branch(init, 90, 1.5, 1);			//init point, angle, scale, levels

	}

	for(i = 1; i <= y; i++){

		tree_ctr++;

		Point2 init(rand()%40+ (i * screenWidth / (y + 3)), 

											(2*screenHeight/5) + rand()%40);

		each_tree[tree_ctr] = init;

		xx = init.getX();

		yy = init.getY();

		Branch(init, 90, 2.5, 1);			

	}

	for(i = 1; i <= z; i++){

		tree_ctr++;

		Point2 init(rand()%40 + (i * screenWidth / (z + 3)), 

											(1*screenHeight/6) + rand()%60);

		each_tree[tree_ctr] = init;

		xx = init.getX();

		yy = init.getY();

		Branch(init, 90, 3, 1);			

	}



		//added glflush
		glFlush();

	//spring call
	spring();

	//delay between seasons
	for(int a = 0; a< innerdelay; a++){
		for (int b = 0; b < outerdelay; b++);
	}

	//summer call
	summer();


	//delay between seasons
	for(int a = 0; a< innerdelay; a++){
		for (int b = 0; b < outerdelay; b++);
	}


	//call fall
	fall();
}
//br


void myInit(void)

{

	glClearColor(1.0,1.0,1.0,0.0);	//set background color.

	glColor3f(0.65f, 0.16f, 0.16f);	//set drawing color to brown

	glLineWidth(3.0);				//set line width to 3 pixels

	glMatrixMode(GL_PROJECTION);

	glLoadIdentity();

	gluOrtho2D(0.0, (GLdouble)screenWidth, 0.0, (GLdouble)screenHeight);

}




void main(int argc, char** argv)

{

	glutInit(&argc, argv);					//initialize the toolkit

	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);//set display mode

	glutInitWindowSize(screenWidth, screenHeight);			//setwindowsize

	glutInitWindowPosition(100,100);			//set window position on screen

	glutCreateWindow("This is a Tree");			//open the screen window

	glutDisplayFunc(Br);					//register redraw function

	myInit();

	glutMainLoop();



}