/* 0015gl.c  0015 wing at various angle of attack */

#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <math.h>

static double xmin=0.0;
static double xmax=1.0;
static int width=1000; /* 4 across, 3 rows  2 degrees each */
static int height=500;
static double Pi=M_PI;

double f(double x)
{
  return (15./20.)*(0.29690*sqrt(x)-0.12600*x-0.35160*x*x+
		    0.28430*x*x*x-0.10150*x*x*x*x);
}

void pitch(double angle, double x, double y, double *ax, double *ay)
{
  double xc;
  xc = x-0.3; /* rotate about maximum chord */
  *ax = 0.3+xc*cos(angle)+y*sin(angle);
  *ay = -xc*sin(angle)+y*cos(angle);
}

void draw(double angle, double xoff, double yoff)
{
  int j;
  double x1, y1, x2, y2;
  double ax1, ay1, ax2, ay2;
  double nax1, nay1, nax2, nay2; /* negative surface */
  int n=40;
  double dx;

  dx = (xmax-xmin)/(double)(n+1);
  x1=xmin;
  y1=f(x1);
  pitch(angle, x1, y1, &ax1, &ay1);
  pitch(angle, x1, -y1, &nax1, &nay1);
  glColor3f(0.0, 0.0, 0.0);
  for(j=0; j<=n; j++)
  {
    x2=xmin+(j+1)*dx;
    y2=f(x2);
    pitch(angle, x2, y2, &ax2, &ay2);
    pitch(angle, x2, -y2, &nax2, &nay2);
    glBegin(GL_LINES);
      glVertex2f(xoff+ax1,yoff+ay1);
      glVertex2f(xoff+ax2,yoff+ay2);
      glVertex2f(xoff+nax1,yoff+nay1);
      glVertex2f(xoff+nax2,yoff+nay2);
    glEnd();
    ax1=ax2;
    ay1=ay2;
    nax1=nax2;
    nay1=nay2;
  }
  glColor3f(1.0, 0.0, 0.0);
  glPointSize(4.0);
  glBegin(GL_POINTS);
    glVertex2f(xoff+0.3,yoff);
  glEnd();

}

void display(void)
{
  double angle, xoff, yoff;
  char title[] = "angle of attack, 0 to 22 degrees in 2 degree steps";
  char *p;

  /* clear window */
  glClear(GL_COLOR_BUFFER_BIT); 
  glLoadIdentity ();

  /* Draw wings */
  xoff= 0.0;
  yoff= 1.5;
  angle=  Pi*0.0/180.0;
  draw(angle, xoff, yoff);

  xoff= 1.0;
  yoff= 1.5;
  angle=  Pi*2.0/180.0;
  draw(angle, xoff, yoff);

  xoff= 2.0;
  yoff= 1.5;
  angle=  Pi*4.0/180.0;
  draw(angle, xoff, yoff);

  xoff= 3.0;
  yoff= 1.5;
  angle=  Pi*6.0/180.0;
  draw(angle, xoff, yoff);


  xoff= 0.0;
  yoff= 1.0;
  angle=  Pi*8.0/180.0;
  draw(angle, xoff, yoff);

  xoff= 1.0;
  yoff= 1.0;
  angle=  Pi*10.0/180.0;
  draw(angle, xoff, yoff);

  xoff= 2.0;
  yoff= 1.0;
  angle=  Pi*12.0/180.0;
  draw(angle, xoff, yoff);

  xoff= 3.0;
  yoff= 1.0;
  angle=  Pi*14.0/180.0;
  draw(angle, xoff, yoff);


  xoff= 0.0;
  yoff= 0.5;
  angle=  Pi*16.0/180.0;
  draw(angle, xoff, yoff);

  xoff= 1.0;
  yoff= 0.5;
  angle=  Pi*18.0/180.0;
  draw(angle, xoff, yoff);

  xoff= 2.0;
  yoff= 0.5;
  angle=  Pi*20.0/180.0;
  draw(angle, xoff, yoff);

  xoff= 3.0;
  yoff= 0.5;
  angle=  Pi*22.0/180.0;
  draw(angle, xoff, yoff);

  /* draw text, in its own context */
  glPushMatrix();
  glLoadIdentity ();
  glColor3f(0.0, 0.0, 0.0);
  glEnable(GL_LINE_SMOOTH);
  glTranslatef(0.1, 1.8, 0.0);
  glScalef(0.001, 0.001, 0.0);
  for(p=title; *p; p++)
    glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
  glPopMatrix();
  
  glFlush(); 
}

/* This routine handels mouse events */
static void mouse(int button, int state, int x, int y)
{
  float wx, wy;
  
  if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
  {
    exit(0);
  }
  glutPostRedisplay();
}

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

void init()
{
  printf("0015gl.c running Pi=%f \n", Pi);
  /* 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(0.0, 4.0, 0.0, 2.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);
  glutMouseFunc(mouse);
  init();
  glutMainLoop();
  return 0;
}

