Let A=(aij) be a 4 by 4 matrix.
A transformation that moves a point ( x, y, z ) to
the point (x'/c, y'/c, z'/c) where
( x' y' z' c ) = ( x y z 1 ) |
|
is called a projective transformation determined by A.
The concept of Projective transformations contains congruent transformations, similar transformations and affine transformations.
For example, the rotation about the x-axis by θ is a projective transformation determined by a matrix
( |
|
) |
the rotation about the x-axis by θ is a projective transformation determined by a matrix
( |
|
) |
Furthermore, the translation determined by a vector(a, b, c) is a projective transformation determined by a matrix
( |
|
) |
Note.
Transformations are represented in row vectors in Full BASIC. Thus the matrix that represents the composite transformation of a transformation represented by a matrix A and a transformation represented by a matrix B is A*B.
A DRAW statement can transform the picture by including a 4 by 4 matrix in the WITH-clause.
Let A be a 4 by 4 matrix declared as DIM A(4,4).
DRAW a_pict with A transforms a picture a_pict using a matrix, provided that z-coordinates are ignored when the image is drawn on the screen.
Any product of an arbitrary number of 4-by-4 matrices or supplied transform functions can be written in a WITH-clause of a DRAW statement. Multiplication is represented by a symbol *.
Supplied transform functions are defined as follows, for example,
ROTATE(α) = |
|
SHIFT(a,b) = |
|
For example, preparing a matrix that represents the transformation in which y-coordinates are converted to x-coordinates, z-coordinates are converted to x-coordinates and x-coordinates are converted to z-coordinates
A = |
|
and a matrix that represents the transformation in which x-coordinates are converted to y-coordinates, y-coordinates are converted to z-coordinates and z-coordinates are converted to x-coordinates
B = |
|
enables writing a matrix that represents the rotation about the x-axis by θ as A*ROTATE(θ)*B.
Example
The external picture "tetra" described in 1000 line or later on the following program draws all edges of a regular tetrahedron that has a base that lies in the xy-plane and its barycenter is located at the origin and has a vertex at the point (1,0,0), while the details are explained later.
The following program draws a "tetra" rotating about the x-axis by 120°.
100 DECLARE EXTERNAL PICTURE tetra 110 OPTION ANGLE DEGREES 120 DIM a(4,4), b(4,4) 130 MAT READ a 140 DATA 0,0,1,0 150 DATA 1,0,0,0 160 DATA 0,1,0,0 170 DATA 0,0,0,1 180 MAT READ b 190 DATA 0,1,0,0 200 DATA 0,0,1,0 210 DATA 1,0,0,0 220 DATA 0,0,0,1 230 SET WINDOW -2,2,-2,2 240 DRAW tetra WITH a*ROTATE(120)*b 250 END 260 ! 1000 EXTERNAL PICTURE tetra 1010 OPTION ANGLE DEGREES 1020 PICTURE face 1030 PLOT LINES: 1,0; COS(120),SIN(120); COS(240),SIN(240); 1,0 1040 END PICTURE 1050 DIM ry(4,4) 1060 MAT ry=IDN ! IDN represents an identity matrix 1070 LET ry(1,1)=1/3 1080 LET ry(1,3)=-SQR(8)/3 1090 LET ry(3,1)=SQR(8)/3 1100 LET ry(3,3)=1/3 1110 DRAW face 1120 DRAW face WITH SHIFT(1/2,0)*ry*SHIFT(-1/2,0) 1130 DRAW face WITH SHIFT(1/2,0)*ry*SHIFT(-1/2,0)*ROTATE(120) 1140 DRAW face WITH SHIFT(1/2,0)*ry*SHIFT(-1/2,0)*ROTATE(240) 1150 END PICTURE
Note. DECLARE EXTERNAL PICTURE statement in 100 line may be able to be omitted in the past and current versions of Decimal BASIC. But the Full BASIC standard requires this declaration.
Full BASIC has drawing commands that act only on the xy-plane, but transforming a picture which contains drawing commands enables drawing points, lines, or areas in space.
For example, drawing commands are located in the picture "face", lines from 1020 to 1040. Transforming "face" enables drawing faces in space.
The picture definition "face", lines from 1020 to 1040 in the above program, draws on the xy-plane a regular triangle that has a barycenter at the origin and has a vertex at the point (1, 0, 0), which is the base.
Denoting the face angle of a regular tetrahedron as α, we have cosα = 1/3, sinα = SQR(8)/3, so, we prepare a matrix "ry" which represents the rotation about the y-axis by α.
ry = |
|
As no computational expressions can be written in DATA statements, we make such matrix by assigning an identity matrix and replace the elements that differ from the identity as shown in lines from 1060 to 1100.
A face of a regular tetrahedron can be obtained by rotating the base about the line x=-1/2 by α.
This transformation can be made by translating as the line x=-1/2 moves to the y-axis and rotating about the y-axis and translating as the y-axis moves the line x=-1/2 as shown in line 1120.
The other faces can obtained by rotating this face about the z-axis by 120°or 240°(as shown in lines 1130, 1140).
When we draw a face, we must distinguish the face is visible or not.
In case of drawing convex a polyhedron as a regular polyhedron, we can use a method that we define the direction of a face and draw a face if its direction is forward.
We adopt right-handed coordinate system, so the positive direction of the z-axis is front of the screen.
Hence we draw a face the z-coordinate of whose direction is positive.
Full BASIC provides us with a matrix function TRANSFORM that represents the transformation matrix applied for drawing commands in the picture definition currently executed.
Using it, we can obtain the converted normal vector of a face that directs the positive direction of it.
Furthermore, we can draw a face varying the brightness according to the angle between the normal vector and the light source.
Now we draw a tetrahedron a edge of a base of which is parallel to the x-axis and a vertex of which lies on the z-axis.
We prepare a picture definition that draw a equilateral triangle a side of which lies on the x-axis and a vertex of which lies on the y-axis and the side length of which is 2, and make the other sides by transforming.
1210 EXTERNAL PICTURE face 1260 PLOT AREA: -1,0; 1,0; 0, SQR(3) 1280 END PICTURE
Because the cosine of the angle between the lateral side and the base is 1/3, we find the angle α such that cosα = 1/3, and rotate "face" about the x-axis by α to obtain a prototype of lateral sides.
We want to make the top vertex lie on the z-axis, so we translate it by SQR(3)/3 to the negative direction of the y-axis.
And we draw it rotated about the z-axis by 120°and 240°, then we have three lateral side.
As the right side of the base must be downward, we turn over the face and translate it by SQR(3)/3 to the negative direction of the y-axis. Turning over can be obtained by rotating about the y-axis by 180°.
1000 EXTERNAL PICTURE tetra 1010 DECLARE EXTERNAL PICTURE face 1020 OPTION ANGLE DEGREES 1030 DIM rx(4,4),ry(4,4) 1040 MAT rx=IDN ! rx = rotation about the x-axis by ACOS(1/3) 1050 LET a=ACOS(1/3) ! face angle 1060 LET rx(2,2)=COS(a) 1070 LET rx(2,3)=SIN(a) 1080 LET rx(3,2)=-SIN(a) 1090 LET rx(3,3)=COS(a) 1100 MAT ry=IDN ! ry = rotation about the y-axis by 180° 1110 LET ry(1,1)=-1 1120 LET ry(3,3)=-1 1130 DRAW face WITH rx * SHIFT(0,-SQR(3)/3) ! a lateral side 1140 DRAW face WITH rx * SHIFT(0,-SQR(3)/3) * ROTATE(120) 1150 DRAW face WITH rx * SHIFT(0,-SQR(3)/3) * ROTATE(240) 1160 DRAW face WITH ry * SHIFT(0,-SQR(3)/3) ! the base 1170 END PICTURE
In case of congruent or similar transformation, the right side of a face can be decided by the transformed vector of the normal vector (0, 0, 1).
The vector to which the vector (0, 0, 1) converts can be calculated by subtracting two vectors to which the origin (0, 0, 0) and the point (0, 0, 1) moves.
If we call the subprogram "makeNormal" shown below during execution of the external picture "face",
we obtain the normal vector.
As Full BASIC cannot define a matrix valued function, we denotes the routine as a subprogram.
1310 EXTERNAL SUB makeNormal(N()) 1320 DIM m(4,4),A(4),B(4) 1330 MAT m=TRANSFORM 1340 MAT READ A 1350 DATA 0,0,1,1 ! the point (0,0,1) 1360 MAT A=A*M 1370 MAT A=(1/A(4))*A ! the point to which the point (0,0,1) moves 1380 MAT READ B 1390 DATA 0,0,0,1 ! the origin 1400 MAT B=B*M 1410 MAT B=(1/B(4))*B ! the point to which the origin moves 1420 MAT A=A-B ! transformed result of the vector(0,0,1) 1430 LET N(1)=A(1) 1440 LET N(2)=A(2) 1450 LET N(3)=A(3) 1460 END SUB
1490 EXTERNAL SUB setBrightness(N()) 1500 DIM A(3) 1510 MAT READ A 1520 DATA -1,1,1 ! direction of light source 1530 LET s=DOT(A,N)/(SQR(DOT(A,A))*SQR(DOT(N,N))) 1540 LET s=(0.8*s+1)/2 1550 SET COLOR MIX(8) s,s,s 1560 SET AREA COLOR 8 1570 END SUB
The above two subprogram must be invoked within a picture definition, because the current transform can be obtained only during the execution of a picture definition. Therefore, we modify the picture definition "face" as follows.
1200 EXTERNAL PICTURE face 1210 DECLARE EXTERNAL SUB makeNormal, setBrightness 1220 DIM N(3) 1230 CALL makeNormal(N) 1240 IF N(3)>0 THEN ! if outside is near side 1250 CALL setBrightness(N) 1260 PLOT AREA: -1,0; 1,0; 0, SQR(3) 1270 END IF 1280 END PICTURE
Note.
The normal vector can also be calculated in the picture "face". For example,
the normal vector of the face drawn by the execution of
1150 DRAW face WITH rx * SHIFT(0,-SQR(3)/3)
can be obtained by
DIM m(4,4),n(3) MAT m=TRANSFORM MAT m=rx * SHIFT(0,-SQR(3)/3) * m
If we want to draw a solid as we see, we must draw near objects bigger and remote objects smaller.
Projective transformation realize this.
When we view a point (x, y, z) from the point (0, 0, t) on the z-axis,
the point (x, y, z) is observed as if it lies at the point ( x/(1-z/t), y/(1-z/t), 0) on the xy-plane.
If we ignore the z-coordinates of results, this transformation can be obtained by a matrix
( |
|
) |
In case of projective transformation, the normal vector of a face may not be mapped to the normal vector of the transformed face. hence we calculate the normal vector by calculating the outer vector of the transformed vectors of two vectors in the plane.
100 ! Regular Tetrahedron 110 DECLARE EXTERNAL PICTURE tetra 120 OPTION ANGLE DEGREES 130 LET z0=10 ! The Viewpoint 140 DIM p(4,4) ! Projection about the point (0,0,z0) 150 MAT p=IDN 160 LET p(3,4)=-1/z0 170 LET theta0=70 180 REM draw a tetra as if it is viewed from the point (0, 0, 10), 190 REM rotating about the z-axis by theta0 °, 200 REM and rotating about the x-axis by t° 210 SET WINDOW -2, 2, -2, 2 220 FOR t=0 TO -100 STEP -0.1 230 DIM rotx(4,4) ! rotation about the x-axis 240 MAT rotx=IDN 250 LET rotx(2,2)=COS(t) 260 LET rotx(2,3)=SIN(t) 270 LET rotx(3,2)=-SIN(t) 280 LET rotx(3,3)=COS(t) 290 SET DRAW mode hidden 300 CLEAR 310 DRAW tetra WITH ROTATE(theta0) * rotx * p 320 SET DRAW mode explicit 330 WAIT DELAY 0.01 340 NEXT t 350 END 360 ! 980 ! draw a regular tetrahedron 990 ! the base on the xy-plane, the barycenter of the base the origin 1000 EXTERNAL PICTURE tetra 1010 DECLARE EXTERNAL PICTURE face 1020 OPTION ANGLE DEGREES 1030 DIM rx(4,4),ry(4,4) 1040 MAT rx=IDN ! rotation about the x-axis by ACOS(1/3) 1050 LET a=ACOS(1/3) ! face angle 1060 LET rx(2,2)=COS(a) 1070 LET rx(2,3)=SIN(a) 1080 LET rx(3,2)=-SIN(a) 1090 LET rx(3,3)=COS(a) 1100 MAT ry=IDN ! rotation about the y-axis by 180° 1110 LET ry(1,1)=-1 1120 LET ry(3,3)=-1 1130 DRAW face WITH rx * SHIFT(0,-SQR(3)/3) ! lateral side 1140 DRAW face WITH rx * SHIFT(0,-SQR(3)/3) * ROTATE(120) 1150 DRAW face WITH rx * SHIFT(0,-SQR(3)/3) * ROTATE(240) 1160 DRAW face WITH ry * SHIFT(0,-SQR(3)/3) ! the base 1170 END PICTURE 1180 ! 1190 ! draw a face 1200 EXTERNAL PICTURE face 1210 DECLARE EXTERNAL SUB makeNormal, setBrightness 1220 DIM N(3) 1230 CALL makeNormal(N) 1240 IF N(3)>0 THEN ! if outside is near side 1250 CALL setBrightness(N) 1260 PLOT AREA: -1,0; 1,0; 0, SQR(3) 1270 END IF 1280 END PICTURE 1290 ! 1300 ! find the normal vector in the transformed coordinates 1310 EXTERNAL SUB makeNormal(N()) 1320 DIM m(4,4),A(4),B(4),C(4) 1330 MAT m=TRANSFORM 1340 MAT READ A 1350 DATA 0,0,0,1 1360 MAT READ B 1370 DATA 1,0,0,1 1380 MAT READ C 1390 DATA 1,1,0,1 1400 MAT A=A*M 1410 MAT B=B*M 1420 MAT C=C*M 1430 MAT A=(1/A(4))*A 1440 MAT B=(1/B(4))*B 1450 MAT C=(1/C(4))*C 1460 MAT REDIM A(3) 1470 MAT REDIM B(3) 1480 MAT REDIM C(3) 1490 MAT A=B-A 1500 MAT B=C-B 1510 MAT N=CROSS(A,B) 1520 END SUB 1530 ! 1540 ! determine the brightness of the face from the direction of the normal 1550 EXTERNAL SUB setBrightness(N()) 1560 DIM A(3) 1570 MAT READ A ! direction of light source 1580 DATA -1,1,1 1590 LET s=DOT(A,N)/(SQR(DOT(A,A))*SQR(DOT(N,N))) 1600 LET s=(0.8*s+1)/2 1610 SET COLOR MIX(8) s,s,s 1620 SET AREA COLOR 8 1630 END SUB
Note.
An array valued function CROSS(A, B) is an original enhanced of Decimal BASIC, and calculates the outer product of two vectors A and B. This can be replaced by a subprogram that calculates the outer product, if you want to conform the program to the Full BASIC standard.
Also SET DRAW MODE statements in lines 290 and 320 are original enhancements. These two lines can be removed if you want to have a conformed program.
If you re-write the main program as follows, the solid shall rotate about the x-axis when you drag the mouse vertically on the screen, and rotate about the y-axis when you drag the mouse horizontally on the screen.
However MOUSE POLL statement in 480 line is not compatible with the Full BASIC standard.
100 ! Regular Tetrahedron 110 DECLARE EXTERNAL PICTURE tetra 120 OPTION ANGLE DEGREES 130 LET z0=20 ! The Viewpoint 140 DIM p(4,4) ! Projection about the point (0,0,z0) 150 MAT p=IDN 160 LET p(3,4)=-1/z0 170 LET theta0=45 ! angle of rotation about the z-axis 180 LET t=-60 ! initial angle of rotation about the x-axis 190 LET s=0 ! initial angle of rotation about the y-axis 260 DIM m(4,4) 270 MAT m=ROTATE(theta0) 280 SET WINDOW -2, 2, -2, 2 290 DO 300 DIM rotx(4,4) ! rotation about the x-axis 310 MAT rotx=IDN 320 LET rotx(2,2)=COS(t) 330 LET rotx(2,3)=SIN(t) 340 LET rotx(3,2)=-SIN(t) 350 LET rotx(3,3)=COS(t) 360 DIM roty(4,4) ! rotation about the y-axis 370 MAT roty=IDN 380 LET roty(1,1)=COS(s) 390 LET roty(1,3)=-SIN(s) 400 LET roty(3,1)=SIN(s) 410 LET roty(3,3)=COS(s) 420 MAT m=m * rotx * roty 430 SET DRAW mode hidden 440 CLEAR 450 DRAW tetra WITH m * p 460 PLOT TEXT, AT -2,-2: "Drag to rotate. Right click to quit." 470 SET DRAW mode explicit 480 MOUSE POLL x,y,l,r 490 IF r<>0 THEN EXIT DO 500 LET t=0 510 LET s=0 520 IF l<>0 THEN 530 LET t=-20*(y-y0) 540 LET s= 20*(x-x0) 550 END IF 560 LET x0=x 570 LET y0=y 580 LOOP 590 END
Another 3D drawing technique can be found in a sample program 3DPLOT.BAS in the SAMPLE folder.