January 18, 2014

Rainbow - part 5

I didn't realize this before - converting RGB values to OpenGL colors is really easy - just convert the RGB value by dividing by 255.  I wanted DeepBlueSky with RGB values (0, 212, 255), so the corresponding OpenGL colors are (0, 0.83, 1).

I did a bit more refactoring.  The rainbow is now smaller and its two ends are covered by "clouds" - just two ellipses for now.  And the background is blue.  For some reason there's two notches in the sides of each curved line in the rainbow but I'm not gonna worry about that for now.

So here's my new code:

#define PI 3.1415926535897932384626433832795

float colors[] =
{1.0, 0.0, 0.0,
 1.0, 0.5, 0.0,
 1.0, 1.0, 0.0,
 0.0, 1.0, 0.0,
 0.0, 0.0, 1.0,
 1.0, 0.0, 1.0,
 1.0, 1.0, 1.0};

typedef struct
{
  float x;
  float y;
} ELLIPSE;

int RED = 0, ORANGE = 3, YELLOW = 6, GREEN = 9, BLUE = 12, PURPLE = 15, WHITE = 18;

void drawCurvedLine(float a, float b, int color, float yPos) {
  ELLIPSE ellipse;
  glColor3f(colors[color], colors[color + 1], colors[color + 2]);

  for (float i = 0; i < PI; i+=.1) {
 ellipse.x = a * cos((float)i);
 ellipse.y = b * sin((float)i);
 glVertex3f(ellipse.x, ellipse.y + yPos, 0);

 ellipse.x = a * cos((float)(i + .1));
 ellipse.y = b * sin((float)(i + .1));
 glVertex3f(ellipse.x, ellipse.y + yPos, 0);
  }
}

void drawRainbow(float thickness) {
  float b = .8, a = .9, y = -0.1;
  float yEpsilon = .05, aEpsilon = .035;

  glLineWidth(thickness);
  glBegin(GL_LINES);

  drawCurvedLine(a, b, RED, y);
  drawCurvedLine(a - aEpsilon, b, ORANGE, y - yEpsilon);
  drawCurvedLine(a - 2*aEpsilon, b, YELLOW, y - 2*yEpsilon);
  drawCurvedLine(a - 3*aEpsilon, b, GREEN, y - 3*yEpsilon);
  drawCurvedLine(a - 4*aEpsilon, b, BLUE, y - 4*yEpsilon);
  drawCurvedLine(a - 5*aEpsilon, b, PURPLE, y - 5*yEpsilon);

  glEnd();
}

void drawEllipse(float a, float b, int color, float xPos, float yPos) {
glColor3f(colors[color], colors[color + 1], colors[color + 2]);

glBegin(GL_TRIANGLE_FAN);
glVertex2f(xPos,yPos);

for (float angle = 1; angle <= 360; angle += 0.2)
{
float xTemp = sin(angle)*a + xPos;
float yTemp = cos(angle)*b + yPos;
glVertex2f(xTemp,yTemp);
}

glEnd();
}

void display()
{
  glClearColor(0,.83,1,1);
  glClear(GL_COLOR_BUFFER_BIT);

  float thickness = 9;
  drawRainbow(thickness);

  float width = .3, height = .22;
  float xPos = -.68, yPos = -.2, xOtherSide = 1.37;
  drawEllipse(width, height, WHITE, xPos, yPos);
  drawEllipse(width, height, WHITE, xPos + xOtherSide, yPos);

  glutSwapBuffers();
}

int main(int argc, char** argv)
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
  glutInitWindowSize(600,600);

  glutCreateWindow("better rainbow");
  glutDisplayFunc(display);

  glutMainLoop();
}

And here it is now: