[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]
{ NOTE : Units needed are included at the end of this code }
program the_4d_experiment;
{version 1.1}
{ Kiszely Laszlo 1995
kiszely@bmeik.eik.bme.hu}
{--------------------------------------------------------------------------}
uses crt,mygraf;
const end_seq:real=237; {the end of a data-stream,
it is a 'í' sign, indicates
the end of a kind of stream}
{---------------------------------------------------------------------------}
var data:file of real; {the file of the generated object}
j:integer; {indexes}
a:real; {for temporary storage}
chrt:char; {readkey at the end}
vertex: array[1..100,1..4] of real;
{let's store the vertex-values!}
vertex_number:integer; {the number of vertexes}
edges: array[1..200,1..3] of byte;
{let's store the edges' start-
and end-points plus the color of the edge}
edge_number:integer; {yes, the number of edges}
xy,xz,xw,yz,yw,zw:integer;
sine: array[0..359] of real; {sine-table}
cosine: array[0..359] of real; {cosine-table}
FileName:string; {the name of the 4d-object file}
{---------------------------------------------------------------------------}
{Input/Output procedures}
procedure Open_And_Check; {Checks whether the requested file is
in the directory or not}
begin
{$I-}
reset(data);
{$I+}
if IOResult<>0 then
begin
writeln(FileName,' not found!');
halt;
end;
end;
function CheckFlag(flag:real): Boolean;
begin
read(data,a);
if a=flag then CheckFlag:=true else CheckFlag:=False;
end;
procedure GetVertex_And_Write; {Reads the vertexes and puts them
into an an array}
begin
for j:=1 to 4 do
read(data,vertex[vertex_number,j]);
end;
procedure GetEdge_And_Write; {Reads the edge-data-stream and
puts them into an array}
var real_edge:real;
begin
for j:=1 to 3 do
begin
read(data,real_edge);
edges[edge_number,j]:=round(real_edge);
end;
end;
{--------------------------------------------------------------------------}
procedure CmdLineFileName;
begin
if ParamCount<>1 then begin
writeln('No Parameter/Too much Parameters Found!');
writeln('Usage: 4dexp object.4d');
halt(1);
end;
FileName:=ParamStr(1);
end;
procedure MainScreenOut;
begin
writeln;writeln;writeln;
writeln(' THE 4D EXPERIMENT');
writeln;writeln;writeln;
writeln(' A little program to rotate a 4 dimensional cube');
writeln;writeln;
writeln(' programmed by Kiszely L szl¢');
writeln;writeln;writeln;
writeln(' Control Keys');
writeln(' 4 - 6 Rotation around the YW-plane');
writeln(' 8 - 2 Rotation around the XW-plane');
writeln(' 1 - 9 Rotation around the ZW-plane');
writeln(' 3 - 7 Rotation around the XY-plane');
writeln(' a - s Rotation around the XZ-plane');
writeln(' z - x Rotation around the YZ-plane');
writeln(' q Quit');
writeln;
writeln(' Hit any key!');
writeln;writeln;
asm
@again:
in AL,60h
and AL,128
jnz @again
end;
end;
procedure BuildSineTable;
var index:integer;
begin
for index:=0 to 359 do
sine[index]:=sin(index*3.14/180);
end;
procedure BuildCosineTable;
var index:integer;
begin
for index:=0 to 359 do
cosine[index]:=cos(index*3.14/180);
end;
{--------------------------------------------------------------------------}
{Graphical procedures}
procedure ShowThePixel(x1:real;y1:real);{Transform the relative coords}
var x1tmp,y1tmp:integer;
begin
x1tmp:=160+round(x1); {160 - origin-translation}
y1tmp:=100+round(y1);
point(x1tmp,y1tmp,10);
end;
procedure ShowTheLine(startpoint:integer;endpoint:integer;color:byte);
var x1tmp,y1tmp,x2tmp,y2tmp,colour:integer;
begin
x1tmp:=160+round(vertex[startpoint,1]);
y1tmp:=100+round(vertex[startpoint,2]);
x2tmp:=160+round(vertex[endpoint,1]);
y2tmp:=100+round(vertex[endpoint,2]);
colour:=round(color);
myline(x1tmp,y1tmp,x2tmp,y2tmp,colour);
end;
procedure ShowTheObject;
var o:integer;
begin
cls;
for o:=1 to vertex_number do
ShowThePixel(vertex[o,1],vertex[o,2]);
for o:=1 to edge_number do
ShowTheLine(edges[o,1],edges[o,2],edges[o,3]);
end;
{--------------------------------------------------------------------------}
{The functions of rotation}
procedure RotateAroundXW(alfa:integer); {alfa - angle of rotating}
{in degrees, of course}
var ytmp,ztmp:real;
i:integer;
begin
for i:=1 to vertex_number do
begin
ytmp:=vertex[i,2]*cosine[alfa]+vertex[i,3]*sine[alfa];
ztmp:=-vertex[i,2]*sine[alfa]+vertex[i,3]*cosine[alfa];
vertex[i,2]:=ytmp;
vertex[i,3]:=ztmp;
end;
end;
procedure RotateAroundZW(alfa:integer);
var xtmp,ytmp:real;
index:integer;
begin
for index:=1 to vertex_number do
begin
xtmp:=vertex[index,1]*cosine[alfa]+vertex[index,2]*sine[alfa];
ytmp:=-(vertex[index,1]*sine[alfa])+vertex[index,2]*cosine[alfa];
vertex[index,1]:=xtmp;
vertex[index,2]:=ytmp;
end;
end;
procedure RotateAroundYW(alfa:integer);
var xtmp,ztmp:real;
index:integer;
begin
for index:=1 to vertex_number do
begin
xtmp:=vertex[index,1]*cosine[alfa]+vertex[index,3]*sine[alfa];
ztmp:=-(vertex[index,1]*sine[alfa])+vertex[index,3]*cosine[alfa];
vertex[index,1]:=xtmp;
vertex[index,3]:=ztmp;
end;
end;
procedure RotateAroundXY(alfa:integer);
var ztmp,wtmp:real;
index:integer;
begin
for index:=1 to vertex_number do
begin
ztmp:=vertex[index,3]*cosine[alfa]+vertex[index,4]*sine[alfa];
wtmp:=-(vertex[index,3]*sine[alfa])+vertex[index,4]*cosine[alfa];
vertex[index,3]:=ztmp;
vertex[index,4]:=wtmp;
end;
end;
procedure RotateAroundXZ(alfa:integer);
var ytmp,wtmp:real;
index:integer;
begin
for index:=1 to vertex_number do
begin
ytmp:=vertex[index,2]*cosine[alfa]+vertex[index,4]*sine[alfa];
wtmp:=-(vertex[index,2]*sine[alfa])+vertex[index,4]*cosine[alfa];
vertex[index,2]:=ytmp;
vertex[index,4]:=wtmp;
end;
end;
procedure RotateAroundYZ(alfa:integer);
var ytmp,ztmp:real;
index:integer;
begin
for index:=1 to vertex_number do
begin
ytmp:=vertex[index,2]*cosine[alfa]+vertex[index,3]*sine[alfa];
ztmp:=-(vertex[index,2]*sine[alfa])+vertex[index,3]*cosine[alfa];
vertex[index,2]:=ytmp;
vertex[index,3]:=ztmp;
end;
end;
{---------------------------------------------------------------------------}
begin
CmdLineFileName;
MainScreenOut;
assign(data,FileName);
Open_And_Check;
vertex_number:=0;
edge_number:=0;
while CheckFlag(47) do
begin
vertex_number:=vertex_number+1;
GetVertex_And_Write;
end;
while CheckFlag(92) do
begin
edge_number:=edge_number+1;
GetEdge_And_Write;
end;
if a<>237 then begin
writeln('This 4d file is not a valid one!');
halt(2);
end;
close(data);
vga320;
BuildSineTable;
BuildCosineTable;
ShowTheObject;
repeat
repeat
RotateAroundYW(yw);
RotateAroundZW(zw);
RotateAroundXW(xw);
RotateAroundXY(xy);
RotateAroundXZ(xz);
RotateAroundYZ(yz);
ShowTheObject;
until keypressed;
chrt:=readkey;
case chrt of
'4': begin;inc(yw);if yw>359 then yw:=yw-360;end;
'6': begin;dec(yw);if yw<0 then yw:=yw+360;end;
'1': begin;inc(zw);if zw>359 then zw:=zw-360;end;
'9': begin;dec(zw);if zw<0 then zw:=zw+360;end;
'8': begin;inc(xw);if xw>359 then xw:=xw-360;end;
'2': begin;dec(xw);if xw<0 then xw:=xw+360;end;
'7': begin;inc(xy);if xy>359 then xy:=xy-360;end;
'3': begin;dec(xy);if xy<0 then xy:=xy+360;end;
'a': begin;inc(xz);if xz>359 then xz:=xz-360;end;
's': begin;dec(xz);if xz<0 then xz:=xz+360;end;
'z': begin;inc(yz);if yz>359 then yz:=yz-360;end;
'x': begin;dec(yz);if yz<0 then yz:=yz+360;end;
'q': break;
end;
until j=0;
vga_out;
end.
{ ----------------------- CUT HERE ---------------------}
unit mygraf;
{Author: Kiszely Laszlo 1995
kiszely@bmeik.eik.bme.hu
Credits: Thanx to Bas van Gaalen for his 3dpas package}
interface
const vidseg: word=$a000;
procedure vga320;
procedure retrace;
procedure point(x,y:word;color:byte);
procedure vga_out;
procedure cls;
procedure myline(xk,yk,xv,yv:word; color:byte);
implementation
procedure vga320; assembler;
asm
mov ax,13h;
int 10h;
end;
procedure retrace; assembler; asm
mov dx,03dah; @vert1: in al,dx; test al,8; jnz @vert1
@vert2: in al,dx; test al,8; jz @vert2; end;
procedure point(x,y:word;color:byte);
begin
{if (y<200) and (x<320) then}
mem[vidseg:y*320+x]:=color;
end;
procedure vga_out; assembler;
asm
mov ax,03h
int 10h
end;
procedure cls; assembler;
asm
mov es,[vidseg];xor di,di;xor ax,ax;mov cx,320*100;
rep stosw;
end;
procedure myline(xk,yk,xv,yv:word; color:byte);
var
sgnx,sgny:byte;
eltx,elty,x,y,pp,qq,count,nn:word;
begin
asm
mov ax,xv
mov bx,xk
sub ax,bx
js @h1
mov cl,1
mov sgnx,cl
mov eltx,ax
jmp @h3
@h1:
mov cl,0
mov sgnx,cl
mov eltx,ax
neg eltx
@h3:
mov ax,yv
mov bx,yk
sub ax,bx
js @h4
mov cl,1
mov sgny,cl
mov elty,ax
jmp @h5
@h4:
mov cl,0
mov sgny,cl
mov elty,ax
neg elty
@h5:
mov ax, eltx
mov bx, elty
cmp ax,bx
ja @j1
mov ax, elty
mov nn,ax
jmp @j2
@j1:
mov ax, eltx
mov nn,ax
@j2:
mov ax, nn
mov dx,0
mov bx,2
div bx
cmp ax,0
je @gy1
mov ax,0
mov pp,ax
mov qq,ax
inc pp
inc qq
jmp @gy2
@gy1:
mov pp,ax
mov qq,ax
@gy2:
mov ax,xk
mov x,ax
mov ax,yk
mov y,ax
mov ax,1
mov count,ax
@next :
push x
push y
mov al,color
push ax
call point
mov ax, pp
add ax, eltx
mov pp,ax
mov bx, nn
cmp ax,bx
jb @t1
mov ax, pp
sub ax, nn
mov pp,ax
mov al, sgnx
cmp al,1
je @nn1
dec x
jmp @t1
@nn1:
inc x
@t1:
mov ax, qq
add ax, elty
mov qq,ax
mov bx, nn
cmp ax,bx
jb @t2
mov ax, qq
sub ax, nn
mov qq,ax
mov al, sgny
cmp al,1
je @nn3
dec y
jmp @t2
@nn3:
inc y
@t2:
inc count
mov ax, count
cmp nn,ax
jae @next
end;
end;
end.
{ ----------------------- CUT HERE ---------------------}
{ CODE TO GENERATE THE CUBE FILE }
program generate_the_4d_cube;
{this little util generates a 4d_object}
{Author:Kiszely Laszlo 1995
kiszely@bmeik.eik.bme.hu}
const end_seq:real=237; {the end of a data-stream,
it is a 'í' sign, indicates
the end of a kind of stream}
vertex_number:integer=16; {the number of the vertexes}
the_object: array[1..16,1..5] of real=((47,40,40,40,40),(47,40,40,40,-40),
(47,40,40,-40,40),(47,40,40,-40,-40),(47,40,-40,40,40),(47,40,-40,40,-40),
(47,40,-40,-40,40),(47,40,-40,-40,-40),(47,-40,40,40,40),(47,-40,40,40,-40),
(47,-40,40,-40,40),(47,-40,40,-40,-40),(47,-40,-40,40,40),
(47,-40,-40,40,-40),(47,-40,-40,-40,40),(47,-40,-40,-40,-40));
{an array of vertexes,where:
47 - a flag, here starts 4 data members
of the vertex-stream
of course, it can be anything else,too}
edge_number:integer=32; {the number of edges in the object}
the_edges: array[1..32,1..4] of real=( (92,1,3,10),(92,3,7,10),
(92,7,5,10),(92,5,1,10),(92,9,11,10),(92,11,15,10),
(92,15,13,10),(92,13,9,10),(92,11,3,10),(92,15,7,10),
(92,13,5,10),(92,9,1,10),
(92,2,10,3),(92,10,14,3),(92,14,6,3),(92,6,2,3),
(92,12,4,3),(92,4,8,3),(92,8,16,3),(92,16,12,3),
(92,10,12,3),(92,14,16,3),(92,6,8,3),(92,2,4,3),
(92,9,10,5),(92,13,14,5),(92,5,6,5),(92,1,2,5),
(92,11,12,5),(92,3,4,5),(92,7,8,5),(92,15,16,5));
{an array of edges,where:
92 - a flag to separate the 2 data members
first value - starting point of the edge
second value - endpoint of the edge
third value - the color of the edge}
var data:file of real; {the file of the generated object}
i,j:integer; {indexes}
begin
assign(data,'cube.4d');
rewrite(data);
for i:=1 to vertex_number do
begin
for j:=1 to 5 do
begin
write(data,the_object[i,j]);
end;
end; {the vertexes' coords}
write(data,end_seq);
for i:=1 to edge_number do
begin
for j:=1 to 4 do
begin
write(data,the_edges[i,j]);
end;
end; {which v-s are on one edge}
write(data,end_seq);
{Right now, the file of the 4d_object is ready. Be careful at the reading!}
close(data);
end.
[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]