Better code readability
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Mon, 30 Jun 2025 15:50:44 +0000 (18:50 +0300)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Mon, 30 Jun 2025 15:50:44 +0000 (18:50 +0300)
Miscellaneous/4D engine/qeng.bas

index 31fbaa7..8e4eb92 100755 (executable)
 '\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
-DECLARE SUB setpal ()\r
-DECLARE SUB getp (x1!, y1!, z1!, q1!, x2!, y2!, z2!, q2!, n!, rx!, ry!, rz!, rq!)\r
-DECLARE SUB qpyra (x1!, y1!, z1!, q1!, x2!, y2!, z2!, q2!, x3!, y3!, z3!, q3!, x4!, y4!, z4!, q4!, x5!, y5!, z5!, q5!)\r
-DECLARE FUNCTION vahe! (x1!, y1!, z1!, q1!, x2!, y2!, z2!, q2!)\r
-DIM SHARED siz\r
-DIM SHARED an1, an2, an3, an4, an5, an6\r
-DIM SHARED myx, myy, myz, myq\r
+' 2024 - 2025, Improved program readability\r
+\r
+' Declare subroutines and functions that will be used in the program\r
+DECLARE SUB CalculateInterpolatedLine (originalX1!, originalY1!, originalZ1!, originalQ1!, originalX2!, originalY2!, originalZ2!, originalQ2!)\r
+DECLARE SUB RotatePoint (x1!, y1!, z1!, q1!, x4!, y4!, z4!, q4!)\r
+DECLARE SUB SetupPalette ()\r
+DECLARE SUB GetPointAtDistance (x1!, y1!, z1!, q1!, x2!, y2!, z2!, q2!, distanceFactor!, rx!, ry!, rz!, rq!)\r
+DECLARE SUB RenderPentachoron (ox1!, oy1!, oz1!, oq1!, ox2!, oy2!, oz2!, oq2!, ox3!, oy3!, oz3!, oq3!, ox4!, oy4!, oz4!, oq4!, ox5!, oy5!, oz5!, oq5!)\r
+DECLARE FUNCTION CalculateDistance (x1!, y1!, z1!, q1!, x2!, y2!, z2!, q2!)\r
+\r
+' Shared variables that can be accessed from any subroutine\r
+DIM SHARED screenSize\r
+DIM SHARED angleXZ, angleYZ, angleXY, angleQX, angleQY, angleQZ\r
+DIM SHARED cameraX, cameraY, cameraZ, cameraQ\r
 DIM SHARED pi\r
-DIM SHARED s1, s2, s3, s4, s5, s6\r
-DIM SHARED c1, c2, c3, c4, c5, c6\r
+DIM SHARED sineXZ, sineYZ, sineXY, sineQX, sineQY, sineQZ\r
+DIM SHARED cosineXZ, cosineYZ, cosineXY, cosineQX, cosineQY, cosineQZ\r
 \r
-DIM SHARED px(1 TO 10)\r
-DIM SHARED py(1 TO 10)\r
-DIM SHARED pm\r
-DIM SHARED frm\r
+' Arrays to store projected points and other drawing information\r
+DIM SHARED projectedX(1 TO 10)\r
+DIM SHARED projectedY(1 TO 10)\r
+DIM SHARED pointCount\r
+DIM SHARED frame\r
 \r
+' Display control instructions to the user\r
 PRINT ""\r
 PRINT " Use keys:"\r
 PRINT "       Rotate:"\r
@@ -57,247 +61,289 @@ PRINT
 PRINT "       ESC - to quit program"\r
 PRINT\r
 PRINT " Press any key to continue..."\r
-a$ = INPUT$(1)\r
+in$ = INPUT$(1)\r
 \r
+' Initialize pi value for rotation calculations\r
 pi = 3.1415\r
 \r
-' Angles for rotation along different axes\r
-an1 = pi * .5\r
-an2 = an1\r
-an3 = an1\r
-an4 = 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
+' Initialize rotation angles for each axis\r
+angleXZ = pi * .5\r
+angleYZ = angleXZ\r
+angleXY = angleXZ\r
+angleQX = angleXZ\r
+angleQY = angleXZ\r
+angleQZ = angleXZ\r
+\r
+' Set initial camera position in 4D space\r
+cameraX = 0\r
+cameraY = 0\r
+cameraZ = 0\r
+cameraQ = .5\r
+\r
+' Set graphics mode to 640x480 with 16 colors\r
 SCREEN 12\r
-setpal\r
+' Setup the color palette for rendering\r
+SetupPalette\r
 \r
