/*This program draws a simple example of the bifurcation diagram for the
Logistic Difference Equation.  The horizontal axis shows the values for k
from 0 to 4 and the vertical axis will plot a number of iterations of the
original x-value which is between 0 and 1  */

#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <GL/glut.h>

#define initial_width 700             // Initial Window Width 
#define initial_height 200            // Initial Window Height

int main_window;                      // Window ID number 

// Draw text on the screen using pre-defined Bitmap character fonts 
// Passed arguments include location in 3-space, pointer to string, pointer to font

void bitmap_output(int x, int y, int z, char *string, void *font)
{  int len, i;
   glRasterPos3f(x, y, 0);            // Locate Raster Position in 3-space
   len = (int) strlen(string);        // Find length of string

   for (i = 0; i < len; i++) {        // Plot each characters in font style
       glutBitmapCharacter(font, string[i]);
      }
}


// Draw bifurcation Diagram 

DrawGraph()
{ float x, k;
  int i;
  glBegin(GL_POINTS);                         // Start drawing points
    glColor3f(0.0,0.0,0.0);                   // Set drawing color to black
    for (k=0; k< 4.0; k+= 0.005)              // Step through k values
     { x = 0.0001; 
      for( i=0; i<100; i++)                   // Generate a bunch of iterations
       { x = k * x * (1.0 - x);
         glVertex3f(k,x,0.0);                 // Put a point at (k,x)
       }
     }
  glEnd();
}


//Draw some titles on the screen in available Times Roman fonts

void DrawTitles()
{ glColor3f(0.0, 0.0, 0.0);                   // Set color to Black
  glPushMatrix();                             // New frame of reference
  glTranslatef(0.1, 0.8, 0);                 // Move to new location
  bitmap_output(0,0,0, "Bifurcation", GLUT_BITMAP_TIMES_ROMAN_24);  // Plot large title
  glPopMatrix();                              // Return to old reference

} 
  
// Display Window Definition

void display1(void)
{ glClear(GL_COLOR_BUFFER_BIT);               // Clear window area with proper color
  DrawGraph();
  DrawTitles();
  glFlush();                                  // Force all drawing
}
                               

//  Common Initialization functions. 
void init(void)
{ /* select clearing (background) color   */
   glClearColor(1.0, 1.0, 0.0, 0.0);

/* initialize viewing values */
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(0.0, 4.0, 0.0, 1.0, -1.0, 1.0);
}


int main(int argc, char **argv)
{
  glutInit(&argc, argv);                      // Initialize with any passed arguments to main
  glutInitDisplayMode(GLUT_RGB);              // Initialize RGB mode in OpenGL
  glutInitWindowSize(initial_width, initial_height);  // Initialize window
  main_window = glutCreateWindow("Bifurcation ");  // Create main window with title
  init();
  glutDisplayFunc(display1);                  // Pass pointer to inner window display
  glutMainLoop();                             // Enter main loop - wait for events
  return 0;             	/* ANSI C requires main to return int. */
}
