/* colorw_gl.c   color wheel based on phase angle                          */
/*            1/1/97 JSS initial version                                   */
/*            tested on OpenVMS, SunOS, Exceed on PC                       */
/*            converted to OpenGl from X Windows 10/29/2005                */
/* may be compiled and linked using    cl /GX /ML /I. colorw_gl.c          */

#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
#define Pi    3.14159265358979323846
#undef  abs
#define abs(x) ((x>=0.0)?x:(-x))
#undef  max
#define max(x,y) ((x)>(y)?(x):(y))

static int width=400;
static int height=400;

void display(void)
{
  char text[]="colorw_gl";
  char *p;
  int i, j;
  float x1, x2, y1, y2;
  float A, AA, AAA; /* temporaries */
  float R, G, B;    /* red, green, blue intensities computer */
  float radius_1 = 0.9;
  float radius_2 = 0.4;
  
  /* clear window */
  glClear(GL_COLOR_BUFFER_BIT); 
  glLoadIdentity ();
  glColor3f(0.0, 0.0, 0.0);

  /* draw text, in its own context */
  glPushMatrix();
    glLoadIdentity ();
    glColor3f(0.0, 0.0, 0.0);
    glEnable(GL_LINE_SMOOTH);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);
    glTranslatef(-0.95, 0.89, 0.0);
    glScalef(0.00055, 0.00055, 0.0);
    for(p=text; *p; p++)
      glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
  glPopMatrix();
  
  /* Draw the segments */

  glLineWidth(5.0);
  glBegin(GL_LINES);
  A = -1.0;
  while(A < 1.0)  /* walk the angle in bams around the circle */
  {
    /* A = arctan(Y, X)/PI   for normalized angle from X-Y plot        */
    /* get double R,G,B  R==1 at A==0, G==1 at A==2/3, B==1 at A==-2/3 */
    R = 1.0 - abs(A);
    AA = A - 2.0/3.0;
    if(AA < -1.0) AA = 2.0+AA;
    G = 1.0 - abs(AA);
    AA = A + 2.0/3.0;
    if(AA > 1.0) AA = 2.0-AA;
    B = 1.0 - abs(AA);

    /* boost low end and normalize (this brightens colors) */
    R = R+0.2;
    G = G+0.2;
    B = B+0.2;
    AAA = max(R, G);
    AAA = max(AAA, B);
    R = R/AAA;
    G = G/AAA;
    B = B/AAA;
    

    /* set cell colors */
    glColor3f(R, G, B);

    /* compute line ends */
    x1 = radius_1 * cos(A * Pi);
    y1 = radius_1 * sin(A * Pi);
    x2 = radius_2 * cos(A * Pi);
    y2 = radius_2 * sin(A * Pi);
    glVertex3d(x1, y1, 0.0);
    glVertex3d(x2, y2, 0.0);
    A = A + 0.01;  /* 200 lines */
  }
  glEnd();

  glFlush(); 
}

/* This routine handles window resizes */
void reshape(int w, int h)
{
  width = w;
  height = h;
  /* Set the transformations */
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
  glMatrixMode(GL_MODELVIEW);
  glViewport(0, 0, w, h);
}

void init()
{
  /* set clear color to white */
  glClearColor (1.0, 1.0, 1.0, 0.0);
  /* set fill  color to black */
  glColor3f(0.0, 0.0, 0.0);

  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();
  glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
  glMatrixMode (GL_MODELVIEW);
  glViewport(0, 0, width, height);
}

int main(int argc, char* argv[])
{
  glutInit(&argc,argv);
  glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);  
  glutInitWindowSize(width, height);
  glutInitWindowPosition(0,0); 
  
  glutCreateWindow(argv[0]); 
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);
  init();
  glutMainLoop();
  return 0;
}