-1\r
+MainLoop:\r
+' Clear screen for new frame\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
-s4 = SIN(an4): c4 = COS(an4)\r
-s5 = SIN(an5): c5 = COS(an5)\r
-s6 = SIN(an6): c6 = COS(an6)\r
+' Calculate sine and cosine values for each rotation angle\r
+sineXZ = SIN(angleXZ): cosineXZ = COS(angleXZ)\r
+sineYZ = SIN(angleYZ): cosineYZ = COS(angleYZ)\r
+sineXY = SIN(angleXY): cosineXY = COS(angleXY)\r
+sineQX = SIN(angleQX): cosineQX = COS(angleQX)\r
+sineQY = SIN(angleQY): cosineQY = COS(angleQY)\r
+sineQZ = SIN(angleQZ): cosineQZ = COS(angleQZ)\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
+' Render multiple frames of the pentachoron with varying depth\r
+FOR frame = 1 TO 15 STEP 3\r
+  ' Render a pentachoron (5-cell) with the current camera position and rotation\r
+  RenderPentachoron -10, -10, -10, 0, 10, -10, -10, 0, 0, -10, 10, 0, 0, 10, 0, 0, 0, 0, 0, 10\r
+NEXT frame\r
 \r
-a$ = INPUT$(1)\r
+' Get user input for camera control\r
+in$ = INPUT$(1)\r
 \r
 ' Handle user input for rotation and movement\r
-SELECT CASE a$\r
+SELECT CASE in$\r
 CASE CHR$(27)\r
+  ' ESC key pressed - exit program\r
   SYSTEM\r
 CASE "q"\r
-  an1 = an1 + .1\r
+  ' Increase rotation angle along XZ axis\r
+  angleXZ = angleXZ + .1\r
 CASE "w"\r
-  an1 = an1 - .1\r
+  ' Decrease rotation angle along XZ axis\r
+  angleXZ = angleXZ - .1\r
 CASE "a"\r
-  an2 = an2 + .1\r
+  ' Increase rotation angle along YZ axis\r
+  angleYZ = angleYZ + .1\r
 CASE "s"\r
-  an2 = an2 - .1\r
+  ' Decrease rotation angle along YZ axis\r
+  angleYZ = angleYZ - .1\r
 CASE "z"\r
-  an3 = an3 + .1\r
+  ' Increase rotation angle along XY axis\r
+  angleXY = angleXY + .1\r
 CASE "x"\r
-  an3 = an3 - .1\r
+  ' Decrease rotation angle along XY axis\r
+  angleXY = angleXY - .1\r
 CASE "e"\r
-  an4 = an4 + .1\r
+  ' Increase rotation angle along QX axis\r
+  angleQX = angleQX + .1\r
 CASE "r"\r
-  an4 = an4 - .1\r
+  ' Decrease rotation angle along QX axis\r
+  angleQX = angleQX - .1\r
 CASE "d"\r
-  an5 = an5 + .1\r
+  ' Increase rotation angle along QY axis\r
+  angleQY = angleQY + .1\r
 CASE "f"\r
-  an5 = an5 - .1\r
+  ' Decrease rotation angle along QY axis\r
+  angleQY = angleQY - .1\r
 CASE "c"\r
-  an6 = an6 + .1\r
+  ' Increase rotation angle along QZ axis\r
+  angleQZ = angleQZ + .1\r
 CASE "v"\r
-  an6 = an6 - .1\r
+  ' Decrease rotation angle along QZ axis\r
+  angleQZ = angleQZ - .1\r
 \r
 ' Handle user input for movement in the 4D space\r
 CASE "4"\r
-  myx = myx - 3\r
+  ' Move camera left along X axis\r
+  cameraX = cameraX - 3\r
 CASE "6"\r
-  myx = myx + 3\r
+  ' Move camera right along X axis\r
+  cameraX = cameraX + 3\r
 CASE "8"\r
-  myz = myz + 3\r
+  ' Move camera forward along Z axis\r
+  cameraZ = cameraZ + 3\r
 CASE "2"\r
-  myz = myz - 3\r
+  ' Move camera backward along Z axis\r
+  cameraZ = cameraZ - 3\r
 CASE "7"\r
-  myy = myy + 3\r
+  ' Move camera up along Y axis\r
+  cameraY = cameraY + 3\r
 CASE "1"\r
-  myy = myy - 3\r
+  ' Move camera down along Y axis\r
+  cameraY = cameraY - 3\r
 CASE "+"\r
-  myq = myq + .3\r
+  ' Move camera forward along Q axis (4th dimension)\r
+  cameraQ = cameraQ + .3\r
 CASE "-"\r
-  myq = myq - .3\r
+  ' Move camera backward along Q axis (4th dimension)\r
+  cameraQ = cameraQ - .3\r
 \r
 END SELECT\r
 \r
