Skip to content

Instantly share code, notes, and snippets.

@tai2
Created May 24, 2013 01:18
Show Gist options
  • Select an option

  • Save tai2/5640702 to your computer and use it in GitHub Desktop.

Select an option

Save tai2/5640702 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <GLUT/glut.h>
#define KEY_ESC 27
#define WINDOW_POS_X 100
#define WINDOW_POS_Y 100
#define DEF_SCREEN_WIDTH 200
#define DEF_SCREEN_HEIGHT 200
struct complex {
double r;
double i;
};
static int curr_width = 0;
static int curr_height = 0;
static GLubyte *screen_buf = NULL;
static int fullscreen = 0;
static clock_t c_orig = 0;
// The five parameters
static struct complex p[5] = {{50, -30}, {18, 8}, {12, -10}, {-14, -60}, {40, 20}};
static void
keyboard(unsigned char c, int x, int y)
{
switch (c) {
case KEY_ESC:
exit(0);
break;
case 'f':
if (fullscreen) {
glutReshapeWindow(DEF_SCREEN_WIDTH, DEF_SCREEN_HEIGHT);
glutPositionWindow(WINDOW_POS_X, WINDOW_POS_Y);
fullscreen = 0;
} else {
glutFullScreen();
fullscreen = 1;
}
break;
}
}
void
idle()
{
glutPostRedisplay();
}
static void
reshape(int w, int h)
{
curr_width = w;
curr_height = h;
if (screen_buf) {
free(screen_buf);
}
screen_buf = (GLubyte *)malloc(curr_width * curr_height * 4);
if (!screen_buf) {
abort();
}
}
static void
draw_pixel(int x, int y, GLubyte r, GLubyte g, GLubyte b)
{
int base = 4 * ((curr_height - 1 - y) * curr_width + x);
if (0 <= x && x < curr_width && 0 <= y && y < curr_height) {
screen_buf[base + 0] = r;
screen_buf[base + 1] = g;
screen_buf[base + 2] = b;
screen_buf[base + 3] = 255;
}
}
static double
fourier(double t, double a[], double b[])
{
int k;
double r = 0;
for (k = 0; k < 6; k++) {
r += a[k] * cos(k * t) + b[k] * sin(k * t);
}
return r;
}
static void
display()
{
double ax[6] = {0, 0, 0, p[2].r, 0, p[3].r};
double bx[6] = {0, p[0].r, p[1].r, 0, 0, 0 };
double ay[6] = {0, p[3].i, 0, 0, 0, 0 };
double by[6] = {0, p[0].i, p[1].i, p[2].i, 0, 0 };
double t, tstart, tend;
double x0, y0;
double past = (double)(clock() - c_orig) / CLOCKS_PER_SEC;
memset(screen_buf, 0, curr_width * curr_height * 4);
tstart = 0.4 + 1.3 * M_PI;
tend = 2 * M_PI + 0.9 * M_PI;
for (t = tstart; t < tend; t += (tend - tstart) / 1000) {
double x = fourier(t, ax, bx);
double y = fourier(t, ay, by);
draw_pixel(y + curr_width / 2, x + curr_height / 2, 255, 255, 255);
}
tstart = 2 * M_PI + 0.9 * M_PI;
tend = 0.4 + 3.3 * M_PI;
x0 = fourier(tstart, ax, bx);
y0 = fourier(tstart, ay, by);
for (t = tstart; t < tend; t += (tend - tstart) / 1000) {
double x = fourier(t, ax, bx);
double y = fourier(t, ay, by);
x += sin((y - y0) * M_PI / 1000) * sin(past) * p[4].r;
draw_pixel(y + curr_width / 2, x + curr_height / 2, 255, 255, 255);
}
draw_pixel(p[4].i + curr_width / 2, -p[4].i + curr_height / 2, 255, 255, 255);
glWindowPos2i(0, 0);
glDrawPixels(curr_width, curr_height, GL_RGBA, GL_UNSIGNED_BYTE, screen_buf);
glutSwapBuffers();
}
int
main(int argc, char** argv)
{
srand(0);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
glutInitWindowSize(DEF_SCREEN_WIDTH, DEF_SCREEN_HEIGHT);
glutInitWindowPosition(WINDOW_POS_X, WINDOW_POS_Y);
glutCreateWindow(argv[0]);
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
c_orig = clock();
glShadeModel(GL_FLAT);
glutMainLoop();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment