January 23, 2014

Polar graphs Part 1

I've recently been really interested in polar graphs.  I mean, you can make some really cool things with them:

 

And it's kind of tedious to punch in values into an online polar graphing app and see how the graph varies with different parameters, different ranges.  Maybe I just didn't look hard enough.  But I wanted to see if I could code my own.

So I did.  Here it is:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string>
#include <GL/glew.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glext.h>
using namespace std;

int window_width = 500, window_height = 500;
int xPos = 10, yPos = 10;
string angles[] = {"PI/2", "PI", "3PI/2", "2PI"};

#define PI 3.1415926535897932384626433832795

void writeText(int xPos, int yPos, string message) {
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0, window_width, 0.0, window_height, -1.0, 1.0);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glTranslatef(xPos, yPos, 0);
  glScalef(.3, .3, 0);
 
  glColor3f(.1176, .562, 1);
  for (size_t i = 0; i < message.length(); i++) {
 glutStrokeCharacter(GLUT_STROKE_ROMAN, message[i]);
  }
}

void drawAngle(int i) {

glMatrixMode (GL_MODELVIEW);
glPushMatrix ();
glLoadIdentity ();
glMatrixMode (GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();

glBegin(GL_POINTS);
for (float angle = 0; angle < i*(PI/2) + PI/2; angle += .005) {
float radius = angle * .1;
//message.append("1");
float x = radius * cos(angle);
float y = radius * sin(angle);

glVertex3f(x, y, 0);
}
glEnd();

glPopMatrix ();
glMatrixMode (GL_MODELVIEW);
glPopMatrix ();
}

void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor4f(.1176,.562,1,1);

int space = 10, yScale = window_height / 2, xScale = window_width / 2;

for (int i = 0; i < 4; i++) {
int xToggle = i & 0x1, yToggle = (i >> 1) & 0x1;
int xMin = xToggle * xScale, yMin = yToggle * yScale;
int xCorrection = xToggle * (space / 2), yCorrection = yToggle * (space / 2);
int width = xScale - (space / 2), height = yScale - (space / 2);

glViewport(xMin + xCorrection, yMin + yCorrection, width, height);
drawAngle(i);
writeText(xPos, yPos, angles[i]);
}

glFlush();
}


///////////////////////////////////////////////////////////////

int main(int argc, char** argv)
{
  glutInit(&argc, argv);
  glutInitWindowSize(window_width, window_height);
  glutCreateWindow("polar coordinates graph");
  glutDisplayFunc(display);
  glutMainLoop();
}

Again, don't completely understand everything up above (especially the matrix stuff) but the understanding is solidifying.

Sample output:



There are some things I'd like to do: display the equation above or below the graph (was having trouble with the Viewports), make even more ranges, have less hard-coded values and have the program eventually parse the r value as a string (which I would need to use recursive descent parsing for..)

But I think this helps a lot.  It automates a lot of the things I was doing by hand before.