-GOTO 1\r
+' Loop back to render next frame\r
+GOTO MainLoop\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
+' Function to calculate the distance between two points in 4D space\r
+FUNCTION CalculateDistance (x1, y1, z1, q1, x2, y2, z2, q2)\r
+  ' Calculate Euclidean distance in 4D space\r
+  CalculateDistance = SQR((x1 - x2) ^ 2 + (y1 - y2) ^ 2 + (z1 - z2) ^ 2 + (q1 - q2) ^ 2)\r
+END FUNCTION\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
+' Subroutine to calculate the linear interpolation between two points\r
+SUB CalculateInterpolatedLine (originalX1, originalY1, originalZ1, originalQ1, originalX2, originalY2, originalZ2, originalQ2)\r
+  ' Local variables to store coordinates of the two points\r
+  x1 = originalX1: y1 = originalY1: z1 = originalZ1: q1 = originalQ1\r
+  x2 = originalX2: y2 = originalY2: z2 = originalZ2: q2 = originalQ2\r
+\r
+  ' If the first point is in front of the camera and the second is behind,\r
+  ' swap them to ensure proper rendering order\r
+  IF (q1 > cameraQ) AND (q2 < cameraQ) 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
+  ' If the first point is in front of the camera and the second is behind,\r
+  ' calculate the intersection point where the line segment crosses the camera plane\r
+  IF (q1 < cameraQ) AND (q2 > cameraQ) THEN\r
+    ' Calculate the difference in Q coordinates\r
+    qDifference = q2 - q1\r
+    ' Calculate how far along the line segment we need to go to reach the camera plane\r
+    qToCamera = cameraQ - q1\r
+    ' Calculate the interpolation factor\r
+    interpolationFactor = qToCamera / qDifference\r
+    ' Increment point counter\r
+    pointCount = pointCount + 1\r
+    ' Calculate interpolated coordinates\r
+    interpolatedX = (x2 - x1) * interpolationFactor + x1\r
+    interpolatedY = (y2 - y1) * interpolationFactor + y1\r
+    interpolatedZ = (z2 - z1) * interpolationFactor + z1 + 50\r
+    ' Project 3D coordinates to 2D screen coordinates and store them\r
+    projectedX(pointCount) = interpolatedX / interpolatedZ * 700 + 320\r
+    projectedY(pointCount) = interpolatedY / interpolatedZ * 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
+SUB GetPointAtDistance (x1, y1, z1, q1, x2, y2, z2, q2, distanceFactor, rx, ry, rz, rq)\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
+  xVector = x2 - x1\r
+  yVector = y2 - y1\r
+  zVector = z2 - z1\r
+  qVector = q2 - q1\r
+\r
+  ' Calculate the coordinates of the point at the specified distance along the line segment\r
+  rx = x1 + (xVector * distanceFactor)\r
+  ry = y1 + (yVector * distanceFactor)\r
+  rz = z1 + (zVector * distanceFactor)\r
+  rq = q1 + (qVector * distanceFactor)\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
-  ' 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
+SUB RenderPentachoron (originalX1, originalY1, originalZ1, originalQ1, originalX2, originalY2, originalZ2, originalQ2, originalX3, originalY3, originalZ3, originalQ3, originalX4, originalY4, originalZ4, originalQ4, originalX5, originalY5, originalZ5 _\r
+, originalQ5)\r
+\r
+  ' Adjust coordinates based on camera position and frame depth\r
+  originalX1 = originalX1 - cameraX\r
+  originalY1 = originalY1 - cameraY\r
+  originalZ1 = originalZ1 - cameraZ\r
+  originalQ1 = originalQ1 - cameraQ - frame\r
+\r
+  originalX2 = originalX2 - cameraX\r
+  originalY2 = originalY2 - cameraY\r
+  originalZ2 = originalZ2 - cameraZ\r
+  originalQ2 = originalQ2 - cameraQ - frame\r
+\r
+  originalX3 = originalX3 - cameraX\r
+  originalY3 = originalY3 - cameraY\r
+  originalZ3 = originalZ3 - cameraZ\r
+  originalQ3 = originalQ3 - cameraQ - frame\r
+\r
+  originalX4 = originalX4 - cameraX\r
+  originalY4 = originalY4 - cameraY\r
+  originalZ4 = originalZ4 - cameraZ\r
+  originalQ4 = originalQ4 - cameraQ - frame\r
+\r
+  originalX5 = originalX5 - cameraX\r
+  originalY5 = originalY5 - cameraY\r
+  originalZ5 = originalZ5 - cameraZ\r
+  originalQ5 = originalQ5 - cameraQ - frame\r
+\r
+  ' Rotate all points based on current rotation angles\r
+  RotatePoint originalX1, originalY1, originalZ1, originalQ1, x1, y1, z1, q1\r
+  RotatePoint originalX2, originalY2, originalZ2, originalQ2, x2, y2, z2, q2\r
+  RotatePoint originalX3, originalY3, originalZ3, originalQ3, x3, y3, z3, q3\r
+  RotatePoint originalX4, originalY4, originalZ4, originalQ4, x4, y4, z4, q4\r
+  RotatePoint originalX5, originalY5, originalZ5, originalQ5, x5, y5, z5, q5\r
+\r
+  ' Initialize point counter\r
+  pointCount = 0\r
+\r
+  ' Calculate interpolated points for all edges of the pentachoron\r
+  CalculateInterpolatedLine x1, y1, z1, q1, x2, y2, z2, q2\r
+  CalculateInterpolatedLine x1, y1, z1, q1, x3, y3, z3, q3\r
+  CalculateInterpolatedLine x1, y1, z1, q1, x4, y4, z4, q4\r
+  CalculateInterpolatedLine x1, y1, z1, q1, x5, y5, z5, q5\r
+\r
+  CalculateInterpolatedLine x2, y2, z2, q2, x3, y3, z3, q3\r
+  CalculateInterpolatedLine x2, y2, z2, q2, x4, y4, z4, q4\r
+  CalculateInterpolatedLine x2, y2, z2, q2, x5, y5, z5, q5\r
+\r
+  CalculateInterpolatedLine x3, y3, z3, q3, x4, y4, z4, q4\r
+  CalculateInterpolatedLine x3, y3, z3, q3, x5, y5, z5, q5\r
+\r
+  CalculateInterpolatedLine x4, y4, z4, q4, x5, y5, z5, q5\r
+\r
+  ' Draw lines between each pair of interpolated points\r
+  FOR pointA = 1 TO pointCount\r
+    FOR pointB = pointA + 1 TO pointCount\r
+      ' Draw line with color based on frame depth (for varying brightness)\r
+      LINE (projectedX(pointA), projectedY(pointA))-(projectedX(pointB), projectedY(pointB)), 15 - frame\r
+    NEXT pointB\r
+  NEXT pointA\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
+SUB RotatePoint (x1, y1, z1, q1, x4, y4, z4, q4)\r
 \r
   ' Rotate the point along the QX axis\r
