#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glut.h>
#include <time.h>
#include <math.h>
GLUquadricObj *cylinder;
struct vec
{
float x,y,z;
vec(float x, float y, float z) : x(x), y(y), z(z) {}
vec &operator-=(vec b) { x-=b.x; y-=b.y; z-=b.z; return *this; }
vec &operator*=(float f) { x*=f; y*=f; z*=f; return *this; }
};
float dot(vec a, vec b) { return a.x*b.x + a.y*b.y + a.z*b.z; }
vec cross(vec a, vec b) { return vec(a.y*b.z - b.y*a.z, -a.x*b.z + b.x*a.z, a.x*b.y - b.x*a.y); }
vec normalize(vec a) { return a*=1.f/sqrtf(dot(a,a)); }
void DrawLine(vec a, vec b)
{
vec p = (vec(b) -= a);
if (dot(p, p)<0.001)
return;
float len = sqrtf(dot(p, p));
p *= 1.f/len;
vec z = vec(0, 0, 1);
vec c = cross(p, z);
if (dot(c, c) < 0.001)
c = vec(1, 0, 0);
glPushMatrix();
glTranslatef(a.x, a.y, a.z);
glRotatef(-acos(dot(z, p))/3.14*180, c.x, c.y, c.z);
gluCylinder(cylinder, 0.02, 0.02, len, 10, 10);
glPopMatrix();
}
clock_t start = clock();
void Display()
{
double t = 1.*(clock()-start)/CLOCKS_PER_SEC;
glDepthMask(1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ;
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, 1, 0.1, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -1.5);
float edge_color[4] = { 0, 1, 0, 0 };
glMaterialfv(GL_FRONT, GL_DIFFUSE, edge_color);
float cub[2][2][2][2][4];
for (int x=0; x<2; ++x)
{
for (int y=0; y<2; ++y)
for (int z=0; z<2; ++z)
for (int w=0; w<2; ++w)
{
cub[x][y][z][w][0] = (2*x-1)*0.5;
cub[x][y][z][w][1] = (2*y-1)*0.5;
cub[x][y][z][w][2] = (2*z-1)*0.5;
cub[x][y][z][w][3] = (2*w-1)*0.5;
}
}
struct matrix
{
float m[4][4];
};
matrix rotation1, rotation2;
for (int i=0; i<4; ++i)
for (int j=0; j<4; ++j)
rotation1.m[i][j] = i==j;
for (int axe2 = 0; axe2<4; ++axe2)
{
for (int axe1 = 0; axe1<axe2; ++axe1)
{
rotation2 = rotation1;
float phi = 10 + t*sqrtf(10+axe1*axe2 + axe1 + axe2)*0.1;
float f[2][2] = { { cos(phi), -sin(phi) }, { sin(phi), cos(phi) } };
int axes[2] = { axe1, axe2 };
for (int i = 0; i < 2; ++i)
for (int k = 0; k<4; ++k)
rotation1.m[k][axes[i]] = 0;
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
for (int k = 0; k<4; ++k)
rotation1.m[k][axes[i]] += f[i][j]*rotation2.m[k][axes[j]];
}
}
float(*cub_ptr)[4] = cub[0][0][0];
float rotated_cub[16][4] = {};
for (int v=0; v<16; ++v)
for (int i=0; i<4; ++i)
for (int j=0; j<4; ++j)
rotated_cub[v][i] += rotation1.m[j][i]*cub_ptr[v][j];
for (int v1=0; v1<16; ++v1)
for (int v2=0; v2<v1; ++v2)
if (!((v1 ^ v2)&((v1 ^ v2)-1)))
DrawLine(*(vec*)&rotated_cub[v1], *(vec*)&rotated_cub[v2]);
float red[4] = { 1, 0, 0, 0.2 };
float blue[4] = { 0, 0, 1, 0.2 };
glDisable(GL_LIGHTING);
glDepthMask(0);
glEnable(GL_BLEND);
glDisable(GL_CULL_FACE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
{
glBegin(GL_QUADS);
#define QUAD0(a, b, c, d) glVertex3fv(rotated_cub[a]);glVertex3fv(rotated_cub[b]);glVertex3fv(rotated_cub[c]);glVertex3fv(rotated_cub[d]);
#define QUAD(a, b, c, d, bit);
QUAD(0, 8, 12, 4, (2));
QUAD(0, 8, 10, 2, (4));
QUAD(0, 2, 6, 4, (8));
} glEnd();
glDisable(GL_BLEND);
glutSwapBuffers();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(700,700);
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("HyperCube 4D->3D Proection");
glutIdleFunc(Display);
glutDisplayFunc(Display);
cylinder = gluNewQuadric();
glutMainLoop();
} |