Here are all of my files:
Main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <GL/glew.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include "constants.h"
#include "Parameters.h"
#include "Parser.h"
#include "ColorMap.h"
#include "Equations.h"
using namespace std;
/////////////////////////////////////
/////////////////////////////////////
string removeCharFromEnd(string s) {
int len = s.size();
s[len - 1] = s[len];
return s;
}
void writeText(int xPos, int yPos, float size, string message, string color) {
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(size, size, 0);
glColor3f(Colors[color].red, Colors[color].green, Colors[color].blue);
for (size_t i = 0; i < message.length(); i++) {
glutStrokeCharacter(GLUT_STROKE_ROMAN, message[i]);
}
}
float determineAngleIncrement() {
float angle_increment;
switch (angle_index) {
case 0:
angle_increment = PI/2;
break;
case 1:
angle_increment = PI/3;
break;
case 2:
angle_increment = PI/4;
break;
}
return angle_increment;
}
void drawAngle(int i, int equation, string color) {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glBegin(GL_POINTS);
glColor3f(Colors[color].red, Colors[color].green, Colors[color].blue);
float angle_increment = determineAngleIncrement();
for (float angle = 0; angle < i * angle_increment + angle_increment; angle += .005) {
// refactor this out
char *a = new char[equations[equation].size() + 1];
a[equations[equation].size()] = 0;
memcpy(a, equations[equation].c_str(), equations[equation].size());
float r = valueOfExpr(a, angle);
float x = r * cos(angle);
float y = r * sin(angle);
glVertex3f(x, y, 0);
}
glEnd();
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void displayGraphs()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor4f(1,1,1,1);
// would it be possible to put all this in a struct?
float header_font_size = .2, text_size = .3;
int numOfSquares = 9, numOfCols = sqrt(numOfSquares);
int mask = 0x3;
int space = 10;
int yScale = window_height / numOfCols, xScale = window_width / numOfCols;
for (int i = 0; i < numOfSquares; i++) {
// would it be possible to put all of this into a struct as well?
int xToggle = (i % numOfCols) & mask, yToggle = (i / numOfCols) & mask;
int xMin = xToggle * xScale, yMin = yToggle * yScale;
int xCorrection = xToggle * (space / numOfCols), yCorrection = yToggle * (space / numOfCols);
int width = xScale - (space / numOfCols), height = yScale - (space / numOfCols);
glViewport(xMin + xCorrection, yMin + yCorrection, width, height);
for (size_t graph = 0; graph < equations.size(); graph++) {
string color = DetermineIterator(graph)->first;
drawAngle(i, graph, color);
}
string white = "WHITE";
writeText(xPos, yPos, .3, angles[angle_index][i], white);
}
glFlush();
}
void displayEquations() {
InitializeEquations();
PrepareEquationsForParsing();
for (size_t i = 0, yCorrection = 0; i < equations.size(); i++, yCorrection += 50) {
string equation = removeCharFromEnd(equations[i]);
string color = DetermineIterator(i)->first;
writeText(xPos, yPos + yCorrection, .25, "r = " + equation, color);
}
}
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
InitializeColors();
glutInit(&argc, argv);
glutInitWindowSize(window_width, window_height);
glutCreateWindow("polar graphs");
glutDisplayFunc(displayGraphs);
glutInitWindowSize(200, 200);
glutCreateWindow("equations");
glutPositionWindow(540, 40);
glutDisplayFunc(displayEquations);
glutMainLoop();
}
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <GL/glew.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include "constants.h"
#include "Parameters.h"
#include "Parser.h"
#include "ColorMap.h"
#include "Equations.h"
using namespace std;
/////////////////////////////////////
/////////////////////////////////////
string removeCharFromEnd(string s) {
int len = s.size();
s[len - 1] = s[len];
return s;
}
void writeText(int xPos, int yPos, float size, string message, string color) {
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(size, size, 0);
glColor3f(Colors[color].red, Colors[color].green, Colors[color].blue);
for (size_t i = 0; i < message.length(); i++) {
glutStrokeCharacter(GLUT_STROKE_ROMAN, message[i]);
}
}
float determineAngleIncrement() {
float angle_increment;
switch (angle_index) {
case 0:
angle_increment = PI/2;
break;
case 1:
angle_increment = PI/3;
break;
case 2:
angle_increment = PI/4;
break;
}
return angle_increment;
}
void drawAngle(int i, int equation, string color) {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glBegin(GL_POINTS);
glColor3f(Colors[color].red, Colors[color].green, Colors[color].blue);
float angle_increment = determineAngleIncrement();
for (float angle = 0; angle < i * angle_increment + angle_increment; angle += .005) {
// refactor this out
char *a = new char[equations[equation].size() + 1];
a[equations[equation].size()] = 0;
memcpy(a, equations[equation].c_str(), equations[equation].size());
float r = valueOfExpr(a, angle);
float x = r * cos(angle);
float y = r * sin(angle);
glVertex3f(x, y, 0);
}
glEnd();
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void displayGraphs()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor4f(1,1,1,1);
// would it be possible to put all this in a struct?
float header_font_size = .2, text_size = .3;
int numOfSquares = 9, numOfCols = sqrt(numOfSquares);
int mask = 0x3;
int space = 10;
int yScale = window_height / numOfCols, xScale = window_width / numOfCols;
for (int i = 0; i < numOfSquares; i++) {
// would it be possible to put all of this into a struct as well?
int xToggle = (i % numOfCols) & mask, yToggle = (i / numOfCols) & mask;
int xMin = xToggle * xScale, yMin = yToggle * yScale;
int xCorrection = xToggle * (space / numOfCols), yCorrection = yToggle * (space / numOfCols);
int width = xScale - (space / numOfCols), height = yScale - (space / numOfCols);
glViewport(xMin + xCorrection, yMin + yCorrection, width, height);
for (size_t graph = 0; graph < equations.size(); graph++) {
string color = DetermineIterator(graph)->first;
drawAngle(i, graph, color);
}
string white = "WHITE";
writeText(xPos, yPos, .3, angles[angle_index][i], white);
}
glFlush();
}
void displayEquations() {
InitializeEquations();
PrepareEquationsForParsing();
for (size_t i = 0, yCorrection = 0; i < equations.size(); i++, yCorrection += 50) {
string equation = removeCharFromEnd(equations[i]);
string color = DetermineIterator(i)->first;
writeText(xPos, yPos + yCorrection, .25, "r = " + equation, color);
}
}
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
InitializeColors();
glutInit(&argc, argv);
glutInitWindowSize(window_width, window_height);
glutCreateWindow("polar graphs");
glutDisplayFunc(displayGraphs);
glutInitWindowSize(200, 200);
glutCreateWindow("equations");
glutPositionWindow(540, 40);
glutDisplayFunc(displayEquations);
glutMainLoop();
}
constants.h
#define PI 3.1415926535897932384626433832795
int PI_2 = 0, PI_3 = 1, PI_4 = 2;
std::string angles[3][11] = {
{"PI/2", "PI", "3PI/2", "2PI", "5PI/2", "3PI", "7PI/2", "4PI", "9PI/2", "5PI", "11PI/2"},
{"PI/3", "2PI/3", "PI", "4PI/3", "5PI/3", "2PI", "7PI/3", "10PI/3", "11PI/3", "4PI", "13PI/3"},
{"PI/4", "PI/2", "3PI/4", "PI", "9PI/4", "5PI/2", "11PI/4", "3PI", "13PI/4", "7PI/2", "15PI/4"}
};
int PI_2 = 0, PI_3 = 1, PI_4 = 2;
std::string angles[3][11] = {
{"PI/2", "PI", "3PI/2", "2PI", "5PI/2", "3PI", "7PI/2", "4PI", "9PI/2", "5PI", "11PI/2"},
{"PI/3", "2PI/3", "PI", "4PI/3", "5PI/3", "2PI", "7PI/3", "10PI/3", "11PI/3", "4PI", "13PI/3"},
{"PI/4", "PI/2", "3PI/4", "PI", "9PI/4", "5PI/2", "11PI/4", "3PI", "13PI/4", "7PI/2", "15PI/4"}
};
Parameters.h
int window_width = 500, window_height = 500;
int xPos = 10, yPos = 10;
int angle_index = PI_4;
int xPos = 10, yPos = 10;
int angle_index = PI_4;
Equations.h
#pragma once
#include <string>
#include <vector>
extern std::vector<std::string> equations;
void InitializeEquations();
void PrepareEquationsForParsing();
#include <string>
#include <vector>
extern std::vector<std::string> equations;
void InitializeEquations();
void PrepareEquationsForParsing();
Equations.cpp
#include "Equations.h"
std::vector<std::string> equations;
void InitializeEquations() {
equations.push_back("sin(2*t)");
equations.push_back("0.85*cos(4*t)");
equations.push_back("sin(3*t)");
equations.push_back("2*cos(2*t)");
equations.push_back("2*sin(2*t)");
equations.push_back("2*sin(4*t)");
}
void PrepareEquationsForParsing() {
for (size_t i = 0; i < equations.size(); i++) {
equations[i].append("!");
}
}
std::vector<std::string> equations;
void InitializeEquations() {
equations.push_back("sin(2*t)");
equations.push_back("0.85*cos(4*t)");
equations.push_back("sin(3*t)");
equations.push_back("2*cos(2*t)");
equations.push_back("2*sin(2*t)");
equations.push_back("2*sin(4*t)");
}
void PrepareEquationsForParsing() {
for (size_t i = 0; i < equations.size(); i++) {
equations[i].append("!");
}
}
ColorTriple.h
#pragma once
class ColorTriple {
public:
float red, blue, green;
ColorTriple();
ColorTriple(float, float, float);
};
class ColorTriple {
public:
float red, blue, green;
ColorTriple();
ColorTriple(float, float, float);
};
ColorTriple.cpp
#include "ColorTriple.h"
ColorTriple::ColorTriple (float r, float g, float b) {
red = r;
green = g;
blue = b;
}
ColorTriple::ColorTriple() {
red = 0.0;
green = 0.0;
blue = 0.0;
}
ColorTriple::ColorTriple (float r, float g, float b) {
red = r;
green = g;
blue = b;
}
ColorTriple::ColorTriple() {
red = 0.0;
green = 0.0;
blue = 0.0;
}
ColorMap.h
#pragma once
#include <map>
#include <string>
#include "ColorTriple.h"
//typedef std::map<std::string, ColorTriple> map_type;
extern std::map<std::string, ColorTriple> Colors;
void InitializeColors();
std::map<std::string, ColorTriple>::iterator DetermineIterator(int i);
#include <map>
#include <string>
#include "ColorTriple.h"
//typedef std::map<std::string, ColorTriple> map_type;
extern std::map<std::string, ColorTriple> Colors;
void InitializeColors();
std::map<std::string, ColorTriple>::iterator DetermineIterator(int i);
#include "ColorMap.h"
std::map<std::string, ColorTriple> Colors;
// this ordering doesn't stay
void InitializeColors() {
Colors.insert(std::pair<std::string, ColorTriple>("RED", ColorTriple(1.0f, 0.0f, 0.0f)));
Colors.insert(std::pair<std::string, ColorTriple>("ORANGE", ColorTriple(1.0f, 0.5f, 0.0f)));
Colors.insert(std::pair<std::string, ColorTriple>("YELLOW", ColorTriple(1.0f, 1.0f, 0.0f)));
Colors.insert(std::pair<std::string, ColorTriple>("GREEN", ColorTriple(0.0f, 1.0f, 0.0f)));
Colors.insert(std::pair<std::string, ColorTriple>("BLUE", ColorTriple(0.2f, 0.2f, 0.5f)));
Colors.insert(std::pair<std::string, ColorTriple>("PURPLE", ColorTriple(1.0f, 0.0f, 1.0f)));
Colors.insert(std::pair<std::string, ColorTriple>("WHITE", ColorTriple(1.0f, 1.0f, 1.0f)));
}
std::map<std::string, ColorTriple>::iterator DetermineIterator(int i) {
int color = i % (Colors.size());
std::map<std::string, ColorTriple>::iterator it = Colors.begin();
for (int placeHolder = 0; placeHolder != color; ++it, placeHolder++) { }
return it;
}
std::map<std::string, ColorTriple> Colors;
// this ordering doesn't stay
void InitializeColors() {
Colors.insert(std::pair<std::string, ColorTriple>("RED", ColorTriple(1.0f, 0.0f, 0.0f)));
Colors.insert(std::pair<std::string, ColorTriple>("ORANGE", ColorTriple(1.0f, 0.5f, 0.0f)));
Colors.insert(std::pair<std::string, ColorTriple>("YELLOW", ColorTriple(1.0f, 1.0f, 0.0f)));
Colors.insert(std::pair<std::string, ColorTriple>("GREEN", ColorTriple(0.0f, 1.0f, 0.0f)));
Colors.insert(std::pair<std::string, ColorTriple>("BLUE", ColorTriple(0.2f, 0.2f, 0.5f)));
Colors.insert(std::pair<std::string, ColorTriple>("PURPLE", ColorTriple(1.0f, 0.0f, 1.0f)));
Colors.insert(std::pair<std::string, ColorTriple>("WHITE", ColorTriple(1.0f, 1.0f, 1.0f)));
}
std::map<std::string, ColorTriple>::iterator DetermineIterator(int i) {
int color = i % (Colors.size());
std::map<std::string, ColorTriple>::iterator it = Colors.begin();
for (int placeHolder = 0; placeHolder != color; ++it, placeHolder++) { }
return it;
}
Parser.h
#pragma once
#include <math.h>
#include <string>
float valueOfDigitSeq(char source[], float angle);
float valueOfFactor(char source[], float angle);
float valueOfTerm(char source[], float angle);
float valueOfExpr(char source[], float angle);
#include <math.h>
#include <string>
float valueOfDigitSeq(char source[], float angle);
float valueOfFactor(char source[], float angle);
float valueOfTerm(char source[], float angle);
float valueOfExpr(char source[], float angle);
Parser.cpp
#include "Parser.h"
void remove(char s[], int remove) {
for (size_t i = 0; i < strlen(s); i++) {
s[i] = s[i + remove];
}
}
float valueOfDigitSeq(char source[], float angle) {
if (source[0] == 't') {
remove(source, 1);
return angle;
}
float value = 0;
if (source[0] >= '0' && source[0] <= '9') {
value = (float)(source[0] - '0');
}
remove(source, 1);
while (source[0] >= '0' && source[0] <= '9') {
value *= 10;
value += (float)(source[0] - '0');
remove(source, 1);
}
float trailing = 0.0;
int placeHolder = 10;
if (source[0] == '.') {
remove(source, 1);
while (source[0] >= '0' && source[0] <= '9') {
float digit = (float)(source[0] - '0') / placeHolder;
placeHolder *= 10;
trailing += digit;
remove(source, 1);
}
}
return value + trailing;
}
float valueOfFactor(char source[], float angle) {
float value;
if (source[0] == '(' || source[0] == 's' || source[0] == 'c')
{
if (source[0] == '(')
{
remove(source, 1);
value = valueOfExpr(source, angle);
remove(source, 1);
}
else if (source[0] == 's')
{
remove(source, 3);
value = sin(valueOfFactor(source, angle));
}
else
{
remove(source, 3);
value = cos(valueOfExpr(source, angle));
}
}
else
{
value = valueOfDigitSeq(source, angle);
}
return value;
}
float valueOfTerm(char source[], float angle) {
float value = valueOfFactor(source, angle);
while (source[0] == '*' || source[0] == '/')
{
char mystery = source[0];
remove(source, 1);
if (mystery == '*')
{
value = value * valueOfTerm(source, angle);
}
else if (mystery == '/')
{
value = value / valueOfTerm(source, angle);
}
}
return value;
}
float valueOfExpr(char source[], float angle) {
float value = valueOfTerm(source, angle);
while (source[0] == '+' || source[0] == '-')
{
char mystery = source[0];
remove(source, 1);
if (mystery == '+')
{
value = value + valueOfTerm(source, angle);
}
else
{
value = value - valueOfTerm(source, angle);
}
}
return value;
}
void remove(char s[], int remove) {
for (size_t i = 0; i < strlen(s); i++) {
s[i] = s[i + remove];
}
}
float valueOfDigitSeq(char source[], float angle) {
if (source[0] == 't') {
remove(source, 1);
return angle;
}
float value = 0;
if (source[0] >= '0' && source[0] <= '9') {
value = (float)(source[0] - '0');
}
remove(source, 1);
while (source[0] >= '0' && source[0] <= '9') {
value *= 10;
value += (float)(source[0] - '0');
remove(source, 1);
}
float trailing = 0.0;
int placeHolder = 10;
if (source[0] == '.') {
remove(source, 1);
while (source[0] >= '0' && source[0] <= '9') {
float digit = (float)(source[0] - '0') / placeHolder;
placeHolder *= 10;
trailing += digit;
remove(source, 1);
}
}
return value + trailing;
}
float valueOfFactor(char source[], float angle) {
float value;
if (source[0] == '(' || source[0] == 's' || source[0] == 'c')
{
if (source[0] == '(')
{
remove(source, 1);
value = valueOfExpr(source, angle);
remove(source, 1);
}
else if (source[0] == 's')
{
remove(source, 3);
value = sin(valueOfFactor(source, angle));
}
else
{
remove(source, 3);
value = cos(valueOfExpr(source, angle));
}
}
else
{
value = valueOfDigitSeq(source, angle);
}
return value;
}
float valueOfTerm(char source[], float angle) {
float value = valueOfFactor(source, angle);
while (source[0] == '*' || source[0] == '/')
{
char mystery = source[0];
remove(source, 1);
if (mystery == '*')
{
value = value * valueOfTerm(source, angle);
}
else if (mystery == '/')
{
value = value / valueOfTerm(source, angle);
}
}
return value;
}
float valueOfExpr(char source[], float angle) {
float value = valueOfTerm(source, angle);
while (source[0] == '+' || source[0] == '-')
{
char mystery = source[0];
remove(source, 1);
if (mystery == '+')
{
value = value + valueOfTerm(source, angle);
}
else
{
value = value - valueOfTerm(source, angle);
}
}
return value;
}
Some things I learned along the way:
- Never put using statements in your header files
- It's okay to put #include though
- If you have a single variable in your header file, put extern in front of it (to indicate it's declared elsewhere) and in the .cpp file that's where you declare it (and you don't use extern there). This caused me a lot of trouble
- Map does not keep ordering. I guess I just assumed it did. So I was surprised when my colors all came out looking different
- Use #pragma once in header files to make life easier. I don't know how guards work as a result
- printf("%s") for strings doesn't work, because %s only works for char*. Use s.c_str() instead.