-' 4D engine. It renders 5-cell (aka. pentachoron) as a series of 3D tetrahedrons with varying brightness.\r
-' Brightness is used to represent shift in fourth dimension.\r
+' 4D engine. It renders a 5-cell (aka. pentachoron) as a series\r
+' of 3D tetrahedrons with varying brightness. Brightness is used\r
+' to indicate shift in the fourth dimension.\r
'\r
-' In essence you can look at 3D object as a series of 2D crossections along third dimension.\r
-' Here we look at 4D object as series of 3D crossections with varying brightness (to distinguish between them).\r
+' In essence, you can look at a 3D object as a series of 2D\r
+' cross-sections along the third dimension. Here we look at\r
+' a 4D object as a series of 3D cross-sections with varying\r
+' brightness (to distinguish between them).\r
'\r
-' 4 dimensions also make it possible to rotate object along 6 different axis.\r
-' Interestingly shape of the object changes in 3D space when it is rotated\r
-' along any of the axis that involves 4th dimension.\r
+' 4 dimensions also make it possible to rotate the object along\r
+' 6 different axes. Interestingly, the shape of the object changes\r
+' in 3D space when it is rotated along any of the axes that\r
+' involve the fourth dimension.\r
'\r
+' By Svjatoslav Agejenko.\r
+' Email: svjatoslav@svjatoslav.eu\r
+' Homepage: http://www.svjatoslav.eu\r
'\r
-' made by Svjatoslav Agejenko\r
-' in 2003.08\r
-' H-Page: svjatoslav.eu\r
-' E-Mail: svjatoslav@svjatoslav.eu\r
+' Changelog:\r
+' 2003.08, Initial version\r
+' 2024, Improved program readability using AI\r
+\r
\r
DECLARE SUB chlin (x1!, y1!, z1!, q1!, x2!, y2!, z2!, q2!)\r
DECLARE SUB rot (x1!, y1!, z1!, q1!, x4!, y4!, z4!, q4!)\r
DIM SHARED pm\r
DIM SHARED frm\r
\r
-PRINT " 4D Engine, 2003.08"\r
-PRINT " Svjatoslav Agejenko: n0@hot.ee"\r
PRINT ""\r
-PRINT " use keys:"\r
-PRINT " rotate:"\r
+PRINT " Use keys:"\r
+PRINT " Rotate:"\r
PRINT " qw - XZ"\r
PRINT " as - YZ"\r
PRINT " zx - XY"\r
PRINT " er - QX"\r
PRINT " df - QY"\r
PRINT " cv - QZ"\r
-PRINT " move:"\r
+PRINT " Move:"\r
PRINT " 46 - x"\r
PRINT " 82 - y"\r
PRINT " 71 - z"\r
PRINT\r
PRINT " ESC - to quit program"\r
PRINT\r
-PRINT "press any key to continue..."\r
+PRINT " Press any key to continue..."\r
a$ = INPUT$(1)\r
\r
pi = 3.1415\r
\r
+' Angles for rotation along different axes\r
an1 = pi * .5\r
an2 = an1\r
an3 = an1\r
an5 = an1\r
an6 = an1\r
\r
+' Current position in the 4D space\r
myx = 0\r
myy = 0\r
myz = 0\r
myq = .5\r
+\r
SCREEN 12\r
setpal\r
\r
-\r
1\r
CLS\r
+\r
+' Calculate sine and cosine for each rotation angle\r
s1 = SIN(an1): c1 = COS(an1)\r
s2 = SIN(an2): c2 = COS(an2)\r
s3 = SIN(an3): c3 = COS(an3)\r
s5 = SIN(an5): c5 = COS(an5)\r
s6 = SIN(an6): c6 = COS(an6)\r
\r
+' Render the 3D tetrahedrons with varying brightness\r
FOR frm = 1 TO 15 STEP 3\r
qpyra -10, -10, -10, 0, 10, -10, -10, 0, 0, -10, 10, 0, 0, 10, 0, 0, 0, 0, 0, 10\r
NEXT frm\r
\r
a$ = INPUT$(1)\r
\r
+' Handle user input for rotation and movement\r
SELECT CASE a$\r
CASE CHR$(27)\r
SYSTEM\r
CASE "v"\r
an6 = an6 - .1\r
\r
+' Handle user input for movement in the 4D space\r
CASE "4"\r
myx = myx - 3\r
CASE "6"\r
myq = myq - .3\r
\r
END SELECT\r
+\r
GOTO 1\r
\r
+' Subroutine to calculate the linear interpolation between two points\r
SUB chlin (ox1, oy1, oz1, oq1, ox2, oy2, oz2, oq2)\r
-x1 = ox1: y1 = oy1: z1 = oz1: q1 = oq1\r
-x2 = ox2: y2 = oy2: z2 = oz2: q2 = oq2\r
-\r
-IF (q1 > myq) AND (q2 < myq) THEN\r
- SWAP x1, x2\r
- SWAP y1, y2\r
- SWAP z1, z2\r
- SWAP q1, q2\r
-END IF\r
-\r
-IF (q1 < myq) AND (q2 > myq) THEN\r
- vq = q2 - q1\r
- vmq = myq - q1\r
- jt = vmq / vq\r
- pm = pm + 1\r
- rx = (x2 - x1) * jt + x1\r
- ry = (y2 - y1) * jt + y1\r
- rz = (z2 - z1) * jt + z1 + 50\r
- px(pm) = rx / rz * 700 + 320\r
- py(pm) = ry / rz * 700 + 240\r
-END IF\r
+ x1 = ox1: y1 = oy1: z1 = oz1: q1 = oq1\r
+ x2 = ox2: y2 = oy2: z2 = oz2: q2 = oq2\r
+\r
+ ' Swap points if the first point is behind the current position in the fourth dimension\r
+ IF (q1 > myq) AND (q2 < myq) THEN\r
+ SWAP x1, x2\r
+ SWAP y1, y2\r
+ SWAP z1, z2\r
+ SWAP q1, q2\r
+ END IF\r
+\r
+ ' Calculate the interpolated point if the first point is in front of the current position\r
+ ' and the second point is behind it\r
+ IF (q1 < myq) AND (q2 > myq) THEN\r
+ vq = q2 - q1\r
+ vmq = myq - q1\r
+ jt = vmq / vq\r
+ pm = pm + 1\r
+ rx = (x2 - x1) * jt + x1\r
+ ry = (y2 - y1) * jt + y1\r
+ rz = (z2 - z1) * jt + z1 + 50\r
+ px(pm) = rx / rz * 700 + 320\r
+ py(pm) = ry / rz * 700 + 240\r
+ END IF\r
END SUB\r
\r
+' Subroutine to get a point at a specific distance along the line segment\r
SUB getp (x1, y1, z1, q1, x2, y2, z2, q2, n, rx, ry, rz, rq)\r
-xv = x2 - x1\r
-yv = y2 - y1\r
-zv = z2 - z1\r
-qv = q2 - q1\r
-\r
-rx = x1 + (xv * n)\r
-ry = y1 + (yv * n)\r
-rz = z1 + (zv * n)\r
-rq = q1 + (qv * n)\r
+ ' Calculate the vector between the two points\r
+ xv = x2 - x1\r
+ yv = y2 - y1\r
+ zv = z2 - z1\r
+ qv = q2 - q1\r
+\r
+ ' Calculate the interpolated point at the specified distance along the line segment\r
+ rx = x1 + (xv * n)\r
+ ry = y1 + (yv * n)\r
+ rz = z1 + (zv * n)\r
+ rq = q1 + (qv * n)\r
END SUB\r
\r
+' Subroutine to render a 3D tetrahedron with varying brightness\r
SUB qpyra (ox1, oy1, oz1, oq1, ox2, oy2, oz2, oq2, ox3, oy3, oz3, oq3, ox4, oy4, oz4, oq4, ox5, oy5, oz5, oq5)\r
\r
-ox1 = ox1 - myx\r
-oy1 = oy1 - myy\r
-oz1 = oz1 - myz\r
-oq1 = oq1 - myq - frm\r
-\r
-ox2 = ox2 - myx\r
-oy2 = oy2 - myy\r
-oz2 = oz2 - myz\r
-oq2 = oq2 - myq - frm\r
-\r
-ox3 = ox3 - myx\r
-oy3 = oy3 - myy\r
-oz3 = oz3 - myz\r
-oq3 = oq3 - myq - frm\r
-\r
-ox4 = ox4 - myx\r
-oy4 = oy4 - myy\r
-oz4 = oz4 - myz\r
-oq4 = oq4 - myq - frm\r
-\r
-ox5 = ox5 - myx\r
-oy5 = oy5 - myy\r
-oz5 = oz5 - myz\r
-oq5 = oq5 - myq - frm\r
-\r
-rot ox1, oy1, oz1, oq1, x1, y1, z1, q1\r
-rot ox2, oy2, oz2, oq2, x2, y2, z2, q2\r
-rot ox3, oy3, oz3, oq3, x3, y3, z3, q3\r
-rot ox4, oy4, oz4, oq4, x4, y4, z4, q4\r
-rot ox5, oy5, oz5, oq5, x5, y5, z5, q5\r
-\r
-pm = 0\r
-\r
-chlin x1, y1, z1, q1, x2, y2, z2, q2\r
-chlin x1, y1, z1, q1, x3, y3, z3, q3\r
-chlin x1, y1, z1, q1, x4, y4, z4, q4\r
-chlin x1, y1, z1, q1, x5, y5, z5, q5\r
-\r
-chlin x2, y2, z2, q2, x3, y3, z3, q3\r
-chlin x2, y2, z2, q2, x4, y4, z4, q4\r
-chlin x2, y2, z2, q2, x5, y5, z5, q5\r
-\r
-chlin x3, y3, z3, q3, x4, y4, z4, q4\r
-chlin x3, y3, z3, q3, x5, y5, z5, q5\r
-\r
-chlin x4, y4, z4, q4, x5, y5, z5, q5\r
-\r
-FOR a = 1 TO pm\r
- FOR b = a + 1 TO pm\r
- LINE (px(a), py(a))-(px(b), py(b)), 15 - frm\r
- NEXT b\r
-NEXT a\r
-\r
+ ' Adjust the coordinates for the current position in the 4D space\r
+ ox1 = ox1 - myx\r
+ oy1 = oy1 - myy\r
+ oz1 = oz1 - myz\r
+ oq1 = oq1 - myq - frm\r
+\r
+ ox2 = ox2 - myx\r
+ oy2 = oy2 - myy\r
+ oz2 = oz2 - myz\r
+ oq2 = oq2 - myq - frm\r
+\r
+ ox3 = ox3 - myx\r
+ oy3 = oy3 - myy\r
+ oz3 = oz3 - myz\r
+ oq3 = oq3 - myq - frm\r
+\r
+ ox4 = ox4 - myx\r
+ oy4 = oy4 - myy\r
+ oz4 = oz4 - myz\r
+ oq4 = oq4 - myq - frm\r
+\r
+ ox5 = ox5 - myx\r
+ oy5 = oy5 - myy\r
+ oz5 = oz5 - myz\r
+ oq5 = oq5 - myq - frm\r
+\r
+ ' Rotate the points along the specified axes\r
+ rot ox1, oy1, oz1, oq1, x1, y1, z1, q1\r
+ rot ox2, oy2, oz2, oq2, x2, y2, z2, q2\r
+ rot ox3, oy3, oz3, oq3, x3, y3, z3, q3\r
+ rot ox4, oy4, oz4, oq4, x4, y4, z4, q4\r
+ rot ox5, oy5, oz5, oq5, x5, y5, z5, q5\r
+\r
+ ' Initialize the list of points to be drawn\r
+ pm = 0\r
+\r
+ ' Calculate the linear interpolation between each pair of points\r
+ chlin x1, y1, z1, q1, x2, y2, z2, q2\r
+ chlin x1, y1, z1, q1, x3, y3, z3, q3\r
+ chlin x1, y1, z1, q1, x4, y4, z4, q4\r
+ chlin x1, y1, z1, q1, x5, y5, z5, q5\r
+\r
+ chlin x2, y2, z2, q2, x3, y3, z3, q3\r
+ chlin x2, y2, z2, q2, x4, y4, z4, q4\r
+ chlin x2, y2, z2, q2, x5, y5, z5, q5\r
+\r
+ chlin x3, y3, z3, q3, x4, y4, z4, q4\r
+ chlin x3, y3, z3, q3, x5, y5, z5, q5\r
+\r
+ chlin x4, y4, z4, q4, x5, y5, z5, q5\r
+\r
+ ' Draw lines between each pair of points\r
+ FOR a = 1 TO pm\r
+ FOR b = a + 1 TO pm\r
+ LINE (px(a), py(a))-(px(b), py(b)), 15 - frm\r
+ NEXT b\r
+ NEXT a\r
\r
END SUB\r
\r
+' Subroutine to rotate a point along the specified axes\r
SUB rot (x1, y1, z1, q1, x4, y4, z4, q4)\r
\r
-' qx\r
-q2 = q1 * s4 - x1 * c4\r
-x2 = q1 * c4 + x1 * s4\r
-\r
-' qy\r
-q3 = q2 * s5 - y1 * c5\r
-y2 = q2 * c5 + y1 * s5\r
+ ' Rotate the point along the QX axis\r
+ q2 = q1 * s4 - x1 * c4\r
+ x2 = q1 * c4 + x1 * s4\r
\r
-' qz\r
-q4 = q3 * s6 - z1 * c6\r
-z2 = q3 * c6 + z1 * s6\r
+ ' Rotate the point along the QY axis\r
+ q3 = q2 * s5 - y1 * c5\r
+ y2 = q2 * c5 + y1 * s5\r
\r
-' zx\r
-x3 = x2 * s1 - z2 * c1\r
-z3 = x2 * c1 + z2 * s1\r
+ ' Rotate the point along the QZ axis\r
+ q4 = q3 * s6 - z1 * c6\r
+ z2 = q3 * c6 + z1 * s6\r
\r
-' zy\r
-y3 = y2 * s2 - z3 * c2\r
-z4 = y2 * c2 + z3 * s2\r
+ ' Rotate the point along the XZ axis\r
+ x3 = x2 * s1 - z2 * c1\r
+ z3 = x2 * c1 + z2 * s1\r
\r
-' xy\r
-y4 = y3 * s3 - x3 * c3\r
-x4 = y3 * c3 + x3 * s3\r
+ ' Rotate the point along the YZ axis\r
+ y3 = y2 * s2 - z3 * c2\r
+ z4 = y2 * c2 + z3 * s2\r
\r
+ ' Rotate the point along the XY axis\r
+ y4 = y3 * s3 - x3 * c3\r
+ x4 = y3 * c3 + x3 * s3\r
\r
END SUB\r
\r
+' Subroutine to set up the color palette\r
SUB setpal\r
\r
-FOR a = 0 TO 15\r
- OUT &H3C8, a\r
- OUT &H3C9, a * 4\r
- OUT &H3C9, a * 4\r
- OUT &H3C9, a * 4\r
- LINE (a, 0)-(a, 400), a\r
-NEXT a\r
-'a$ = INPUT$(1)\r
+ ' Set up the color palette for the 4D rendering\r
+ FOR a = 0 TO 15\r
+ OUT &H3C8, a\r
+ OUT &H3C9, a * 4\r
+ OUT &H3C9, a * 4\r
+ OUT &H3C9, a * 4\r
+ LINE (a, 0)-(a, 400), a\r
+ NEXT a\r
+\r
END SUB\r
\r
+' Function to calculate the distance between two points in 4D space\r
FUNCTION vahe (x1, y1, z1, q1, x2, y2, z2, q2)\r
-vahe = SQR((x1 - x2) ^ 2 + (y1 - y2) ^ 2 + (z1 - z2) ^ 2 + (q1 - q2) ^ 2)\r
+ vahe = SQR((x1 - x2) ^ 2 + (y1 - y2) ^ 2 + (z1 - z2) ^ 2 + (q1 - q2) ^ 2)\r
END FUNCTION\r
+\r