More info on this and his other works on his website.
]]>Vimeo’s compression screws up the details quite a bit so watch it in action in realtime here.
As there are some random values at work, refreshing will yield variations.
Based on the function designed by D. Sleator in 1976: f(x, y) = ((x ^ y) & ((y – 350) >> 3)) ** 2.
]]>
/*
* harmonograph.cpp
*
* Created by Brecht Debackere on 24/04/12.
* 2012 Autofasurer.
*
*/
#include <GLUT/glut.h>
#include <iostream>
#include <math.h>
using namespace std;
//initialising variables
float fRed, fGreen, fBlue, fXpos, fYpos, fFrequency, fAmplitude, fPhase, fTime, fPointsize;
bool fullScreen = false;
//initialising states
void init()
{
glClearColor(0.0,0.0,0.0,1.);
//init some random values
fFrequency = (rand()%500-250)/5.0;
fPhase = (rand()%500-250)/5.0;
fAmplitude = (rand()%500-250)/5.0;
fRed = (rand()%100)/1000.0;
fGreen = (rand()%100)/1000.0;
fBlue = (rand()%100)/1000.0;
glEnable(GL_POINT_SMOOTH);
glPointSize(0.5f);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
}
//reshaping the viewport and projection
void reshape(int width, int height)
{
glViewport(0, 0, 640, 480);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(120.,(GLfloat) width/(GLfloat) height,0.1, 800.0);
gluLookAt(0.0,0.0,12.0, 0.0, 0.0, 0.0, 0,1,0);
glMatrixMode(GL_MODELVIEW);
}
//reading the keyboard input
void key(unsigned char key, int x, int y){
switch (key){
case 32://press spacebar for a new random figure
fFrequency = (rand()%500-250)/5.0;
fPhase = (rand()%500-250)/5.0;
fAmplitude = (rand()%500-250)/5.0;
fRed = (rand()%100)/1000.0;
fGreen = (rand()%100)/1000.0;
fBlue = (rand()%100)/1000.0;
fTime = 0.0;
break;
case 27://escape toggles fullscreen
fullScreen = !fullScreen;
if (fullScreen) {
glutFullScreen();
}
else {
glutReshapeWindow(640, 480);
glutPositionWindow(100, 100);
}
break;
}
}
//drawing and displaying
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_POINTS);
while (fTime < 400.0) {
glColor4f(fRed, fGreen, fBlue, 0.1);
fXpos = -10*(cos(fFrequency * fTime) + cos(fPhase * fTime)*0.5 + cos(fAmplitude * fTime)*0.33);
fYpos = -10*(sin(fFrequency * fTime) + sin(fPhase * fTime)*0.5 + sin(fAmplitude * fTime)*0.33);
glVertex3f(fXpos, fYpos, 0);
fTime += 0.002;
}
glEnd();
fFrequency -= 0.00001;
fAmplitude += 0.00001;
fPhase += 0.00001;
fTime = 0.0;
glutSwapBuffers();
}
//main loop with initialising of window and glut, assigning functions
int main(int argc, char** argv)
{
srand(time(NULL));
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutCreateWindow("Harmonograph");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(key);
glutMainLoop();
return 0;
}
]]>