Groups | Search | Server Info | Login | Register
Groups > comp.sys.ibm.pc.demos > #18
| From | David Melik <dchmelik@hipplanet.com> |
|---|---|
| Newsgroups | comp.graphics.algorithms, comp.sys.ibm.pc.demos |
| Subject | questions about rotating cube graphics in C++ (aiming for C) |
| Date | 2012-06-22 00:53 -0700 |
| Organization | A noiseless patient Spider |
| Message-ID | <js189n$aso$1@dont-email.me> (permalink) |
Cross-posted to 2 groups.
//cube.cpp
//I am having trouble with the following C++ code (aiming to be C, but
with a declaration error if compiled in C)--or perhaps mainly the
math--to rotate a cube. The code is for Watcom C++, but I added a
#define for Turbo C++ but do not recall if I tested that. This was
originally for Watcom 11, and I compiled it in Open Watcom 1.9 under
DOSbox. Depending on how a,b (3D alpha, beta) are defined, the code has
shown an elongated pyramid from the top left ((1,1)) to the screen
centre, and has moved it around a bit (this version just shows a few
lines coming from (1,1).) However, I think perhaps what I read about 3D
is wrong. It seems the way I have my 101-unit-sized cube defined, when
vertices' z-values are translated from the range (-50,50) to (1,101),
101 is too big to divide the x and y by and divides those down to about
1. Is it even right that to calculate x,y from 3D onto the plane you let
x=x/z, y=y/z? Each line() in my draw_cube() uses those calculations. It
is hard for me to figure out if my equations are wrong, or if there is
some bug in my code. I would like to learn more C and graphics
programming... can anyone help with this 3D cube problem?
//#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 x1, int y1, int colour);
//void circle();
void draw_square(int square[][4], int colour);
void draw_cube(int cube[][8], int colour);
//void translate_shape(int shape[][sizeof(int / 2)], int colour);
//Watcom
//void wait_retrace();
void clrscr();
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.785398; //pi/4;
float b=0.785398;
float l=0.785398;
//matrices for rotation in 3D realspace by a,b,l. When compiled as a
C file, I get an error for these array declarations that they must be
constant. I want my program to be C, and it seems the trigonometric
functions do have only one value. Other than that, I am not declaring
these as constants; I do not really understand the error. If I recall,
array assignments may have to be separate from declarations in C. Is
this so--or perhaps at least if they use functions?
float mR3a[3][3]={{1, 0, 0}, {0, cos(b), sin(b)}, {0, -sin(l), cos(l)}};
float mR3b[3][3]={{cos(a), 0, -sin(a)}, {0, 1, 0}, {sin(l), 0, cos(l)}};
float mR3l[3][3]={{cos(a), sin(a), 0}, {-sin(b), cos(b), 0}, {0, 0, 1}};
float mR3r[3][3]={{cos(b)*sin(l), cos(b)*sin(l), -sin(b)},
{sin(a)*sin(b)*cos(l)-cos(b)*sin(l), sin(a)*sin(b)*sin(l)+cos(a)*cos(b),
sin(a)*cos(b)}, {cos(a)*sin(b)*cos(l)+sin(a)*sin(l),
cos(a)*sin(b)*sin(l)-sin(a)*cos(b), cos(a)*cos(b)}};
//clearscreen, set video mode 640x480x16; return error if impossible
//initgraph(VGA, 2, ""); //almost right in Turbo C
clrscr();
if(_setvideomode(_VRES16COLOR)==0)
{
printf("%s", "Cannot switch to 640x480x16 colour mode.\r\n");
return 1;
}
//increment lambda and rotate cube on that or also other angles
for(l=0;l<=6.283185;l+=0.104720)
{
mR3r[0][0]=cos(b)*sin(l);
mR3r[0][1]=cos(b)*sin(l);
mR3r[0][2]=-sin(b);
mR3r[1][0]=sin(a)*sin(b)*cos(l)-cos(b)*sin(l);
mR3r[1][1]=sin(a)*sin(b)*sin(l)+cos(a)*cos(b);
mR3r[1][2]=sin(a)*cos(b);
mR3r[2][0]=cos(a)*sin(b)*cos(l)+sin(a)*sin(l);
mR3r[2][1]=cos(a)*sin(b)*sin(l)-sin(a)*cos(b);
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;
}
for(i=0;i<=7;i++)
{
cube_a[0][i]+=316;
cube_a[1][i]+=236;
cube_a[2][i]+=51;
}
delay(10);
clrscr();
draw_cube(cube_a, 2);
}
//wait; set video mode to text; exit
//For some reason, the program does not always get to the following
getch(), depending on how source is edited! It seems just to depend on
a,b angles and usually works when they are changed in a way that
displays an elongated pyramid. I have gone back and forth many times.
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(cube[0][0]/cube[2][0], cube[1][0]/cube[2][0],
cube[0][1]/cube[2][1], cube[1][1]/cube[2][1], colour);
line(cube[0][0]/cube[2][0], cube[1][0]/cube[2][0],
cube[0][3]/cube[2][3], cube[1][3]/cube[2][3], colour);
line(cube[0][0]/cube[2][0], cube[1][0]/cube[2][0],
cube[0][4]/cube[2][4], cube[1][4]/cube[2][4], colour);
line(cube[0][1]/cube[2][1], cube[1][1]/cube[2][1],
cube[0][2]/cube[2][2], cube[1][2]/cube[2][2], colour);
line(cube[0][1]/cube[2][1], cube[1][1]/cube[2][1],
cube[0][5]/cube[2][5], cube[1][5]/cube[2][5], colour);
line(cube[0][2]/cube[2][2], cube[1][2]/cube[2][2],
cube[0][7]/cube[2][7], cube[1][7]/cube[2][7], colour);
line(cube[0][3]/cube[2][3], cube[1][3]/cube[2][3],
cube[0][2]/cube[2][2], cube[1][2]/cube[2][2], colour);
line(cube[0][3]/cube[2][3], cube[1][3]/cube[2][3],
cube[0][4]/cube[2][4], cube[1][4]/cube[2][4], colour);
line(cube[0][4]/cube[2][4], cube[1][4]/cube[2][4],
cube[0][7]/cube[2][7], cube[1][7]/cube[2][7], colour);
line(cube[0][5]/cube[2][5], cube[1][5]/cube[2][5],
cube[0][6]/cube[2][6], cube[1][6]/cube[2][6], colour);
line(cube[0][5]/cube[2][5], cube[1][5]/cube[2][5],
cube[0][4]/cube[2][4], cube[1][4]/cube[2][4], colour);
line(cube[0][7]/cube[2][7], cube[1][7]/cube[2][7],
cube[0][6]/cube[2][6], cube[1][6]/cube[2][6], colour);
}
Back to comp.sys.ibm.pc.demos | Previous | Next — Next in thread | Find similar
questions about rotating cube graphics in C++ (aiming for C) David Melik <dchmelik@hipplanet.com> - 2012-06-22 00:53 -0700
figured part out; new questions David Melik <dchmelik@hipplanet.com> - 2012-06-22 03:19 -0700
Re: figured part out; new questions David Melik <dchmelik@hipplanet.com> - 2012-06-22 04:33 -0700
Re: figured part out; new questions Johann Klammer <klammerj@NOSPAM.a1.net> - 2012-06-24 00:40 +0200
Re: figured part out; new questions David Melik <dchmelik@hipplanet.com> - 2012-06-23 19:29 -0700
Re: figured part out; new questions Nobody <nobody@nowhere.com> - 2012-06-25 22:40 +0100
Re: figured part out; new questions Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2012-06-26 00:20 +0200
Re: figured part out; new questions legalize+jeeves@mail.xmission.com (Richard) - 2012-06-29 18:59 +0000
Re: figured part out; new questions David Melik <dchmelik@hipplanet.com> - 2012-06-23 19:36 -0700
Re: figured part out; new questions JohnF <john@please.see.sig.for.email.com> - 2012-07-01 13:50 +0000
Re: figured part out; new questions David Melik <dchmelik@hipplanet.com> - 2012-07-08 22:36 -0700
csiph-web