![]() |
are you ready for a mindfuck? |
|
....::::Menu::::.... ---------------------------...::About::... ...::Articles::... ...::Contact::... ...::Home & News::... ...::Links & Credits::... --------------------------- --------------------------- |
Spiralby Elie De BrauwerGoal of this fileThis files takes the circle article a little step further, now we will create a spiral and we will let it rotate around it's center (let's call it a mindfuck). While running we will be able to change the number of lines used to created the circle (in that way it will also be possible to create a spiral of triangles) and also modify the number of circles in the spiral. History of this file
The concept
If you remember the circle article we determined the coordinates that were on a circle by
using the formulas L*cos(alpha) and L*sin(alpha). L was a constant (the radius of the circle) and alpha was
a value varying from 0 to 360 degrees (or from 0 to 2*Pi radians). Now suppose we make L variable and write it in function
of alpha and we let alpha vary from 0 to k*360 degrees (or from 0 to 2*k*Pi radians), k is a whole number 1,2,3,... . The concept in code
This spiral finds it origin in polar coordinates (defined by a corner and a distance) that are transformad to
cartesian coordinates (x and y).You can see easily that this spiral can't be defined by a normal function (y=f(x),
like for example the parabola y=x^2).
// we draw a line strip a entire shape that isn't
// closed at the end and consists of line segments
glBegin(GL_LINE_STRIP);
// a for loop splitting the figure in num_circ*num_lines
// vertices
for(int i =0;i<num_circ*num_lines;i++){
// the angle lies between 0 and num_circ * 2 * Pi
angle = i*2*M_PI/num_lines;
// we begin to draw the spiral at the border and move to the center
// 1.0 (the maximum) - delta (function of the angle and [0,1.0]
length = 1.0 - i* 1.0 / (num_circ*num_lines);
// put the vertex on the screen but multiply with the length since
// the length isn't everywhere 1 like with a circle.
glVertex2d(length*cos(angle),length*sin(angle));
}
// all good things come to and end.
glEnd();
RotatingWhen we call glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); or the floated flavor glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); everything that is drawn after the rotation command will be rotated with an angle angle around the vector (x,y,z). The angle specified has to be in degrees (not in radians like sin() and cos()). So if you would call glRotated(30.0,0.0,0.0,1.0); everything will be rotated 30 degrees around the Z-axis. The vector (1,0.0) is the X-axis, the vector (0,1,0) the Y-axis and the vector (0,0,1) is the Z-axis. Putting it all together In the sourcecode below you can see that we use the glutIdleFunc() to define a callback that increments the
angle over which is rotated. If you have a fast machine this will run fast and if you have a slow machine this will
run slow, this is one of the disadvantages of using the glutIdleFunc(), but using the glutIdleFunc() is in this case
easier than calculating time differences. We can disable the idlecallback by calling glutIdleFunc(NULL);.
Any callback can be disabled/overwritten/changed using this method. ![]() A spiral in the normal sense of the word. ![]() A spiral that consists of concentric triangles instead of circles
#include<iostream>
#include<cmath>
#include<GL/glut.h>
using namespace std;
typedef unsigned char uchar;
// number of line segments
static int num_lines = 35;
static int num_circ = 20;
static GLdouble rot_angle = 0;
// callback prototypes
void disp(void);
void keyb(uchar k, int x, int y);
void reshape(int x, int y);
void idle(void);
////////////////////////////////
// main
int main(int argc, char **argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(400,400);
glutInitWindowPosition(100,100);
glutCreateWindow("spiral.cpp");
glClearColor(0.0,0.0,0.0,0.0);
glutDisplayFunc(disp);
glutKeyboardFunc(keyb);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutMainLoop();
return 0;
}
////////////////
// disp
void disp(void){
double angle, length;
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glRotated(rot_angle, 0.0,0.0,1.0);
// no GL_LINE_LOOP since it isn't a closed loop
glBegin(GL_LINE_STRIP);
for(int i =0;i<num_circ*num_lines;i++){
angle = i*2*M_PI/num_lines;
length = 1.0 - i* 1.0 / (num_circ*num_lines);
glVertex2d(length*cos(angle),length*sin(angle));
}
glEnd();
glutSwapBuffers();
}
////////////////
// idle
void idle(void){
rot_angle++;
// avoid rot_angle overflow
while(rot_angle > 360)
rot_angle -= 360;
// redisplay
glutPostRedisplay();
}
///////////////////////////////////
// keyb
void keyb(uchar k, int x, int y){
/*
Commands:
-> q: quit
-> s: start rotate
-> S: stop rotate
-> c: more circles
-> C: less circles
-> l: more lines
-> L: less lines
*/
switch (k){
case 'q':
exit(0);
break;
case 'c':
if(num_lines < 99){
num_circ++;
cout << "Spiral consists of " << num_circ << " circles " << endl;
glutPostRedisplay();
}
break;
case 'C':
if(num_circ >3){
num_circ--;
cout << "Spiral consists of " << num_circ << " circles " << endl;
glutPostRedisplay();
}
break;
case 'l':
if(num_lines < 99){
num_lines++;
cout << "Circle consists of " << num_lines << " lines " << endl;
glutPostRedisplay();
}
break;
case 'L':
if(num_lines >3){
num_lines--;
cout << "Circle consists of " << num_lines << " lines " << endl;
glutPostRedisplay();
}
break;
case 's':
glutIdleFunc(idle);
cout << "Rotating " << endl;
break;
case 'S':
glutIdleFunc(NULL);
cout << "Not rotating" << endl;
break;
}
}
//////////////////////////
// reshape
void reshape(int x,int y){
if(x<y)
glViewport(0,(y-x)/2,x,x);
else
glViewport((x-y)/2,0,y,y);
}
You can also download the sourcecode |