-  q2 = q1 * s4 - x1 * c4\r
-  x2 = q1 * c4 + x1 * s4\r
+  q2 = q1 * sineQX - x1 * cosineQX\r
+  x2 = q1 * cosineQX + x1 * sineQX\r
 \r
   ' Rotate the point along the QY axis\r
-  q3 = q2 * s5 - y1 * c5\r
-  y2 = q2 * c5 + y1 * s5\r
+  q3 = q2 * sineQY - y1 * cosineQY\r
+  y2 = q2 * cosineQY + y1 * sineQY\r
 \r
   ' Rotate the point along the QZ axis\r
-  q4 = q3 * s6 - z1 * c6\r
-  z2 = q3 * c6 + z1 * s6\r
+  q4 = q3 * sineQZ - z1 * cosineQZ\r
+  z2 = q3 * cosineQZ + z1 * sineQZ\r
 \r
   ' Rotate the point along the XZ axis\r
-  x3 = x2 * s1 - z2 * c1\r
-  z3 = x2 * c1 + z2 * s1\r
+  x3 = x2 * sineXZ - z2 * cosineXZ\r
+  z3 = x2 * cosineXZ + z2 * sineXZ\r
 \r
   ' Rotate the point along the YZ axis\r
-  y3 = y2 * s2 - z3 * c2\r
-  z4 = y2 * c2 + z3 * s2\r
+  y3 = y2 * sineYZ - z3 * cosineYZ\r
+  z4 = y2 * cosineYZ + z3 * sineYZ\r
 \r
   ' Rotate the point along the XY axis\r
-  y4 = y3 * s3 - x3 * c3\r
-  x4 = y3 * c3 + x3 * s3\r
+  y4 = y3 * sineXY - x3 * cosineXY\r
+  x4 = y3 * cosineXY + x3 * sineXY\r
 \r
 END SUB\r
 \r
 ' Subroutine to set up the color palette\r
-SUB setpal\r
-\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
+SUB SetupPalette\r
+\r
+  ' Set up a grayscale color palette\r
+  FOR colorIndex = 0 TO 15\r
+    ' Set palette register\r
+    OUT &H3C8, colorIndex\r
+    ' Set RGB values (all equal for grayscale)\r
+    OUT &H3C9, colorIndex * 4\r
+    OUT &H3C9, colorIndex * 4\r
+    OUT &H3C9, colorIndex * 4\r
+    ' Draw a vertical line with this color to visualize the palette\r
+    LINE (colorIndex, 0)-(colorIndex, 400), colorIndex\r
+  NEXT colorIndex\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
-END FUNCTION\r
-\r