//cube.cpp
//This is my new code. Apparently I had derived the rotation matrices
wrong, so I re-checked VLA's texts. I had read Denthor's tutorials, but
one thing contradicted Abe's Demo School, but by reading these I learned
what I was doing wrong. Apparently it is ok to rotate an object defined
around the origin, and then translate it to the centre and forward all
at once when drawing it. The distance from the screen and to the centre
is hard-coded into the draw_cube() this code uses, but I will do a new
version to control those or at least input them to functions.
//#define gcc
//#define tc
#define wc
#include <conio.h> //getch(), Turbo C clrscr()
#ifdef wc
#include <graph.h> //Watcom _getactivepage(), _getvisualpage(),
_setactivepage(), _setvisualpage()
#include <i86.h> //Watcom delay()
#endif
#ifdef tc
#include <graphics.h> //Turbo C initgraph()
#endif
#include <math.h> //ceil(), cos(), floor(), sin(), sqrt()
#include <stdio.h> //printf()
#include <stdlib.h> //abs()
void put_pixel(int x, int y, int colour);
void line(int x0, int y0, int x5, int y5, int colour);
void draw_cube(int cube[][8], int colour);
#ifdef wc
void clrscr();
#endif
int main(void)
{
int i;
//define polyhedra
int cube_100[3][8]={{-50, -50, 50, 50, -50, -50, 50, 50},
{-50, 50, 50, -50, -50, 50, 50, -50},
{-50, -50, -50, -50, 50, 50, 50, 50}};
int cube_a[3][8]={{-50, -50, 50, 50, -50, -50, 50, 50},
{-50, 50, 50, -50, -50, 50, 50, -50},
{-50, -50, -50, -50, 50, 50, 50, 50}};
float x,y,z;
//define 3D angles and rotation matrices
//alpha, beta, lambda
//float a=0;
float a=0.7853; //pi/4;
//float b=0;
float b=0.7853;
float l=0.7853;
float mR3a[3][3]={{1, 0, 0},
{0, cos(a), -sin(a)},
{0, sin(a), cos(a)}};
float mR3b[3][3]={{cos(b), 0, sin(b)},
{0, 1, 0},
{-sin(b), 0, cos(b)}};
float mR3l[3][3]={{cos(l), -sin(l), 0},
{sin(l), cos(l), 0},
{0, 0, 1}};
float mR3r[3][3]={{cos(b)*cos(l)+sin(a)*sin(b)*sin(l),
-cos(a)*sin(l)+cos(l)*sin(a)*sin(b), cos(a)*sin(b)},
{cos(a)*sin(l), cos(a)*cos(l),-sin(a)},
{-cos(l)*sin(b)+cos(b)*sin(a)*sin(l),sin(b)*sin(l)+cos(b)*cos(l)*sin(a),
cos(a)*cos(b)}};
//clearscreen, set video mode 6256x4256x16; return error if impossible
//initgraph(VGA, 2, ""); //almost right in Turbo C
clrscr();
if(_setvideomode(_VRES256COLOR)==0)
{
printf("%s", "Cannot switch to 6256x480x256 colour mode.\r\n");
return 1;
}
draw_cube(cube_a,2);
getch();
//increment lambda and rotate cube on that or also other angles
for(l=0;l<=6.2831;l+=0.1047)
{
mR3r[0][0]=cos(b)*cos(l)+sin(a)*sin(b)*sin(l);
mR3r[0][1]=-cos(a)*sin(l)+cos(l)*sin(a)*sin(b);
mR3r[0][2]=cos(a)*sin(b);
mR3r[1][0]=cos(a)*sin(l);
mR3r[1][1]=cos(a)*cos(l);
mR3r[1][2]=-sin(a);
mR3r[2][0]=-cos(l)*sin(b)+cos(b)*sin(a)*sin(l);
mR3r[2][1]=sin(b)*sin(l)+cos(b)*cos(l)*sin(a);
mR3r[2][2]=cos(a)*cos(b);
for(i=0; i<=7; i++)
{
x=mR3r[0][0]*cube_100[0][i]+mR3r[0][1]*cube_100[1][i]+mR3r[0][2]*cube_100[2][i];
y=mR3r[1][0]*cube_100[0][i]+mR3r[1][1]*cube_100[1][i]+mR3r[1][2]*cube_100[2][i];
z=mR3r[2][0]*cube_100[0][i]+mR3r[2][1]*cube_100[1][i]+mR3r[2][2]*cube_100[2][i];
cube_a[0][i]=(int)x;
cube_a[1][i]=(int)y;
cube_a[2][i]=(int)z;
}
delay(10);
clrscr();
draw_cube(cube_a, 2);
}
//wait; set video mode to text; exit
getch();
_setvideomode(_TEXTC80);
return 0;
}
#ifdef wc
void clrscr()
{
//Watcom clearscreen
_clearscreen(_GCLEARSCREEN);
}
void put_pixel(int x, int y, int colour)
{
_moveto(x, y);
_setcolor(colour);
_setpixel(x, y);
}
void line(int x0, int y0, int x1, int y1, int colour)
{
_moveto(x0,y0);
_setcolor(colour);
_lineto(x1,y1);
}
#endif
void draw_cube(int cube[][8], int colour)
{
line(256*cube[0][0]/(256+cube[2][0])+320,256*cube[1][0]/(256+cube[2][0])+240,256*cube[0][1]/(256+cube[2][1])+320,256*cube[1][1]/(256+cube[2][1])+240,
colour);
line(256*cube[0][0]/(256+cube[2][0])+320,256*cube[1][0]/(256+cube[2][0])+240,256*cube[0][3]/(256+cube[2][3])+320,256*cube[1][3]/(256+cube[2][3])+240,
colour);
line(256*cube[0][0]/(256+cube[2][0])+320,256*cube[1][0]/(256+cube[2][0])+240,256*cube[0][4]/(256+cube[2][4])+320,256*cube[1][4]/(256+cube[2][4])+240,
colour);
line(256*cube[0][1]/(256+cube[2][1])+320,256*cube[1][1]/(256+cube[2][1])+240,256*cube[0][2]/(256+cube[2][2])+320,256*cube[1][2]/(256+cube[2][2])+240,
colour);
line(256*cube[0][1]/(256+cube[2][1])+320,256*cube[1][1]/(256+cube[2][1])+240,256*cube[0][5]/(256+cube[2][5])+320,256*cube[1][5]/(256+cube[2][5])+240,
colour);
line(256*cube[0][2]/(256+cube[2][2])+320,256*cube[1][2]/(256+cube[2][2])+240,256*cube[0][6]/(256+cube[2][6])+320,256*cube[1][6]/(256+cube[2][6])+240,
colour);
line(256*cube[0][3]/(256+cube[2][3])+320,256*cube[1][3]/(256+cube[2][3])+240,256*cube[0][2]/(256+cube[2][2])+320,256*cube[1][2]/(256+cube[2][2])+240,
colour);
line(256*cube[0][3]/(256+cube[2][3])+320,256*cube[1][3]/(256+cube[2][3])+240,256*cube[0][7]/(256+cube[2][7])+320,256*cube[1][7]/(256+cube[2][7])+240,
colour);
line(256*cube[0][4]/(256+cube[2][4])+320,256*cube[1][4]/(256+cube[2][4])+240,256*cube[0][7]/(256+cube[2][7])+320,256*cube[1][7]/(256+cube[2][7])+240,
colour);
line(256*cube[0][5]/(256+cube[2][5])+320,256*cube[1][5]/(256+cube[2][5])+240,256*cube[0][6]/(256+cube[2][6])+320,256*cube[1][6]/(256+cube[2][6])+240,
colour);
line(256*cube[0][5]/(256+cube[2][5])+320,256*cube[1][5]/(256+cube[2][5])+240,256*cube[0][4]/(256+cube[2][4])+320,256*cube[1][4]/(256+cube[2][4])+240,
colour);
line(256*cube[0][7]/(256+cube[2][7])+320,256*cube[1][7]/(256+cube[2][7])+240,256*cube[0][6]/(256+cube[2][6])+320,256*cube[1][6]/(256+cube[2][6])+240,
colour);
}