+++ /dev/null
-' Program renders rotating 3D animation from cubes.
-' Cubes appear and disappear according to Conway's Game of Life rules.
-'
-' By Svjatoslav Agejenko.
-' Email: svjatoslav@svjatoslav.eu
-' Homepage: http://www.svjatoslav.eu
-'
-' Changelog:
-' ?, Initial version
-' 2024, Improved program readability using AI
-
-DECLARE SUB PlaceCube (x!, y!, z!)
-DECLARE SUB DrawCube (x!, y!, z!)
-
-DECLARE SUB CreateCollisionData ()
-DECLARE SUB UpdateCollisionData ()
-DECLARE SUB RenderScene ()
-DECLARE SUB InitializeEnvironment ()
-DECLARE SUB StartGame ()
-
-DIM SHARED numPoints, numLines, pointCount, lineCount
-DIM SHARED pointsX(1 TO 3000), pointsY(1 TO 3000), pointsZ(1 TO 3000)
-DIM SHARED renderedPointsX(1 TO 7000), renderedPointsY(1 TO 7000)
-DIM SHARED originalRenderedPointsX(0 TO 9000), originalRenderedPointsY(0 TO 9000)
-DIM SHARED oldPointCount, oldLineCount
-DIM SHARED lineVertices1(1 TO 3800), lineVertices2(1 TO 3800), lineColors(1 TO 3800)
-DIM SHARED originalLineVertices1(1 TO 3800), originalLineVertices2(1 TO 3800)
-DIM SHARED myPositionX, myPositionY, myPositionZ
-DIM SHARED myPreviousPositionX, myPreviousPositionY, myPreviousPositionZ
-DIM SHARED angle1, angle2
-DIM SHARED angle1Str, angle2Str
-DIM SHARED frameCount
-
-DIM SHARED gameOfLifeGrid(1 TO 50, 1 TO 50)
-DIM SHARED nextGameOfLifeGrid(1 TO 50, 1 TO 50)
-
-StartGame
-
-angle1 = 1.5
-10
-frameCount = frameCount + 1
-
-CreateCollisionData
-RenderScene
-
-myPositionX = SIN(frameCount / 20) * 12
-myPositionY = SIN(frameCount / 50) * 10 + 15
-myPositionZ = COS(frameCount / 20) * 12
-
-angle1 = angle1 - .05
-angle2 = 2.2 + SIN(frameCount / 50) / 2
-
-inputKey$ = INKEY$
-IF inputKey$ <> "" THEN SYSTEM
-GOTO 10
-
-SUB CreateCollisionData
-pointCount = numPoints
-lineCount = numLines
-
-FOR y = 1 TO 50
- FOR x = 1 TO 50
- IF gameOfLifeGrid(x, y) = 1 THEN
- v = ABS(x - 26) + ABS(y - 26) + frameCount
- PlaceCube x - 25, SIN(v / 5) * 5, y - 25
- END IF
- NEXT x
-NEXT y
-
-IF frameCount \ 10 = frameCount / 10 THEN
-
-FOR y = 2 TO 49
-FOR x = 2 TO 49
-c = gameOfLifeGrid(x - 1, y - 1)
-c = c + gameOfLifeGrid(x, y - 1)
-c = c + gameOfLifeGrid(x + 1, y - 1)
-c = c + gameOfLifeGrid(x - 1, y)
-c = c + gameOfLifeGrid(x + 1, y)
-c = c + gameOfLifeGrid(x - 1, y + 1)
-c = c + gameOfLifeGrid(x, y + 1)
-c = c + gameOfLifeGrid(x + 1, y + 1)
-
-IF gameOfLifeGrid(x, y) = 1 THEN
- IF (c > 3) OR (c < 2) THEN nextGameOfLifeGrid(x, y) = 0 ELSE nextGameOfLifeGrid(x, y) = 1
-ELSE
- IF c = 3 THEN nextGameOfLifeGrid(x, y) = 1 ELSE nextGameOfLifeGrid(x, y) = 0
-END IF
-NEXT x
-NEXT y
-
-FOR y = 1 TO 50
-FOR x = 1 TO 50
- gameOfLifeGrid(x, y) = nextGameOfLifeGrid(x, y)
-NEXT x
-NEXT y
-END IF
-
-END SUB
-
-SUB InitializeEnvironment
-FOR z = -5 TO 5
-FOR x = -5 TO 5
-pointCount = pointCount + 1
-pointsX(pointCount) = x
-pointsY(pointCount) = 0
-pointsZ(pointCount) = z
-IF x > -5 THEN
-lineCount = lineCount + 1
-lineVertices1(lineCount) = pointCount
-lineVertices2(lineCount) = pointCount - 1
-lineColors(lineCount) = 1
-END IF
-IF z > -5 THEN
-lineCount = lineCount + 1
-lineVertices1(lineCount) = pointCount
-lineVertices2(lineCount) = pointCount - 10
-lineColors(lineCount) = 1
-END IF
-NEXT x
-NEXT z
-
-numPoints = pointCount
-numLines = lineCount
-
-END SUB
-
-SUB InitializeEnvironment1
-pointCount = 1
-pointsX(pointCount) = -2
-pointsY(pointCount) = 0
-pointsZ(pointCount) = 0
-pointCount = pointCount + 1
-pointsX(pointCount) = 2
-pointsY(pointCount) = 0
-pointsZ(pointCount) = 0
-
-lineCount = 1
-lineVertices1(lineCount) = 1
-lineVertices2(lineCount) = 2
-lineColors(lineCount) = 14
-
-END SUB
-
-SUB PlaceCube (x, y, z)
-
-v = 3
-
-lineCount = lineCount + 1
-lineVertices1(lineCount) = pointCount + 1
-lineVertices2(lineCount) = pointCount + 2
-lineColors(lineCount) = v
-
-lineCount = lineCount + 1
-lineVertices1(lineCount) = pointCount + 2
-lineVertices2(lineCount) = pointCount + 3
-lineColors(lineCount) = v
-
-lineCount = lineCount + 1
-lineVertices1(lineCount) = pointCount + 3
-lineVertices2(lineCount) = pointCount + 4
-lineColors(lineCount) = v
-
-lineCount = lineCount + 1
-lineVertices1(lineCount) = pointCount + 4
-lineVertices2(lineCount) = pointCount + 1
-lineColors(lineCount) = v
-
-lineCount = lineCount + 1
-lineVertices1(lineCount) = pointCount + 5
-lineVertices2(lineCount) = pointCount + 6
-lineColors(lineCount) = v
-
-lineCount = lineCount + 1
-lineVertices1(lineCount) = pointCount + 6
-lineVertices2(lineCount) = pointCount + 7
-lineColors(lineCount) = v
-
-lineCount = lineCount + 1
-lineVertices1(lineCount) = pointCount + 7
-lineVertices2(lineCount) = pointCount + 8
-lineColors(lineCount) = v
-
-lineCount = lineCount + 1
-lineVertices1(lineCount) = pointCount + 8
-lineVertices2(lineCount) = pointCount + 5
-lineColors(lineCount) = v
-
-lineCount = lineCount + 1
-lineVertices1(lineCount) = pointCount + 1
-lineVertices2(lineCount) = pointCount + 5
-lineColors(lineCount) = v
-
-lineCount = lineCount + 1
-lineVertices1(lineCount) = pointCount + 2
-lineVertices2(lineCount) = pointCount + 6
-lineColors(lineCount) = v
-
-lineCount = lineCount + 1
-lineVertices1(lineCount) = pointCount + 3
-lineVertices2(lineCount) = pointCount + 7
-lineColors(lineCount) = v
-
-lineCount = lineCount + 1
-lineVertices1(lineCount) = pointCount + 4
-lineVertices2(lineCount) = pointCount + 8
-lineColors(lineCount) = v
-
-pointCount = pointCount + 1
-pointsX(pointCount) = x - .5
-pointsY(pointCount) = y
-pointsZ(pointCount) = z - .5
-
-pointCount = pointCount + 1
-pointsX(pointCount) = x + .5
-pointsY(pointCount) = y
-pointsZ(pointCount) = z - .5
-
-pointCount = pointCount + 1
-pointsX(pointCount) = x + .5
-pointsY(pointCount) = y
-pointsZ(pointCount) = z + .5
-
-pointCount = pointCount + 1
-pointsX(pointCount) = x - .5
-pointsY(pointCount) = y
-pointsZ(pointCount) = z + .5
-
-pointCount = pointCount + 1
-pointsX(pointCount) = x - .5
-pointsY(pointCount) = y + 1
-pointsZ(pointCount) = z - .5
-
-pointCount = pointCount + 1
-pointsX(pointCount) = x + .5
-pointsY(pointCount) = y + 1
-pointsZ(pointCount) = z - .5
-
-pointCount = pointCount + 1
-pointsX(pointCount) = x + .5
-pointsY(pointCount) = y + 1
-pointsZ(pointCount) = z + .5
-
-pointCount = pointCount + 1
-pointsX(pointCount) = x - .5
-pointsY(pointCount) = y + 1
-pointsZ(pointCount) = z + .5
-
-END SUB
-
-SUB RenderScene
-
-sineAngle1 = SIN(angle1)
-cosineAngle1 = COS(angle1)
-sineAngle2 = SIN(angle2)
-cosineAngle2 = COS(angle2)
-
-FOR a = 1 TO pointCount
-x = pointsX(a) + myPositionX
-y = pointsY(a) - myPositionY
-z = pointsZ(a) + myPositionZ
-
-x1 = x * sineAngle1 - z * cosineAngle1
-z1 = x * cosineAngle1 + z * sineAngle1
-y1 = y * sineAngle2 - z1 * cosineAngle2
-z2 = y * cosineAngle2 + z1 * sineAngle2
-
-IF z2 < .5 THEN
-renderedPointsX(a) = -1
-ELSE
-renderedPointsX(a) = 320 + (x1 / z2 * 400)
-renderedPointsY(a) = 240 - (y1 / z2 * 400)
-END IF
-NEXT a
-
-FOR a = 1 TO lineCount
-l1 = originalLineVertices1(a)
-l2 = originalLineVertices2(a)
-
-IF originalRenderedPointsX(l1) = -1 OR originalRenderedPointsX(l2) = -1 THEN
-ELSE
-LINE (originalRenderedPointsX(l1), originalRenderedPointsY(l1))-(originalRenderedPointsX(l2), originalRenderedPointsY(l2)), 0
-END IF
-
-l1 = lineVertices1(a)
-l2 = lineVertices2(a)
-IF renderedPointsX(l1) = -1 OR renderedPointsX(l2) = -1 THEN
-ELSE
-LINE (renderedPointsX(l1), renderedPointsY(l1))-(renderedPointsX(l2), renderedPointsY(l2)), lineColors(a)
-END IF
-NEXT a
-
-IF lineCount < oldLineCount THEN
-FOR a = lineCount + 1 TO oldLineCount
-l1 = originalLineVertices1(a)
-l2 = originalLineVertices2(a)
-IF originalRenderedPointsX(l1) = -1 OR originalRenderedPointsX(l2) = -1 THEN
-ELSE
-LINE (originalRenderedPointsX(l1), originalRenderedPointsY(l1))-(originalRenderedPointsX(l2), originalRenderedPointsY(l2)), 0
-END IF
-NEXT a
-END IF
-
-FOR a = 1 TO pointCount
-originalRenderedPointsX(a) = renderedPointsX(a)
-originalRenderedPointsY(a) = renderedPointsY(a)
-NEXT a
-
-oldPointCount = pointCount
-
-FOR a = 1 TO lineCount
-originalLineVertices1(a) = lineVertices1(a)
-originalLineVertices2(a) = lineVertices2(a)
-NEXT a
-
-oldLineCount = lineCount
-
-END SUB
-
-SUB StartGame
-SCREEN 12
-numPoints = 0
-numLines = 0
-pointCount = numPoints
-lineCount = numLines
-gridSize = 50
-
-myPositionX = 4
-myPositionY = 15
-myPositionZ = 17
-angle1 = ATN(1) / 2 - .29
-angle2 = angle1 + 1
-
-FOR a = 1 TO 1000
-lineColors(a) = 4
-NEXT a
-
-FOR a = 1 TO 1000
-originalLineVertices1(a) = 1
-originalLineVertices2(a) = 1
-NEXT a
-
-OPEN "3dlife.dat" FOR INPUT AS #1
-y = 20
-20
-IF EOF(1) <> 0 THEN GOTO 30
-x = 20
-
-LINE INPUT #1, inputLine$
-FOR b = 1 TO LEN(inputLine$)
- c$ = RIGHT$(LEFT$(inputLine$, b), 1)
- IF c$ = "#" THEN gameOfLifeGrid(x, y) = 1
- x = x + 1
-NEXT b
-
-y = y + 1
-GOTO 20
-30
-CLOSE #1
-
-END SUB
+++ /dev/null
-.....#.#.....\r
-...##...##...\r
-..#.......#..\r
-.#..##.##..#.\r
-.#.#.....#.#.\r
-#..#.###.#..#\r
-.....#.#.....\r
-#..#.###.#..#\r
-.#.#.....#.#.\r
-.#..##.##..#.\r
-..#.......#..\r
-...##...##...\r
-.....#.#.....\r
--- /dev/null
+' Program renders rotating 3D animation from cubes.
+' Cubes appear and disappear according to Conway's Game of Life rules.
+'
+' By Svjatoslav Agejenko.
+' Email: svjatoslav@svjatoslav.eu
+' Homepage: http://www.svjatoslav.eu
+'
+' Changelog:
+' ?, Initial version
+' 2024, Improved program readability using AI
+
+DECLARE SUB PlaceCube (x!, y!, z!)
+DECLARE SUB DrawCube (x!, y!, z!)
+
+DECLARE SUB CreateCollisionData ()
+DECLARE SUB UpdateCollisionData ()
+DECLARE SUB RenderScene ()
+DECLARE SUB InitializeEnvironment ()
+DECLARE SUB StartGame ()
+
+DIM SHARED numPoints, numLines, pointCount, lineCount
+DIM SHARED pointsX(1 TO 3000), pointsY(1 TO 3000), pointsZ(1 TO 3000)
+DIM SHARED renderedPointsX(1 TO 7000), renderedPointsY(1 TO 7000)
+DIM SHARED originalRenderedPointsX(0 TO 9000), originalRenderedPointsY(0 TO 9000)
+DIM SHARED oldPointCount, oldLineCount
+DIM SHARED lineVertices1(1 TO 3800), lineVertices2(1 TO 3800), lineColors(1 TO 3800)
+DIM SHARED originalLineVertices1(1 TO 3800), originalLineVertices2(1 TO 3800)
+DIM SHARED myPositionX, myPositionY, myPositionZ
+DIM SHARED myPreviousPositionX, myPreviousPositionY, myPreviousPositionZ
+DIM SHARED angle1, angle2
+DIM SHARED angle1Str, angle2Str
+DIM SHARED frameCount
+
+DIM SHARED gameOfLifeGrid(1 TO 50, 1 TO 50)
+DIM SHARED nextGameOfLifeGrid(1 TO 50, 1 TO 50)
+
+StartGame
+
+angle1 = 1.5
+10
+frameCount = frameCount + 1
+
+CreateCollisionData
+RenderScene
+
+myPositionX = SIN(frameCount / 20) * 12
+myPositionY = SIN(frameCount / 50) * 10 + 15
+myPositionZ = COS(frameCount / 20) * 12
+
+angle1 = angle1 - .05
+angle2 = 2.2 + SIN(frameCount / 50) / 2
+
+inputKey$ = INKEY$
+IF inputKey$ <> "" THEN SYSTEM
+GOTO 10
+
+SUB CreateCollisionData
+pointCount = numPoints
+lineCount = numLines
+
+FOR y = 1 TO 50
+ FOR x = 1 TO 50
+ IF gameOfLifeGrid(x, y) = 1 THEN
+ v = ABS(x - 26) + ABS(y - 26) + frameCount
+ PlaceCube x - 25, SIN(v / 5) * 5, y - 25
+ END IF
+ NEXT x
+NEXT y
+
+IF frameCount \ 10 = frameCount / 10 THEN
+
+FOR y = 2 TO 49
+FOR x = 2 TO 49
+c = gameOfLifeGrid(x - 1, y - 1)
+c = c + gameOfLifeGrid(x, y - 1)
+c = c + gameOfLifeGrid(x + 1, y - 1)
+c = c + gameOfLifeGrid(x - 1, y)
+c = c + gameOfLifeGrid(x + 1, y)
+c = c + gameOfLifeGrid(x - 1, y + 1)
+c = c + gameOfLifeGrid(x, y + 1)
+c = c + gameOfLifeGrid(x + 1, y + 1)
+
+IF gameOfLifeGrid(x, y) = 1 THEN
+ IF (c > 3) OR (c < 2) THEN nextGameOfLifeGrid(x, y) = 0 ELSE nextGameOfLifeGrid(x, y) = 1
+ELSE
+ IF c = 3 THEN nextGameOfLifeGrid(x, y) = 1 ELSE nextGameOfLifeGrid(x, y) = 0
+END IF
+NEXT x
+NEXT y
+
+FOR y = 1 TO 50
+FOR x = 1 TO 50
+ gameOfLifeGrid(x, y) = nextGameOfLifeGrid(x, y)
+NEXT x
+NEXT y
+END IF
+
+END SUB
+
+SUB InitializeEnvironment
+FOR z = -5 TO 5
+FOR x = -5 TO 5
+pointCount = pointCount + 1
+pointsX(pointCount) = x
+pointsY(pointCount) = 0
+pointsZ(pointCount) = z
+IF x > -5 THEN
+lineCount = lineCount + 1
+lineVertices1(lineCount) = pointCount
+lineVertices2(lineCount) = pointCount - 1
+lineColors(lineCount) = 1
+END IF
+IF z > -5 THEN
+lineCount = lineCount + 1
+lineVertices1(lineCount) = pointCount
+lineVertices2(lineCount) = pointCount - 10
+lineColors(lineCount) = 1
+END IF
+NEXT x
+NEXT z
+
+numPoints = pointCount
+numLines = lineCount
+
+END SUB
+
+SUB InitializeEnvironment1
+pointCount = 1
+pointsX(pointCount) = -2
+pointsY(pointCount) = 0
+pointsZ(pointCount) = 0
+pointCount = pointCount + 1
+pointsX(pointCount) = 2
+pointsY(pointCount) = 0
+pointsZ(pointCount) = 0
+
+lineCount = 1
+lineVertices1(lineCount) = 1
+lineVertices2(lineCount) = 2
+lineColors(lineCount) = 14
+
+END SUB
+
+SUB PlaceCube (x, y, z)
+
+v = 3
+
+lineCount = lineCount + 1
+lineVertices1(lineCount) = pointCount + 1
+lineVertices2(lineCount) = pointCount + 2
+lineColors(lineCount) = v
+
+lineCount = lineCount + 1
+lineVertices1(lineCount) = pointCount + 2
+lineVertices2(lineCount) = pointCount + 3
+lineColors(lineCount) = v
+
+lineCount = lineCount + 1
+lineVertices1(lineCount) = pointCount + 3
+lineVertices2(lineCount) = pointCount + 4
+lineColors(lineCount) = v
+
+lineCount = lineCount + 1
+lineVertices1(lineCount) = pointCount + 4
+lineVertices2(lineCount) = pointCount + 1
+lineColors(lineCount) = v
+
+lineCount = lineCount + 1
+lineVertices1(lineCount) = pointCount + 5
+lineVertices2(lineCount) = pointCount + 6
+lineColors(lineCount) = v
+
+lineCount = lineCount + 1
+lineVertices1(lineCount) = pointCount + 6
+lineVertices2(lineCount) = pointCount + 7
+lineColors(lineCount) = v
+
+lineCount = lineCount + 1
+lineVertices1(lineCount) = pointCount + 7
+lineVertices2(lineCount) = pointCount + 8
+lineColors(lineCount) = v
+
+lineCount = lineCount + 1
+lineVertices1(lineCount) = pointCount + 8
+lineVertices2(lineCount) = pointCount + 5
+lineColors(lineCount) = v
+
+lineCount = lineCount + 1
+lineVertices1(lineCount) = pointCount + 1
+lineVertices2(lineCount) = pointCount + 5
+lineColors(lineCount) = v
+
+lineCount = lineCount + 1
+lineVertices1(lineCount) = pointCount + 2
+lineVertices2(lineCount) = pointCount + 6
+lineColors(lineCount) = v
+
+lineCount = lineCount + 1
+lineVertices1(lineCount) = pointCount + 3
+lineVertices2(lineCount) = pointCount + 7
+lineColors(lineCount) = v
+
+lineCount = lineCount + 1
+lineVertices1(lineCount) = pointCount + 4
+lineVertices2(lineCount) = pointCount + 8
+lineColors(lineCount) = v
+
+pointCount = pointCount + 1
+pointsX(pointCount) = x - .5
+pointsY(pointCount) = y
+pointsZ(pointCount) = z - .5
+
+pointCount = pointCount + 1
+pointsX(pointCount) = x + .5
+pointsY(pointCount) = y
+pointsZ(pointCount) = z - .5
+
+pointCount = pointCount + 1
+pointsX(pointCount) = x + .5
+pointsY(pointCount) = y
+pointsZ(pointCount) = z + .5
+
+pointCount = pointCount + 1
+pointsX(pointCount) = x - .5
+pointsY(pointCount) = y
+pointsZ(pointCount) = z + .5
+
+pointCount = pointCount + 1
+pointsX(pointCount) = x - .5
+pointsY(pointCount) = y + 1
+pointsZ(pointCount) = z - .5
+
+pointCount = pointCount + 1
+pointsX(pointCount) = x + .5
+pointsY(pointCount) = y + 1
+pointsZ(pointCount) = z - .5
+
+pointCount = pointCount + 1
+pointsX(pointCount) = x + .5
+pointsY(pointCount) = y + 1
+pointsZ(pointCount) = z + .5
+
+pointCount = pointCount + 1
+pointsX(pointCount) = x - .5
+pointsY(pointCount) = y + 1
+pointsZ(pointCount) = z + .5
+
+END SUB
+
+SUB RenderScene
+
+sineAngle1 = SIN(angle1)
+cosineAngle1 = COS(angle1)
+sineAngle2 = SIN(angle2)
+cosineAngle2 = COS(angle2)
+
+FOR a = 1 TO pointCount
+x = pointsX(a) + myPositionX
+y = pointsY(a) - myPositionY
+z = pointsZ(a) + myPositionZ
+
+x1 = x * sineAngle1 - z * cosineAngle1
+z1 = x * cosineAngle1 + z * sineAngle1
+y1 = y * sineAngle2 - z1 * cosineAngle2
+z2 = y * cosineAngle2 + z1 * sineAngle2
+
+IF z2 < .5 THEN
+renderedPointsX(a) = -1
+ELSE
+renderedPointsX(a) = 320 + (x1 / z2 * 400)
+renderedPointsY(a) = 240 - (y1 / z2 * 400)
+END IF
+NEXT a
+
+FOR a = 1 TO lineCount
+l1 = originalLineVertices1(a)
+l2 = originalLineVertices2(a)
+
+IF originalRenderedPointsX(l1) = -1 OR originalRenderedPointsX(l2) = -1 THEN
+ELSE
+LINE (originalRenderedPointsX(l1), originalRenderedPointsY(l1))-(originalRenderedPointsX(l2), originalRenderedPointsY(l2)), 0
+END IF
+
+l1 = lineVertices1(a)
+l2 = lineVertices2(a)
+IF renderedPointsX(l1) = -1 OR renderedPointsX(l2) = -1 THEN
+ELSE
+LINE (renderedPointsX(l1), renderedPointsY(l1))-(renderedPointsX(l2), renderedPointsY(l2)), lineColors(a)
+END IF
+NEXT a
+
+IF lineCount < oldLineCount THEN
+FOR a = lineCount + 1 TO oldLineCount
+l1 = originalLineVertices1(a)
+l2 = originalLineVertices2(a)
+IF originalRenderedPointsX(l1) = -1 OR originalRenderedPointsX(l2) = -1 THEN
+ELSE
+LINE (originalRenderedPointsX(l1), originalRenderedPointsY(l1))-(originalRenderedPointsX(l2), originalRenderedPointsY(l2)), 0
+END IF
+NEXT a
+END IF
+
+FOR a = 1 TO pointCount
+originalRenderedPointsX(a) = renderedPointsX(a)
+originalRenderedPointsY(a) = renderedPointsY(a)
+NEXT a
+
+oldPointCount = pointCount
+
+FOR a = 1 TO lineCount
+originalLineVertices1(a) = lineVertices1(a)
+originalLineVertices2(a) = lineVertices2(a)
+NEXT a
+
+oldLineCount = lineCount
+
+END SUB
+
+SUB StartGame
+SCREEN 12
+numPoints = 0
+numLines = 0
+pointCount = numPoints
+lineCount = numLines
+gridSize = 50
+
+myPositionX = 4
+myPositionY = 15
+myPositionZ = 17
+angle1 = ATN(1) / 2 - .29
+angle2 = angle1 + 1
+
+FOR a = 1 TO 1000
+lineColors(a) = 4
+NEXT a
+
+FOR a = 1 TO 1000
+originalLineVertices1(a) = 1
+originalLineVertices2(a) = 1
+NEXT a
+
+OPEN "3dlife.dat" FOR INPUT AS #1
+y = 20
+20
+IF EOF(1) <> 0 THEN GOTO 30
+x = 20
+
+LINE INPUT #1, inputLine$
+FOR b = 1 TO LEN(inputLine$)
+ c$ = RIGHT$(LEFT$(inputLine$, b), 1)
+ IF c$ = "#" THEN gameOfLifeGrid(x, y) = 1
+ x = x + 1
+NEXT b
+
+y = y + 1
+GOTO 20
+30
+CLOSE #1
+
+END SUB
--- /dev/null
+.....#.#.....\r
+...##...##...\r
+..#.......#..\r
+.#..##.##..#.\r
+.#.#.....#.#.\r
+#..#.###.#..#\r
+.....#.#.....\r
+#..#.###.#..#\r
+.#.#.....#.#.\r
+.#..##.##..#.\r
+..#.......#..\r
+...##...##...\r
+.....#.#.....\r
+++ /dev/null
-' Program to simulate gravitational forces between atoms.\r
-' By Svjatoslav Agejenko.\r
-' Email: svjatoslav@svjatoslav.eu\r
-' Homepage: http://www.svjatoslav.eu\r
-'\r
-' Changelog:\r
-' 2003.12, Initial version\r
-' 2024.08, Improved program readability using AI\r
-\r
-DECLARE SUB Gravitate ()\r
-DECLARE SUB AddAtom (x AS SINGLE, y AS SINGLE, z AS SINGLE, size AS SINGLE)\r
-DECLARE SUB DisplaySystem ()\r
-\r
-DIM SHARED atomX(1 TO 100)\r
-DIM SHARED atomY(1 TO 100)\r
-DIM SHARED atomZ(1 TO 100)\r
-DIM SHARED atomXSpeed(1 TO 100)\r
-DIM SHARED atomYSpeed(1 TO 100)\r
-DIM SHARED atomZSpeed(1 TO 100)\r
-DIM SHARED atomSize(1 TO 100)\r
-DIM SHARED countOfAtoms\r
-DIM SHARED myX, myY, myZ\r
-DIM SHARED oldAtomX(1 TO 100)\r
-DIM SHARED oldAtomY(1 TO 100)\r
-DIM SHARED oldAtomSize(1 TO 100)\r
-\r
-myX = 0\r
-myY = 0\r
-myZ = -5\r
-countOfAtoms = 0\r
-\r
-SCREEN 13\r
-\r
-' Initialize the system with a random distribution of atoms\r
-FOR a = 1 TO 30\r
- AddAtom RND * 6 - 3, RND * 6 - 3, RND * 4, 50\r
-NEXT a\r
-\r
-' Main loop to display and update the system\r
-1\r
- DisplaySystem\r
- Gravitate\r
- IF INKEY$ <> "" THEN SYSTEM ' Exit on any key press\r
-GOTO 1\r
-\r
-SUB AddAtom (x, y, z, size)\r
- ' Increment the atom count\r
- countOfAtoms = countOfAtoms + 1\r
-\r
- ' Store the new atom's position and size\r
- atomX(countOfAtoms) = x\r
- atomY(countOfAtoms) = y\r
- atomZ(countOfAtoms) = z\r
- atomSize(countOfAtoms) = size\r
-\r
- ' Initialize the speed of the new atom to zero\r
- atomXSpeed(countOfAtoms) = 0\r
- atomYSpeed(countOfAtoms) = 0\r
- atomZSpeed(countOfAtoms) = 0\r
-END SUB\r
-\r
-SUB DisplaySystem\r
- FOR a = 1 TO countOfAtoms\r
- ' Calculate the relative position of each atom\r
- x = atomX(a) - myX\r
- y = atomY(a) - myY\r
- z = atomZ(a) - myZ\r
-\r
- ' Project the 3D positions onto a 2D screen\r
- x1 = x / z * 100 + 160\r
- y1 = y / z * 100 + 100\r
-\r
- ' Erase the old atom position and draw the new one\r
- CIRCLE (oldAtomX(a), oldAtomY(a)), oldAtomSize(a), 0\r
- CIRCLE (x1, y1), atomSize(a) / z, 15\r
-\r
- ' Update the old positions for the next frame\r
- oldAtomX(a) = x1\r
- oldAtomY(a) = y1\r
- oldAtomSize(a) = atomSize(a) / z\r
- NEXT a\r
-END SUB\r
-\r
-SUB Gravitate\r
- DIM pxs, pys, pzs\r
-\r
- FOR a = 1 TO countOfAtoms\r
- ' Get the current atom's position\r
- x = atomX(a)\r
- y = atomY(a)\r
- z = atomZ(a)\r
-\r
- ' Initialize gravitational forces to zero\r
- pxs = 0\r
- pys = 0\r
- pzs = 0\r
-\r
- FOR b = 1 TO countOfAtoms\r
- IF b = a THEN GOTO 2 ' Skip self-gravitation\r
-\r
- ' Calculate the distance between atoms\r
- v = SQR((atomX(b) - x) ^ 2 + (atomY(b) - y) ^ 2 + (atomZ(b) - z) ^ 2)\r
- v2 = 1 / (v - 1)\r
-\r
- ' Accumulate gravitational forces from other atoms\r
- pxs = pxs + (atomX(b) - x) / v2 / 10000\r
- pys = pys + (atomY(b) - y) / v2 / 10000\r
- pzs = pzs + (atomZ(b) - z) / v2 / 10000\r
-\r
-2 NEXT b\r
-\r
- ' Update the atom's velocity with the accumulated forces\r
- atomXSpeed(a) = atomXSpeed(a) / 1.01 + pxs\r
- atomYSpeed(a) = atomYSpeed(a) / 1.01 + pys\r
- atomZSpeed(a) = atomZSpeed(a) / 1.01 + pzs\r
- NEXT a\r
-\r
- ' Update the positions of all atoms based on their velocities\r
- FOR a = 1 TO countOfAtoms\r
- atomX(a) = atomX(a) + atomXSpeed(a)\r
- atomY(a) = atomY(a) + atomYSpeed(a)\r
- atomZ(a) = atomZ(a) + atomZSpeed(a)\r
- NEXT a\r
-END SUB
\ No newline at end of file
--- /dev/null
+' Program to simulate gravitational forces between atoms.\r
+' By Svjatoslav Agejenko.\r
+' Email: svjatoslav@svjatoslav.eu\r
+' Homepage: http://www.svjatoslav.eu\r
+'\r
+' Changelog:\r
+' 2003.12, Initial version\r
+' 2024.08, Improved program readability using AI\r
+\r
+DECLARE SUB Gravitate ()\r
+DECLARE SUB AddAtom (x AS SINGLE, y AS SINGLE, z AS SINGLE, size AS SINGLE)\r
+DECLARE SUB DisplaySystem ()\r
+\r
+DIM SHARED atomX(1 TO 100)\r
+DIM SHARED atomY(1 TO 100)\r
+DIM SHARED atomZ(1 TO 100)\r
+DIM SHARED atomXSpeed(1 TO 100)\r
+DIM SHARED atomYSpeed(1 TO 100)\r
+DIM SHARED atomZSpeed(1 TO 100)\r
+DIM SHARED atomSize(1 TO 100)\r
+DIM SHARED countOfAtoms\r
+DIM SHARED myX, myY, myZ\r
+DIM SHARED oldAtomX(1 TO 100)\r
+DIM SHARED oldAtomY(1 TO 100)\r
+DIM SHARED oldAtomSize(1 TO 100)\r
+\r
+myX = 0\r
+myY = 0\r
+myZ = -5\r
+countOfAtoms = 0\r
+\r
+SCREEN 13\r
+\r
+' Initialize the system with a random distribution of atoms\r
+FOR a = 1 TO 30\r
+ AddAtom RND * 6 - 3, RND * 6 - 3, RND * 4, 50\r
+NEXT a\r
+\r
+' Main loop to display and update the system\r
+1\r
+ DisplaySystem\r
+ Gravitate\r
+ IF INKEY$ <> "" THEN SYSTEM ' Exit on any key press\r
+ \r
+ ' Delay animation\r
+ SOUND 0, 1\r
+GOTO 1\r
+\r
+SUB AddAtom (x, y, z, size)\r
+ ' Increment the atom count\r
+ countOfAtoms = countOfAtoms + 1\r
+\r
+ ' Store the new atom's position and size\r
+ atomX(countOfAtoms) = x\r
+ atomY(countOfAtoms) = y\r
+ atomZ(countOfAtoms) = z\r
+ atomSize(countOfAtoms) = size\r
+\r
+ ' Initialize the speed of the new atom to zero\r
+ atomXSpeed(countOfAtoms) = 0\r
+ atomYSpeed(countOfAtoms) = 0\r
+ atomZSpeed(countOfAtoms) = 0\r
+END SUB\r
+\r
+SUB DisplaySystem\r
+ FOR a = 1 TO countOfAtoms\r
+ ' Calculate the relative position of each atom\r
+ x = atomX(a) - myX\r
+ y = atomY(a) - myY\r
+ z = atomZ(a) - myZ\r
+\r
+ ' Project the 3D positions onto a 2D screen\r
+ x1 = x / z * 100 + 160\r
+ y1 = y / z * 100 + 100\r
+\r
+ ' Erase the old atom position and draw the new one\r
+ CIRCLE (oldAtomX(a), oldAtomY(a)), oldAtomSize(a), 0\r
+ CIRCLE (x1, y1), atomSize(a) / z, 15\r
+\r
+ ' Update the old positions for the next frame\r
+ oldAtomX(a) = x1\r
+ oldAtomY(a) = y1\r
+ oldAtomSize(a) = atomSize(a) / z\r
+ NEXT a\r
+END SUB\r
+\r
+SUB Gravitate\r
+ DIM pxs, pys, pzs\r
+\r
+ FOR a = 1 TO countOfAtoms\r
+ ' Get the current atom's position\r
+ x = atomX(a)\r
+ y = atomY(a)\r
+ z = atomZ(a)\r
+\r
+ ' Initialize gravitational forces to zero\r
+ pxs = 0\r
+ pys = 0\r
+ pzs = 0\r
+\r
+ FOR b = 1 TO countOfAtoms\r
+ IF b = a THEN GOTO 2 ' Skip self-gravitation\r
+\r
+ ' Calculate the distance between atoms\r
+ v = SQR((atomX(b) - x) ^ 2 + (atomY(b) - y) ^ 2 + (atomZ(b) - z) ^ 2)\r
+ v2 = 1 / (v - 1)\r
+\r
+ ' Accumulate gravitational forces from other atoms\r
+ pxs = pxs + (atomX(b) - x) / v2 / 10000\r
+ pys = pys + (atomY(b) - y) / v2 / 10000\r
+ pzs = pzs + (atomZ(b) - z) / v2 / 10000\r
+\r
+2 NEXT b\r
+\r
+ ' Update the atom's velocity with the accumulated forces\r
+ atomXSpeed(a) = atomXSpeed(a) / 1.01 + pxs\r
+ atomYSpeed(a) = atomYSpeed(a) / 1.01 + pys\r
+ atomZSpeed(a) = atomZSpeed(a) / 1.01 + pzs\r
+ NEXT a\r
+\r
+ ' Update the positions of all atoms based on their velocities\r
+ FOR a = 1 TO countOfAtoms\r
+ atomX(a) = atomX(a) + atomXSpeed(a)\r
+ atomY(a) = atomY(a) + atomYSpeed(a)\r
+ atomZ(a) = atomZ(a) + atomZSpeed(a)\r
+ NEXT a\r
+END SUB\r
+\r
--- /dev/null
+' Program to demonstrate 3x3 matrix math for coordinate rotation in 3D space.\r
+' By Svjatoslav Agejenko.\r
+' Email: svjatoslav@svjatoslav.eu\r
+' Homepage: http://www.svjatoslav.eu\r
+'\r
+' Changelog:\r
+' 2003.03, Initial version\r
+' 2024.08, Improved program readability using AI\r
+\r
+' Use keys:\r
+' 7 9 - change alpha angle\r
+' 4 6 - change beta angle\r
+' 1 3 - change gamma angle\r
+' ESC - quit program\r
+\r
+DECLARE SUB graphicalCoordinates (xVal AS Single, yVal AS Single, zVal AS Single, x1Val AS Single, y1Val AS Single)\r
+DECLARE SUB setAngles (alphaVal AS Single, betaVal AS Single, gammaVal AS Single)\r
+DIM SHARED matrixX1 AS Single, matrixY1 AS Single, matrixZ1 AS Single\r
+DIM SHARED matrixX2 AS Single, matrixY2 AS Single, matrixZ2 AS Single\r
+DIM SHARED matrixX3 AS Single, matrixY3 AS Single, matrixZ3 AS Single\r
+\r
+SCREEN 7, , , 1\r
+\r
+' Main loop starts here\r
+DO\r
+ CALL setAngles(angleAlpha, angleBeta, angleGamma)\r
+\r
+ FOR y = -70 TO 70 STEP 5\r
+ FOR x = -70 TO 70 STEP 5\r
+ CALL graphicalCoordinates(x, y, SIN((ABS(x) + ABS(y)) / 30) * 30, x1Val, y1Val)\r
+ PSET (x1Val, y1Val), 15\r
+ NEXT x\r
+ NEXT y\r
+ PCOPY 0, 1\r
+ CLS\r
+ inputChar$ = INPUT$(1)\r
+\r
+ ' Adjust rotation angles based on user input\r
+ IF inputChar$ = "7" THEN angleAlpha = angleAlpha + 0.1\r
+ IF inputChar$ = "9" THEN angleAlpha = angleAlpha - 0.1\r
+ IF inputChar$ = "4" THEN angleBeta = angleBeta + 0.1\r
+ IF inputChar$ = "6" THEN angleBeta = angleBeta - 0.1\r
+ IF inputChar$ = "1" THEN angleGamma = angleGamma + 0.1\r
+ IF inputChar$ = "3" THEN angleGamma = angleGamma - 0.1\r
+ IF inputChar$ = CHR$(27) THEN SYSTEM ' Exit program if ESC key is pressed\r
+LOOP\r
+\r
+SUB graphicalCoordinates (xVal AS Single, yVal AS Single, zVal AS Single, x1Val AS Single, y1Val AS Single)\r
+ ' Perform matrix transformation to rotate coordinates\r
+ rxVal = xVal * matrixX1 + yVal * matrixY1 + zVal * matrixZ1\r
+ ryVal = xVal * matrixX2 + yVal * matrixY2 + zVal * matrixZ2\r
+ rzVal = xVal * matrixX3 + yVal * matrixY3 + zVal * matrixZ3\r
+\r
+ ' Apply perspective calculation to give the illusion of depth\r
+ rzVal = rzVal + 100\r
+ x1Val = rxVal / rzVal * 120 + 160\r
+ y1Val = ryVal / rzVal * 120 + 100\r
+END SUB\r
+\r
+SUB setAngles (alphaVal AS Single, betaVal AS Single, gammaVal AS Single)\r
+ ' Calculate the elements of the rotation matrix based on the angles\r
+ matrixX1 = SIN(gammaVal) * SIN(betaVal) * SIN(alphaVal) + COS(gammaVal) * COS(alphaVal)\r
+ matrixY1 = COS(betaVal) * SIN(alphaVal)\r
+ matrixZ1 = SIN(gammaVal) * COS(alphaVal) - COS(gammaVal) * SIN(betaVal) * SIN(alphaVal)\r
+\r
+ matrixX2 = SIN(gammaVal) * SIN(betaVal) * COS(alphaVal) - COS(gammaVal) * SIN(alphaVal)\r
+ matrixY2 = COS(betaVal) * COS(alphaVal)\r
+ matrixZ2 = -COS(gammaVal) * SIN(betaVal) * COS(alphaVal) - SIN(gammaVal) * SIN(alphaVal)\r
+\r
+ matrixX3 = -SIN(gammaVal) * COS(betaVal)\r
+ matrixY3 = SIN(betaVal)\r
+ matrixZ3 = COS(gammaVal) * COS(betaVal)\r
+END SUB
\ No newline at end of file
+++ /dev/null
-' Program to demonstrate 3x3 matrix math for coordinate rotation in 3D space.\r
-' By Svjatoslav Agejenko.\r
-' Email: svjatoslav@svjatoslav.eu\r
-' Homepage: http://www.svjatoslav.eu\r
-'\r
-' Changelog:\r
-' 2003.03, Initial version\r
-' 2024.08, Improved program readability using AI\r
-\r
-' Use keys:\r
-' 7 9 - change alpha angle\r
-' 4 6 - change beta angle\r
-' 1 3 - change gamma angle\r
-' ESC - quit program\r
-\r
-DECLARE SUB graphicalCoordinates (xVal AS Single, yVal AS Single, zVal AS Single, x1Val AS Single, y1Val AS Single)\r
-DECLARE SUB setAngles (alphaVal AS Single, betaVal AS Single, gammaVal AS Single)\r
-DIM SHARED matrixX1 AS Single, matrixY1 AS Single, matrixZ1 AS Single\r
-DIM SHARED matrixX2 AS Single, matrixY2 AS Single, matrixZ2 AS Single\r
-DIM SHARED matrixX3 AS Single, matrixY3 AS Single, matrixZ3 AS Single\r
-\r
-SCREEN 7, , , 1\r
-\r
-' Main loop starts here\r
-DO\r
- CALL setAngles(angleAlpha, angleBeta, angleGamma)\r
-\r
- FOR y = -70 TO 70 STEP 5\r
- FOR x = -70 TO 70 STEP 5\r
- CALL graphicalCoordinates(x, y, SIN((ABS(x) + ABS(y)) / 30) * 30, x1Val, y1Val)\r
- PSET (x1Val, y1Val), 15\r
- NEXT x\r
- NEXT y\r
- PCOPY 0, 1\r
- CLS\r
- inputChar$ = INPUT$(1)\r
-\r
- ' Adjust rotation angles based on user input\r
- IF inputChar$ = "7" THEN angleAlpha = angleAlpha + 0.1\r
- IF inputChar$ = "9" THEN angleAlpha = angleAlpha - 0.1\r
- IF inputChar$ = "4" THEN angleBeta = angleBeta + 0.1\r
- IF inputChar$ = "6" THEN angleBeta = angleBeta - 0.1\r
- IF inputChar$ = "1" THEN angleGamma = angleGamma + 0.1\r
- IF inputChar$ = "3" THEN angleGamma = angleGamma - 0.1\r
- IF inputChar$ = CHR$(27) THEN SYSTEM ' Exit program if ESC key is pressed\r
-LOOP\r
-\r
-SUB graphicalCoordinates (xVal AS Single, yVal AS Single, zVal AS Single, x1Val AS Single, y1Val AS Single)\r
- ' Perform matrix transformation to rotate coordinates\r
- rxVal = xVal * matrixX1 + yVal * matrixY1 + zVal * matrixZ1\r
- ryVal = xVal * matrixX2 + yVal * matrixY2 + zVal * matrixZ2\r
- rzVal = xVal * matrixX3 + yVal * matrixY3 + zVal * matrixZ3\r
-\r
- ' Apply perspective calculation to give the illusion of depth\r
- rzVal = rzVal + 100\r
- x1Val = rxVal / rzVal * 120 + 160\r
- y1Val = ryVal / rzVal * 120 + 100\r
-END SUB\r
-\r
-SUB setAngles (alphaVal AS Single, betaVal AS Single, gammaVal AS Single)\r
- ' Calculate the elements of the rotation matrix based on the angles\r
- matrixX1 = SIN(gammaVal) * SIN(betaVal) * SIN(alphaVal) + COS(gammaVal) * COS(alphaVal)\r
- matrixY1 = COS(betaVal) * SIN(alphaVal)\r
- matrixZ1 = SIN(gammaVal) * COS(alphaVal) - COS(gammaVal) * SIN(betaVal) * SIN(alphaVal)\r
-\r
- matrixX2 = SIN(gammaVal) * SIN(betaVal) * COS(alphaVal) - COS(gammaVal) * SIN(alphaVal)\r
- matrixY2 = COS(betaVal) * COS(alphaVal)\r
- matrixZ2 = -COS(gammaVal) * SIN(betaVal) * COS(alphaVal) - SIN(gammaVal) * SIN(alphaVal)\r
-\r
- matrixX3 = -SIN(gammaVal) * COS(betaVal)\r
- matrixY3 = SIN(betaVal)\r
- matrixZ3 = COS(gammaVal) * COS(betaVal)\r
-END SUB
\ No newline at end of file
--- /dev/null
+' 3D rocket simulator. Rocket takes off from the surface of the planet.
+'
+' By Svjatoslav Agejenko.
+' Email: svjatoslav@svjatoslav.eu
+' Homepage: http://www.svjatoslav.eu
+
+' Changelog:
+' 2001, Initial version
+' 2024, Improved program readability using AI
+'
+' Usage:
+' arrow keys - move around
+' 2, 6, 4, 8 - look around
+' - - fly up
+' + - fly down
+
+DECLARE SUB addp ()
+DECLARE SUB addl ()
+DEFDBL A-Z
+DECLARE SUB teerock ()
+DECLARE SUB teemaa ()
+DECLARE SUB start ()
+DECLARE SUB n3d ()
+
+DIM SHARED pointX(1 TO 1500)
+DIM SHARED pointY(1 TO 1500)
+DIM SHARED pointZ(1 TO 1500)
+
+DIM SHARED linePoint1(1 TO 3000)
+DIM SHARED linePoint2(1 TO 3000)
+DIM SHARED lc(1 TO 3000)
+
+DIM SHARED onScreenPointX(1 TO 1900)
+DIM SHARED onScreenPointY(1 TO 1900)
+
+DIM SHARED rkx(1 TO 200)
+DIM SHARED rky(1 TO 200)
+DIM SHARED rkz(1 TO 200)
+
+DIM SHARED pointCount, lineCount
+DIM SHARED cameraX, cameraY, cameraZ
+DIM SHARED cameraXSpeed, cameraYSpeed, cameraZSpeed
+DIM SHARED my1, my2
+
+DIM SHARED ox1(1 TO 2500)
+DIM SHARED oy1(1 TO 2500)
+DIM SHARED ox2(1 TO 2500)
+DIM SHARED oy2(1 TO 2500)
+DIM SHARED frm, frm2, frm3
+
+DIM SHARED mk, mks, rs, rst
+DIM SHARED pi
+DIM SHARED rkb, rke, rkm
+DIM SHARED rx, ry, rz, rxp, ryp, rzp
+
+DIM SHARED tmr$, ts
+DIM SHARED ale
+
+start
+my1 = -pi / 2
+
+' Initialize the rocket position and velocity
+rx = 0
+ry = mk / 2 + .009
+rz = 0
+
+cameraX = 0
+cameraY = mk / 2
+cameraZ = -.05
+
+ts = 0
+frm2 = 999999
+tmr$ = TIME$
+1
+frm = frm + 1
+frm2 = frm2 + 1
+
+' Display the current values of some variables
+LOCATE 1, 1
+PRINT pointCount, lineCount, mk, mks
+LOCATE 2, 1
+PRINT rkb, rke, TIMER
+
+' Update rocket position and velocity
+rx = rx + (rxp * ts)
+ry = ry + (ryp * ts)
+rz = rz + (rzp * ts)
+
+' Update the rocket's pitch and roll rates
+ryp = ryp + (.0098 * ts)
+rxp = SIN(frm / 20) / 50
+
+' Update the points that make up the rocket
+FOR a = 1 TO rkm
+ pointX(a + rkb - 1) = rkx(a) + rx
+ pointY(a + rkb - 1) = rky(a) + ry
+ pointZ(a + rkb - 1) = rkz(a) + rz
+NEXT a
+
+' Update the observer position and velocity
+cameraX = cameraX + (cameraXSpeed * ts)
+cameraY = cameraY + (cameraYSpeed * ts)
+cameraZ = cameraZ + (cameraZSpeed * ts)
+
+' Draw the 3D scene
+n3d
+
+' Handle user input
+a$ = INKEY$
+IF a$ <> "" THEN
+ IF a$ = CHR$(0) + "H" THEN
+ ' Move forward
+ cameraZSpeed = cameraZSpeed - SIN(my1) / 100
+ cameraXSpeed = cameraXSpeed + COS(my1) / 100
+ END IF
+ IF a$ = CHR$(0) + "P" THEN
+ ' Move backward
+ cameraZSpeed = cameraZSpeed + SIN(my1) / 100
+ cameraXSpeed = cameraXSpeed - COS(my1) / 100
+ END IF
+ IF a$ = CHR$(0) + "M" THEN
+ ' Move right
+ cameraZSpeed = cameraZSpeed + COS(my1) / 100
+ cameraXSpeed = cameraXSpeed + SIN(my1) / 100
+ END IF
+ IF a$ = CHR$(0) + "K" THEN
+ ' Move left
+ cameraZSpeed = cameraZSpeed - COS(my1) / 100
+ cameraXSpeed = cameraXSpeed - SIN(my1) / 100
+ END IF
+
+ ' Change the viewing angle
+ IF a$ = CHR$(27) THEN SYSTEM
+ IF a$ = "4" THEN my1 = my1 + .1
+ IF a$ = "6" THEN my1 = my1 - .1
+ IF a$ = "2" THEN my2 = my2 + .1
+ IF a$ = "8" THEN my2 = my2 - .1
+ IF a$ = "-" THEN cameraYSpeed = cameraYSpeed + .01
+ IF a$ = "+" THEN cameraYSpeed = cameraYSpeed - .01
+ IF a$ = " " THEN cameraZSpeed = cameraZSpeed / 2: cameraXSpeed = cameraXSpeed / 2
+END IF
+
+' Calculate the speed and distance of the rocket
+v = SQR(rx * rx + ry * ry + rz * rz)
+s = SQR(rxp * rxp + ryp * ryp + rzp * rzp)
+
+' Display the current frame rate and other information
+IF tmr$ <> TIME$ THEN
+ tmr$ = TIME$
+
+ LOCATE 29, 1
+ PRINT "speed"; INT(s * 1000)
+ LOCATE 30, 1
+ PRINT "fps"; frm3; "timeslice"; INT(ts * 1000); "distance"; v;
+
+ ' Update the frame rate and time slice
+ frm3 = frm2
+ ts = 1 / frm3
+ frm2 = 0
+
+ ' Add new points to the scene
+ addp
+ addl
+END IF
+GOTO 1
+
+SUB addl
+pointCount = pointCount + 1
+pointX(pointCount) = rx
+pointY(pointCount) = ry
+pointZ(pointCount) = rz
+
+IF ale > 0 THEN
+ lineCount = lineCount + 1
+ linePoint1(lineCount) = ale
+ linePoint2(lineCount) = pointCount
+ lc(lineCount) = 13
+END IF
+
+ale = pointCount
+END SUB
+
+SUB addp
+' Add new points to the scene
+pointCount = pointCount + 1
+pointX(pointCount) = rx
+pointY(pointCount) = ry
+pointZ(pointCount) = rz
+
+pointCount = pointCount + 1
+pointX(pointCount) = rx - .001
+pointY(pointCount) = ry - .001
+pointZ(pointCount) = rz
+
+pointCount = pointCount + 1
+pointX(pointCount) = rx + .001
+pointY(pointCount) = ry - .001
+pointZ(pointCount) = rz
+
+lineCount = lineCount + 1
+linePoint1(lineCount) = pointCount
+linePoint2(lineCount) = pointCount - 1
+lc(lineCount) = 14
+
+lineCount = lineCount + 1
+linePoint1(lineCount) = pointCount - 2
+linePoint2(lineCount) = pointCount - 1
+lc(lineCount) = 14
+
+lineCount = lineCount + 1
+linePoint1(lineCount) = pointCount
+linePoint2(lineCount) = pointCount - 2
+lc(lineCount) = 14
+
+END SUB
+
+SUB n3d
+' Convert the 3D points to 2D for drawing
+s1 = SIN(my1)
+c1 = COS(my1)
+
+s2 = SIN(my2)
+c2 = COS(my2)
+
+FOR a = 1 TO pointCount
+ x = pointX(a) - cameraX
+ y = pointY(a) - cameraY
+ z = pointZ(a) - cameraZ
+
+ ' Apply the rotation transformations
+ x1 = x * s1 + z * c1
+ z1 = x * c1 - z * s1
+
+ y1 = z1 * s2 + y * c2
+ z2 = z1 * c2 - y * s2
+
+ ' Project the 3D point to 2D
+ IF z2 < .00001 THEN
+ onScreenPointX(a) = -1
+ ELSE
+ onScreenPointX(a) = x1 / z2 * 200 + 320
+ onScreenPointY(a) = 240 - y1 / z2 * 200
+
+ ' Check if the point is within the screen boundaries
+ IF onScreenPointX(a) < -50 OR onScreenPointX(a) > 1000 OR onScreenPointY(a) > 1000 THEN
+ onScreenPointX(a) = -1
+ END IF
+ END IF
+NEXT a
+
+' Draw the lines that make up the rocket
+FOR a = 1 TO lineCount
+ p1 = linePoint1(a)
+ p2 = linePoint2(a)
+ x1 = onScreenPointX(p1)
+ y1 = onScreenPointY(p1)
+ x2 = onScreenPointX(p2)
+ y2 = onScreenPointY(p2)
+
+ ' Check if the line is within the screen boundaries.
+ ' If so, erase line at old locations
+ IF ox1(a) = -1 OR ox2(a) = -1 THEN
+ ELSE
+ LINE (ox1(a), oy1(a))-(ox2(a), oy2(a)), 0
+ END IF
+
+ ' Draw the line if both endpoints are within the screen boundaries
+ IF x1 <> -1 AND x2 <> -1 THEN
+ LINE (x1, y1)-(x2, y2), lc(a)
+ END IF
+
+ ' Update the old endpoints of the line for the next frame
+ ox1(a) = x1
+ oy1(a) = y1
+ ox2(a) = x2
+ oy2(a) = y2
+NEXT a
+
+END SUB
+
+SUB start
+' Initialize the graphics mode and set up the scene
+SCREEN 12
+VIEW PRINT 1 TO 30
+
+mk = 12714
+mks = 500
+rst = 4
+pi = 3.142657
+rs = .00002
+frm2 = 0
+
+ale = -1
+pointX(1) = -.001
+pointY(1) = mk / 2
+pointZ(1) = -.001
+
+pointX(2) = .001
+pointY(2) = mk / 2
+pointZ(2) = -.001
+
+pointX(3) = .001
+pointY(3) = mk / 2
+pointZ(3) = .001
+
+pointX(4) = -.001
+pointY(4) = mk / 2
+pointZ(4) = .001
+
+pointCount = 4
+
+' Set up the initial lines that make up the rocket
+linePoint1(1) = 1
+linePoint2(1) = 2
+lc(1) = 14
+
+linePoint1(2) = 2
+linePoint2(2) = 3
+lc(2) = 14
+
+linePoint1(3) = 3
+linePoint2(3) = 4
+lc(3) = 14
+
+linePoint1(4) = 4
+linePoint2(4) = 1
+lc(4) = 14
+
+lineCount = 4
+
+' Initialize the observer position and velocity
+cameraX = 0
+cameraY = mk * 2
+cameraZ = -35
+
+teemaa
+cameraXSpeed = 0
+cameraYSpeed = 0
+cameraZSpeed = 0
+
+my1 = 0
+
+rkb = pointCount + 1
+teerock
+rke = pointCount
+
+' Calculate the number of points that make up the rocket
+rkm = rke - rkb + 1
+
+' Copy the initial points to the arrays for the rocket
+FOR a = 1 TO rkm
+ p = rkb + a - 1
+ rkx(a) = pointX(p)
+ rky(a) = pointY(p)
+ rkz(a) = pointZ(p)
+NEXT a
+
+END SUB
+
+SUB teemaa
+' Generate the points that make up the earth
+tmpp = pointCount
+le2 = 0
+
+FOR z = -(mk / 3) TO (mk / 3) STEP mks
+ le = 0
+ le2 = le2 + 1
+
+ FOR x = -(mk / 3) TO (mk / 3) STEP mks
+ ' Check if the point is within the rocket's radius
+ IF SQR(x * x + z * z) > (mk / 2.5) THEN GOTO 4
+
+ le = le + 1
+
+ ' Add the first point of the line
+ IF le = 1 THEN
+ xs = x / mks
+ END IF
+
+ pointCount = pointCount + 1
+ pointX(pointCount) = x
+ v = SQR(x * x + z * z)
+ pointY(pointCount) = SQR((v + (mk / 2)) * ((mk / 2) - v))
+ pointZ(pointCount) = z
+
+ ' Add the line to the list of lines
+ IF le > 1 THEN
+ lineCount = lineCount + 1
+ linePoint1(lineCount) = pointCount
+ linePoint2(lineCount) = pointCount - 1
+ lc(lineCount) = 3
+ END IF
+
+ ' Add the line to the list of lines if it is part of a circle
+ IF le2 > 1 THEN
+ IF xso > (x / mks) THEN GOTO 4
+ IF xso + leo <= (x / mks) THEN GOTO 4
+
+ lineCount = lineCount + 1
+ linePoint1(lineCount) = pointCount
+ linePoint2(lineCount) = pointCount - leo - xso + xs
+ lc(lineCount) = 3
+ END IF
+
+ 4
+ NEXT x
+
+ ' Update the variables for the next circle
+ leo = le
+ xso = xs
+NEXT z
+
+END SUB
+
+SUB teerock
+' Generate the points that make up the rocket
+s = 50
+
+FOR y = -9 TO 10 STEP rst
+ st = pi * 2 / 6
+
+ IF y > 5 THEN
+ s = s - 3
+ END IF
+
+ IF y > 8 THEN
+ s = s - 6
+ END IF
+
+ FOR a = 0 TO pi * 2 STEP st
+ x1 = SIN(a) * s
+ z1 = COS(a) * s
+
+ pointCount = pointCount + 1
+ pointX(pointCount) = x1 * rs
+ pointY(pointCount) = y * 50 * rs
+ pointZ(pointCount) = z1 * rs
+
+ ' Add the line to the list of lines
+ IF a > 0 THEN
+ lineCount = lineCount + 1
+ linePoint1(lineCount) = pointCount
+ linePoint2(lineCount) = pointCount - 1
+ lc(lineCount) = 10
+ END IF
+
+ ' Add the line to the list of lines if it is part of a circle
+ IF y > -9 THEN
+ lineCount = lineCount + 1
+ linePoint1(lineCount) = pointCount
+ linePoint2(lineCount) = pointCount - 7
+ lc(lineCount) = 10
+ END IF
+
+ NEXT a
+NEXT y
+
+' Add the points that make up the top of the rocket
+pointCount = pointCount + 1
+pointX(pointCount) = 0
+pointY(pointCount) = 11 * 50 * rs
+pointZ(pointCount) = 0
+
+FOR a = 1 TO 6
+ lineCount = lineCount + 1
+ linePoint1(lineCount) = pointCount
+ linePoint2(lineCount) = pointCount - a
+ lc(lineCount) = 10
+NEXT a
+
+' Add the points that make up the bottom of the rocket
+pointCount = pointCount + 1
+pointX(pointCount) = -100 * rs
+pointY(pointCount) = -450 * rs
+pointZ(pointCount) = 0
+
+pointCount = pointCount + 1
+pointX(pointCount) = 100 * rs
+pointY(pointCount) = -450 * rs
+pointZ(pointCount) = 0
+
+pointCount = pointCount + 1
+pointX(pointCount) = 0
+pointY(pointCount) = -200 * rs
+pointZ(pointCount) = 0
+
+lineCount = lineCount + 1
+linePoint1(lineCount) = pointCount
+linePoint2(lineCount) = pointCount - 1
+lc(lineCount) = 12
+
+lineCount = lineCount + 1
+linePoint1(lineCount) = pointCount - 2
+linePoint2(lineCount) = pointCount - 1
+lc(lineCount) = 12
+
+lineCount = lineCount + 1
+linePoint1(lineCount) = pointCount
+linePoint2(lineCount) = pointCount - 2
+lc(lineCount) = 12
+
+
+
+pointCount = pointCount + 1
+pointX(pointCount) = 0
+pointY(pointCount) = -450 * rs
+pointZ(pointCount) = -100 * rs
+
+pointCount = pointCount + 1
+pointX(pointCount) = 0
+pointY(pointCount) = -450 * rs
+pointZ(pointCount) = 100 * rs
+
+
+lineCount = lineCount + 1
+linePoint1(lineCount) = pointCount
+linePoint2(lineCount) = pointCount - 1
+lc(lineCount) = 12
+
+lineCount = lineCount + 1
+linePoint1(lineCount) = pointCount - 2
+linePoint2(lineCount) = pointCount - 1
+lc(lineCount) = 12
+
+lineCount = lineCount + 1
+linePoint1(lineCount) = pointCount
+linePoint2(lineCount) = pointCount - 2
+lc(lineCount) = 12
+
+END SUB
+++ /dev/null
-' 3D rocket simulator. Rocket takes off from the surface of the planet.
-'
-' By Svjatoslav Agejenko.
-' Email: svjatoslav@svjatoslav.eu
-' Homepage: http://www.svjatoslav.eu
-
-' Changelog:
-' 2001, Initial version
-' 2024, Improved program readability using AI
-'
-' Usage:
-' arrow keys - move around
-' 2, 6, 4, 8 - look around
-' - - fly up
-' + - fly down
-
-DECLARE SUB addp ()
-DECLARE SUB addl ()
-DEFDBL A-Z
-DECLARE SUB teerock ()
-DECLARE SUB teemaa ()
-DECLARE SUB start ()
-DECLARE SUB n3d ()
-
-DIM SHARED pointX(1 TO 1500)
-DIM SHARED pointY(1 TO 1500)
-DIM SHARED pointZ(1 TO 1500)
-
-DIM SHARED linePoint1(1 TO 3000)
-DIM SHARED linePoint2(1 TO 3000)
-DIM SHARED lc(1 TO 3000)
-
-DIM SHARED onScreenPointX(1 TO 1900)
-DIM SHARED onScreenPointY(1 TO 1900)
-
-DIM SHARED rkx(1 TO 200)
-DIM SHARED rky(1 TO 200)
-DIM SHARED rkz(1 TO 200)
-
-DIM SHARED pointCount, lineCount
-DIM SHARED cameraX, cameraY, cameraZ
-DIM SHARED cameraXSpeed, cameraYSpeed, cameraZSpeed
-DIM SHARED my1, my2
-
-DIM SHARED ox1(1 TO 2500)
-DIM SHARED oy1(1 TO 2500)
-DIM SHARED ox2(1 TO 2500)
-DIM SHARED oy2(1 TO 2500)
-DIM SHARED frm, frm2, frm3
-
-DIM SHARED mk, mks, rs, rst
-DIM SHARED pi
-DIM SHARED rkb, rke, rkm
-DIM SHARED rx, ry, rz, rxp, ryp, rzp
-
-DIM SHARED tmr$, ts
-DIM SHARED ale
-
-start
-my1 = -pi / 2
-
-' Initialize the rocket position and velocity
-rx = 0
-ry = mk / 2 + .009
-rz = 0
-
-cameraX = 0
-cameraY = mk / 2
-cameraZ = -.05
-
-ts = 0
-frm2 = 999999
-tmr$ = TIME$
-1
-frm = frm + 1
-frm2 = frm2 + 1
-
-' Display the current values of some variables
-LOCATE 1, 1
-PRINT pointCount, lineCount, mk, mks
-LOCATE 2, 1
-PRINT rkb, rke, TIMER
-
-' Update rocket position and velocity
-rx = rx + (rxp * ts)
-ry = ry + (ryp * ts)
-rz = rz + (rzp * ts)
-
-' Update the rocket's pitch and roll rates
-ryp = ryp + (.0098 * ts)
-rxp = SIN(frm / 20) / 50
-
-' Update the points that make up the rocket
-FOR a = 1 TO rkm
- pointX(a + rkb - 1) = rkx(a) + rx
- pointY(a + rkb - 1) = rky(a) + ry
- pointZ(a + rkb - 1) = rkz(a) + rz
-NEXT a
-
-' Update the observer position and velocity
-cameraX = cameraX + (cameraXSpeed * ts)
-cameraY = cameraY + (cameraYSpeed * ts)
-cameraZ = cameraZ + (cameraZSpeed * ts)
-
-' Draw the 3D scene
-n3d
-
-' Handle user input
-a$ = INKEY$
-IF a$ <> "" THEN
- IF a$ = CHR$(0) + "H" THEN
- ' Move forward
- cameraZSpeed = cameraZSpeed - SIN(my1) / 100
- cameraXSpeed = cameraXSpeed + COS(my1) / 100
- END IF
- IF a$ = CHR$(0) + "P" THEN
- ' Move backward
- cameraZSpeed = cameraZSpeed + SIN(my1) / 100
- cameraXSpeed = cameraXSpeed - COS(my1) / 100
- END IF
- IF a$ = CHR$(0) + "M" THEN
- ' Move right
- cameraZSpeed = cameraZSpeed + COS(my1) / 100
- cameraXSpeed = cameraXSpeed + SIN(my1) / 100
- END IF
- IF a$ = CHR$(0) + "K" THEN
- ' Move left
- cameraZSpeed = cameraZSpeed - COS(my1) / 100
- cameraXSpeed = cameraXSpeed - SIN(my1) / 100
- END IF
-
- ' Change the viewing angle
- IF a$ = CHR$(27) THEN SYSTEM
- IF a$ = "4" THEN my1 = my1 + .1
- IF a$ = "6" THEN my1 = my1 - .1
- IF a$ = "2" THEN my2 = my2 + .1
- IF a$ = "8" THEN my2 = my2 - .1
- IF a$ = "-" THEN cameraYSpeed = cameraYSpeed + .01
- IF a$ = "+" THEN cameraYSpeed = cameraYSpeed - .01
- IF a$ = " " THEN cameraZSpeed = cameraZSpeed / 2: cameraXSpeed = cameraXSpeed / 2
-END IF
-
-' Calculate the speed and distance of the rocket
-v = SQR(rx * rx + ry * ry + rz * rz)
-s = SQR(rxp * rxp + ryp * ryp + rzp * rzp)
-
-' Display the current frame rate and other information
-IF tmr$ <> TIME$ THEN
- tmr$ = TIME$
-
- LOCATE 29, 1
- PRINT "speed"; INT(s * 1000)
- LOCATE 30, 1
- PRINT "fps"; frm3; "timeslice"; INT(ts * 1000); "distance"; v;
-
- ' Update the frame rate and time slice
- frm3 = frm2
- ts = 1 / frm3
- frm2 = 0
-
- ' Add new points to the scene
- addp
- addl
-END IF
-GOTO 1
-
-SUB addl
-pointCount = pointCount + 1
-pointX(pointCount) = rx
-pointY(pointCount) = ry
-pointZ(pointCount) = rz
-
-IF ale > 0 THEN
- lineCount = lineCount + 1
- linePoint1(lineCount) = ale
- linePoint2(lineCount) = pointCount
- lc(lineCount) = 13
-END IF
-
-ale = pointCount
-END SUB
-
-SUB addp
-' Add new points to the scene
-pointCount = pointCount + 1
-pointX(pointCount) = rx
-pointY(pointCount) = ry
-pointZ(pointCount) = rz
-
-pointCount = pointCount + 1
-pointX(pointCount) = rx - .001
-pointY(pointCount) = ry - .001
-pointZ(pointCount) = rz
-
-pointCount = pointCount + 1
-pointX(pointCount) = rx + .001
-pointY(pointCount) = ry - .001
-pointZ(pointCount) = rz
-
-lineCount = lineCount + 1
-linePoint1(lineCount) = pointCount
-linePoint2(lineCount) = pointCount - 1
-lc(lineCount) = 14
-
-lineCount = lineCount + 1
-linePoint1(lineCount) = pointCount - 2
-linePoint2(lineCount) = pointCount - 1
-lc(lineCount) = 14
-
-lineCount = lineCount + 1
-linePoint1(lineCount) = pointCount
-linePoint2(lineCount) = pointCount - 2
-lc(lineCount) = 14
-
-END SUB
-
-SUB n3d
-' Convert the 3D points to 2D for drawing
-s1 = SIN(my1)
-c1 = COS(my1)
-
-s2 = SIN(my2)
-c2 = COS(my2)
-
-FOR a = 1 TO pointCount
- x = pointX(a) - cameraX
- y = pointY(a) - cameraY
- z = pointZ(a) - cameraZ
-
- ' Apply the rotation transformations
- x1 = x * s1 + z * c1
- z1 = x * c1 - z * s1
-
- y1 = z1 * s2 + y * c2
- z2 = z1 * c2 - y * s2
-
- ' Project the 3D point to 2D
- IF z2 < .00001 THEN
- onScreenPointX(a) = -1
- ELSE
- onScreenPointX(a) = x1 / z2 * 200 + 320
- onScreenPointY(a) = 240 - y1 / z2 * 200
-
- ' Check if the point is within the screen boundaries
- IF onScreenPointX(a) < -50 OR onScreenPointX(a) > 1000 OR onScreenPointY(a) > 1000 THEN
- onScreenPointX(a) = -1
- END IF
- END IF
-NEXT a
-
-' Draw the lines that make up the rocket
-FOR a = 1 TO lineCount
- p1 = linePoint1(a)
- p2 = linePoint2(a)
- x1 = onScreenPointX(p1)
- y1 = onScreenPointY(p1)
- x2 = onScreenPointX(p2)
- y2 = onScreenPointY(p2)
-
- ' Check if the line is within the screen boundaries.
- ' If so, erase line at old locations
- IF ox1(a) = -1 OR ox2(a) = -1 THEN
- ELSE
- LINE (ox1(a), oy1(a))-(ox2(a), oy2(a)), 0
- END IF
-
- ' Draw the line if both endpoints are within the screen boundaries
- IF x1 <> -1 AND x2 <> -1 THEN
- LINE (x1, y1)-(x2, y2), lc(a)
- END IF
-
- ' Update the old endpoints of the line for the next frame
- ox1(a) = x1
- oy1(a) = y1
- ox2(a) = x2
- oy2(a) = y2
-NEXT a
-
-END SUB
-
-SUB start
-' Initialize the graphics mode and set up the scene
-SCREEN 12
-VIEW PRINT 1 TO 30
-
-mk = 12714
-mks = 500
-rst = 4
-pi = 3.142657
-rs = .00002
-frm2 = 0
-
-ale = -1
-pointX(1) = -.001
-pointY(1) = mk / 2
-pointZ(1) = -.001
-
-pointX(2) = .001
-pointY(2) = mk / 2
-pointZ(2) = -.001
-
-pointX(3) = .001
-pointY(3) = mk / 2
-pointZ(3) = .001
-
-pointX(4) = -.001
-pointY(4) = mk / 2
-pointZ(4) = .001
-
-pointCount = 4
-
-' Set up the initial lines that make up the rocket
-linePoint1(1) = 1
-linePoint2(1) = 2
-lc(1) = 14
-
-linePoint1(2) = 2
-linePoint2(2) = 3
-lc(2) = 14
-
-linePoint1(3) = 3
-linePoint2(3) = 4
-lc(3) = 14
-
-linePoint1(4) = 4
-linePoint2(4) = 1
-lc(4) = 14
-
-lineCount = 4
-
-' Initialize the observer position and velocity
-cameraX = 0
-cameraY = mk * 2
-cameraZ = -35
-
-teemaa
-cameraXSpeed = 0
-cameraYSpeed = 0
-cameraZSpeed = 0
-
-my1 = 0
-
-rkb = pointCount + 1
-teerock
-rke = pointCount
-
-' Calculate the number of points that make up the rocket
-rkm = rke - rkb + 1
-
-' Copy the initial points to the arrays for the rocket
-FOR a = 1 TO rkm
- p = rkb + a - 1
- rkx(a) = pointX(p)
- rky(a) = pointY(p)
- rkz(a) = pointZ(p)
-NEXT a
-
-END SUB
-
-SUB teemaa
-' Generate the points that make up the earth
-tmpp = pointCount
-le2 = 0
-
-FOR z = -(mk / 3) TO (mk / 3) STEP mks
- le = 0
- le2 = le2 + 1
-
- FOR x = -(mk / 3) TO (mk / 3) STEP mks
- ' Check if the point is within the rocket's radius
- IF SQR(x * x + z * z) > (mk / 2.5) THEN GOTO 4
-
- le = le + 1
-
- ' Add the first point of the line
- IF le = 1 THEN
- xs = x / mks
- END IF
-
- pointCount = pointCount + 1
- pointX(pointCount) = x
- v = SQR(x * x + z * z)
- pointY(pointCount) = SQR((v + (mk / 2)) * ((mk / 2) - v))
- pointZ(pointCount) = z
-
- ' Add the line to the list of lines
- IF le > 1 THEN
- lineCount = lineCount + 1
- linePoint1(lineCount) = pointCount
- linePoint2(lineCount) = pointCount - 1
- lc(lineCount) = 3
- END IF
-
- ' Add the line to the list of lines if it is part of a circle
- IF le2 > 1 THEN
- IF xso > (x / mks) THEN GOTO 4
- IF xso + leo <= (x / mks) THEN GOTO 4
-
- lineCount = lineCount + 1
- linePoint1(lineCount) = pointCount
- linePoint2(lineCount) = pointCount - leo - xso + xs
- lc(lineCount) = 3
- END IF
-
- 4
- NEXT x
-
- ' Update the variables for the next circle
- leo = le
- xso = xs
-NEXT z
-
-END SUB
-
-SUB teerock
-' Generate the points that make up the rocket
-s = 50
-
-FOR y = -9 TO 10 STEP rst
- st = pi * 2 / 6
-
- IF y > 5 THEN
- s = s - 3
- END IF
-
- IF y > 8 THEN
- s = s - 6
- END IF
-
- FOR a = 0 TO pi * 2 STEP st
- x1 = SIN(a) * s
- z1 = COS(a) * s
-
- pointCount = pointCount + 1
- pointX(pointCount) = x1 * rs
- pointY(pointCount) = y * 50 * rs
- pointZ(pointCount) = z1 * rs
-
- ' Add the line to the list of lines
- IF a > 0 THEN
- lineCount = lineCount + 1
- linePoint1(lineCount) = pointCount
- linePoint2(lineCount) = pointCount - 1
- lc(lineCount) = 10
- END IF
-
- ' Add the line to the list of lines if it is part of a circle
- IF y > -9 THEN
- lineCount = lineCount + 1
- linePoint1(lineCount) = pointCount
- linePoint2(lineCount) = pointCount - 7
- lc(lineCount) = 10
- END IF
-
- NEXT a
-NEXT y
-
-' Add the points that make up the top of the rocket
-pointCount = pointCount + 1
-pointX(pointCount) = 0
-pointY(pointCount) = 11 * 50 * rs
-pointZ(pointCount) = 0
-
-FOR a = 1 TO 6
- lineCount = lineCount + 1
- linePoint1(lineCount) = pointCount
- linePoint2(lineCount) = pointCount - a
- lc(lineCount) = 10
-NEXT a
-
-' Add the points that make up the bottom of the rocket
-pointCount = pointCount + 1
-pointX(pointCount) = -100 * rs
-pointY(pointCount) = -450 * rs
-pointZ(pointCount) = 0
-
-pointCount = pointCount + 1
-pointX(pointCount) = 100 * rs
-pointY(pointCount) = -450 * rs
-pointZ(pointCount) = 0
-
-pointCount = pointCount + 1
-pointX(pointCount) = 0
-pointY(pointCount) = -200 * rs
-pointZ(pointCount) = 0
-
-lineCount = lineCount + 1
-linePoint1(lineCount) = pointCount
-linePoint2(lineCount) = pointCount - 1
-lc(lineCount) = 12
-
-lineCount = lineCount + 1
-linePoint1(lineCount) = pointCount - 2
-linePoint2(lineCount) = pointCount - 1
-lc(lineCount) = 12
-
-lineCount = lineCount + 1
-linePoint1(lineCount) = pointCount
-linePoint2(lineCount) = pointCount - 2
-lc(lineCount) = 12
-
-
-
-pointCount = pointCount + 1
-pointX(pointCount) = 0
-pointY(pointCount) = -450 * rs
-pointZ(pointCount) = -100 * rs
-
-pointCount = pointCount + 1
-pointX(pointCount) = 0
-pointY(pointCount) = -450 * rs
-pointZ(pointCount) = 100 * rs
-
-
-lineCount = lineCount + 1
-linePoint1(lineCount) = pointCount
-linePoint2(lineCount) = pointCount - 1
-lc(lineCount) = 12
-
-lineCount = lineCount + 1
-linePoint1(lineCount) = pointCount - 2
-linePoint2(lineCount) = pointCount - 1
-lc(lineCount) = 12
-
-lineCount = lineCount + 1
-linePoint1(lineCount) = pointCount
-linePoint2(lineCount) = pointCount - 2
-lc(lineCount) = 12
-
-END SUB
--- /dev/null
+' Program to render animated 3D tank that drives back and forth on the 3D bridge.
+' Notably, tracks on the tank are properly synchronized with the tank movement.
+' User can freely look and fly around in the space.
+'
+' By Svjatoslav Agejenko.
+' Email: svjatoslav@svjatoslav.eu
+' Homepage: http://www.svjatoslav.eu
+'
+' Changelog:
+' 2000, Initial version
+' 2024, Improved program readability using AI
+
+' Use keys to move around:
+' Left, Right, Up, Down look around
+' + move forward
+' - move back
+' q quit
+' <space> - stop
+
+DECLARE SUB start ()
+DECLARE SUB savepos (x1%, y1%, x2%, y2%)
+DECLARE SUB teemaad ()
+DECLARE SUB setTracks ()
+DECLARE SUB getTracks ()
+DECLARE SUB getTracks1 (x1%, y1%, x2%, y2%)
+DECLARE SUB kiri ()
+DECLARE SUB getcor ()
+DECLARE SUB mulcor ()
+DECLARE SUB nait3d ()
+DECLARE SUB calcsin ()
+DEFINT A-Y
+DIM SHARED xn(1000), yn(1000), czn(1000) ' points transformed to on-screen coordinates
+DIM SHARED pointX(1000), pointY(1000), pointZ(1000) ' points in 3D space
+DIM SHARED Xs1(1000), Ys1(1000), Xe1(1000), Ye1(1000) ' Old rotated points
+DIM SHARED pointers1(1000), pointers2(1000) ' Connected points
+DIM SHARED cosine&(360), sine&(360) ' SIN & COS table
+DIM SHARED np, nl
+
+DIM SHARED Tracksx(1 TO 1000)
+DIM SHARED Tracksy(1 TO 1000)
+DIM SHARED mitTracks
+DIM SHARED smes
+
+' Pointers to the beginning of the tank tracks, this is needed to animate tank tracks
+DIM SHARED TracksBeginp ' point index
+DIM SHARED TracksBeginl ' line index
+
+' Pointers to the beginning of the bridge
+DIM SHARED BridgeBeginp ' point index
+DIM SHARED BridgeBeginl ' line index
+
+DIM SHARED Tracksxp
+DIM SHARED myx, myy, myz
+DIM SHARED myxp, myyp, myzp
+
+DIM SHARED deg1, deg2, deg3
+DIM SHARED speed
+
+DIM SHARED ssu
+
+start
+
+nait3d
+
+DATA -10,-30,-20
+DATA 30,-30,-20
+DATA 30,-10,-20
+DATA -10,-10,-20
+
+DATA -10,-30,20
+DATA 30,-30,20
+DATA 30,-10,20
+DATA -10,-10,20
+
+DATA -10,-40,-15
+DATA 30,-40,-15
+DATA -10,-40,15
+DATA 30,-40,15
+
+DATA -20,-30,-15
+DATA -20,-30, 15
+
+DATA -70,-10,-50
+DATA 60,-10, -50
+DATA 70, 0, -50
+DATA 70, 20, -50
+DATA 60, 30, -50
+DATA -70,30, -50
+DATA -80,20, -50
+DATA -80, 0, -50
+
+DATA -70,-10,-30
+DATA 60,-10, -30
+DATA 70, 0, -30
+DATA 70, 20, -30
+DATA 60, 30, -30
+DATA -70,30, -30
+DATA -80,20, -30
+DATA -80, 0, -30
+
+DATA -70,-10, 50
+DATA 60,-10, 50
+DATA 70, 0, 50
+DATA 70, 20, 50
+DATA 60, 30, 50
+DATA -70,30, 50
+DATA -80,20, 50
+DATA -80, 0, 50
+
+DATA -70,-10, 30
+DATA 60,-10, 30
+DATA 70, 0, 30
+DATA 70, 20, 30
+DATA 60, 30, 30
+DATA -70,30, 30
+DATA -80,20, 30
+DATA -80, 0, 30
+
+DATA -50,-7,-30
+DATA 50,-7,-30
+DATA 50, 15,-30
+DATA -50, 15,-30
+
+DATA -50,-7, 30
+DATA 50,-7, 30
+DATA 50, 15,30
+DATA -50, 15,30
+
+DATA -20,-20,-5
+DATA -20,-20, 5
+DATA -20,-30, 5
+DATA -20,-30,-5
+
+DATA -100,-30,-5
+DATA -100,-30, 5
+DATA -100,-40, 5
+DATA -100,-40,-5
+
+DATA 999,999,999
+
+DATA 0,1
+DATA 1,2
+DATA 2,3
+DATA 3,0
+
+DATA 4,5
+DATA 5,6
+DATA 6,7
+DATA 7,4
+
+DATA 0,8
+DATA 1,9
+DATA 4,10
+DATA 5,11
+
+DATA 0,12
+DATA 4,13
+DATA 12,8
+DATA 13,10
+
+DATA 8,9
+DATA 10,11
+DATA 8,10
+DATA 9,11
+
+DATA 12,13
+DATA 12,3
+DATA 13,7
+DATA 3,7
+DATA 1,5
+DATA 2,6
+
+DATA 14,15
+DATA 15,16
+DATA 16,17
+DATA 17,18
+DATA 18,19
+DATA 19,20
+DATA 20,21
+DATA 21,14
+
+DATA 22,23
+DATA 23,24
+DATA 24,25
+DATA 25,26
+DATA 26,27
+DATA 27,28
+DATA 28,29
+DATA 29,22
+
+DATA 30,31
+DATA 31,32
+DATA 32,33
+DATA 33,34
+DATA 34,35
+DATA 35,36
+DATA 36,37
+DATA 37,30
+
+DATA 38,39
+DATA 39,40
+DATA 40,41
+DATA 41,42
+DATA 42,43
+DATA 43,44
+DATA 44,45
+DATA 45,38
+
+DATA 46,47
+DATA 47,48
+DATA 48,49
+DATA 49,46
+
+DATA 50,51
+DATA 51,52
+DATA 52,53
+DATA 53,50
+
+DATA 50,46
+DATA 51,47
+DATA 52,48
+DATA 53,49
+
+DATA 54,55
+DATA 55,56
+DATA 56,57
+DATA 57,54
+
+DATA 54,58
+DATA 55,59
+DATA 56,60
+DATA 57,61
+
+DATA 58,59
+DATA 59,60
+DATA 60,61
+DATA 61,58
+
+DATA 54,3
+DATA 55,7
+
+DATA 999, 999
+' BRIDGE
+' right handlebars
+DATA 100,0,100
+DATA 100,50,100
+
+DATA 50,0,100
+DATA 50,50,100
+
+DATA 0,0,100
+DATA 0,50,100
+
+DATA -50,0,100
+DATA -50,50,100
+
+DATA -100,0,100
+DATA -100,50,100
+ ' 5
+DATA -150,0,100
+DATA -150,50,100
+
+DATA -200,0,100
+DATA -200,50,100
+
+DATA -250,0,100
+DATA -250,50,100
+
+DATA -300,0,100
+DATA -300,50,100
+
+DATA -350,0,100
+DATA -350,50,100
+ ' 10
+
+DATA -400,0,100
+DATA -400,50,100
+
+DATA -450,0,100
+DATA -450,50,100
+
+DATA -500,0,100
+DATA -500,50,100
+
+DATA -550,0,100
+DATA -550,50,100
+
+DATA -600,0,100
+DATA -600,50,100
+
+DATA -650,0,100
+DATA -650,50,100
+
+ ' left handlebars
+DATA 100,0,-100
+DATA 100,50,-100
+
+DATA 50,0,-100
+DATA 50,50,-100
+
+DATA 0,0,-100
+DATA 0,50,-100
+
+DATA -50,0,-100
+DATA -50,50,-100
+
+DATA -100,0,-100
+DATA -100,50,-100
+ ' 5
+DATA -150,0,-100
+DATA -150,50,-100
+
+DATA -200,0,-100
+DATA -200,50,-100
+
+DATA -250,0,-100
+DATA -250,50,-100
+
+DATA -300,0,-100
+DATA -300,50,-100
+
+DATA -350,0,-100
+DATA -350,50,-100
+ ' 10
+
+DATA -400,0,-100
+DATA -400,50,-100
+
+DATA -450,0,-100
+DATA -450,50,-100
+
+DATA -500,0,-100
+DATA -500,50,-100
+
+DATA -550,0,-100
+DATA -550,50,-100
+
+DATA -600,0,-100
+DATA -600,50,-100
+
+DATA -650,0,-100
+DATA -650,50,-100
+ ' bottom line
+DATA 100,75,-100
+DATA -650,75,-100
+
+DATA 100,75,100
+DATA -650,75,100
+ ' shore
+DATA 75,75,-100
+DATA 75,75,100
+ 'right
+DATA -50,200,-100
+DATA -50,200,100
+
+DATA 75,200,-190
+DATA 75,200, 190
+ 'left
+DATA -525,200,-100
+DATA -525,200, 100
+
+DATA -600,200,-190
+DATA -600,200, 190
+
+'
+
+DATA 999,999,999
+
+ 'right handlebars
+
+DATA 2,3
+DATA 4,5
+DATA 6,7
+DATA 8,9
+
+DATA 10,11
+DATA 12,13
+DATA 14,15
+DATA 16,17
+DATA 18,19
+
+DATA 20,21
+DATA 22,23
+DATA 24,25
+DATA 26,27
+DATA 28,29
+
+
+ 'left handlebars
+DATA 34,35
+DATA 36,37
+DATA 38,39
+DATA 40,41
+
+DATA 42,43
+DATA 44,45
+DATA 46,47
+DATA 48,49
+DATA 50,51
+
+DATA 52,53
+DATA 54,55
+DATA 56,57
+DATA 58,59
+DATA 60,61
+
+' long features
+DATA 0,4
+DATA 4,8
+DATA 8,12
+DATA 12,16
+DATA 16,20
+DATA 20,24
+DATA 24,28
+DATA 28,30
+
+DATA 1,5
+DATA 5,9
+DATA 9,13
+DATA 13,17
+DATA 17,21
+DATA 21,25
+DATA 25,29
+DATA 29,31
+
+DATA 32,36
+DATA 36,40
+DATA 40,44
+DATA 44,48
+DATA 48,52
+DATA 52,56
+DATA 56,60
+DATA 60,62
+
+DATA 33,37
+DATA 37,41
+DATA 41,45
+DATA 45,49
+DATA 49,53
+DATA 53,57
+DATA 57,61
+DATA 61,63
+
+'
+
+' end
+
+DATA 1,33
+DATA 31,63
+
+DATA 64,65
+DATA 66,67
+DATA 64,66
+DATA 65,67
+
+DATA 0,66
+DATA 32,64
+DATA 30,67
+DATA 62,65
+ ' shore
+DATA 68,69
+DATA 70,71
+DATA 68,70
+DATA 69,71
+
+DATA 72,70
+DATA 72,68
+
+DATA 73,71
+DATA 73,69
+ 'left
+DATA 74,76
+DATA 75,77
+DATA 74,75
+
+DATA 74,65
+DATA 76,65
+
+DATA 75,67
+DATA 77,67
+
+DATA 999, 999
+
+DEFINT Z
+SUB calcsin
+' precalculating sine and cosine tables
+
+FOR a! = 0 TO 359 / 57.29577951# STEP 1 / 57.29577951#
+ cosine&(a) = INT(.5 + COS(a!) * 1024)
+ sine&(a) = INT(.5 + SIN(a!) * 1024)
+ a = a + 1
+NEXT
+CLS
+END SUB
+
+DEFSNG Z
+SUB getcor
+' Loading original points and connected points
+FOR a = 0 TO 10000
+ READ pointX(a), pointY(a), pointZ(a)
+ IF pointX(a) = 999 THEN pointX(a) = 0: pointY(a) = 0: pointZ(a) = 0: GOTO 1
+NEXT
+1
+np = a
+FOR a = 0 TO 10000
+ READ pointers1(a), pointers2(a)
+ IF pointers1(a) = 999 THEN GOTO 2
+NEXT
+2
+nl = a
+
+TracksBeginp = np
+TracksBeginl = nl
+
+' Initializing connected points
+FOR a = 1 TO 48
+pointers1(nl) = np
+np = np + 1
+pointers2(nl) = np
+np = np + 1
+nl = nl + 1
+NEXT a
+
+END SUB
+
+DEFINT Z
+SUB getTracks
+
+' Initialize the number of segments
+mitTracks = 1
+getTracks1 -70, -10, -80, 0
+getTracks1 -80, 0, -80, 20
+getTracks1 -80, 20, -70, 30
+getTracks1 -70, 30, 60, 30
+getTracks1 60, 30, 70, 20
+getTracks1 70, 20, 70, 0
+getTracks1 70, 0, 60, -10
+getTracks1 60, -10, -70, -10
+
+END SUB
+
+DEFSNG Z
+SUB getTracks1 (x1%, y1%, x2%, y2%)
+REM Calculating points for a segment
+z1 = ABS(x1 - x2)
+z2 = ABS(y2 - y1)
+mi = SQR(z1 ^ 2 + z2 ^ 2) * 1.017142857#
+
+' Calculating direction vectors
+zxp = (x1 - x2) / mi
+zyp = (y2 - y1) / mi
+zx = x1
+zy = y1
+
+FOR a = 1 TO mi
+ zx = zx - zxp
+ zy = zy + zyp
+ Tracksx(mitTracks) = zx
+ Tracksy(mitTracks) = zy
+ mitTracks = mitTracks + 1
+NEXT a
+
+END SUB
+
+
+
+DEFSNG Z
+SUB nait3d
+' Main loop to render the scene
+DO
+
+ setTracks
+
+ ' Updating rotation angles
+ deg1 = deg1 + d1
+ deg2 = deg2 + d2
+ deg3 = deg3 + d3
+
+ ' Normalizing angles
+ IF deg1 <= 0 THEN deg1 = deg1 + 360
+ IF deg2 <= 0 THEN deg2 = deg2 + 360
+ IF deg3 <= 0 THEN deg3 = deg3 + 360
+
+ IF deg1 >= 360 THEN deg1 = deg1 - 360
+ IF deg2 >= 360 THEN deg2 = deg2 - 360
+ IF deg3 >= 360 THEN deg3 = deg3 - 360
+
+ ' sine and cosine values lookup
+ c1& = cosine&(deg1)
+ s1& = sine&(deg1)
+ c2& = cosine&(deg2)
+ s2& = sine&(deg2)
+ c3& = cosine&(deg3)
+ S3& = sine&(deg3)
+
+ ' Updating tank position
+ myx = myx - (s1& * speed / 100)
+ myy = myy - (c1& * speed / 100)
+ myz = myz - (s2& * speed / 100)
+
+ ' Rotating points
+ FOR a = 0 TO np - 1
+ x1 = pointX(a) + myx
+ y1 = pointY(a) + myz
+ pz1 = pointZ(a) + myy
+
+ ' Applying rotation matrix
+ x2 = (x1 * c1& - pz1 * s1&) \ 1024
+ pz2 = (x1 * s1& + pz1 * c1&) \ 1024
+
+ y2 = (y1 * c2& - pz2 * s2&) \ 1024
+ pz3 = (y1 * s2& + pz2 * c2&) \ 1024
+
+ x3 = (y2 * c3& - x2 * S3&) \ 1024
+ y3 = (y2 * S3& + x2 * c3&) \ 1024
+
+ ' Checking if point is within view
+ IF pz3 > 10 THEN
+ xn(a) = 320 + (x3 / pz3 * 500)
+ yn(a) = 240 + (y3 / pz3 * 500)
+ ELSE
+ xn(a) = -1
+ END IF
+ NEXT
+
+ ' Drawing lines between connected points
+ FOR a1 = 0 TO nl - 1
+ f1 = pointers1(a1)
+ s1 = pointers2(a1)
+
+ xn = xn(f1)
+ yn = yn(f1)
+
+ x1 = xn(s1)
+ y1 = yn(s1)
+
+ ' Drawing lines
+ IF Xs1(a1) = -1 OR Xe1(a1) = -1 THEN
+ ELSE
+ LINE (Xs1(a1), Ys1(a1))-(Xe1(a1), Ye1(a1)), 0
+ END IF
+
+ IF x1 = -1 OR xn = -1 THEN
+ ELSE
+ LINE (x1, y1)-(xn, yn), 15
+ END IF
+
+ ' Updating old rotated points
+ Xs1(a1) = x1
+ Ys1(a1) = y1
+
+ Xe1(a1) = xn
+ Ye1(a1) = yn
+ NEXT
+
+ ' Handling user input
+ k$ = INKEY$
+ IF k$ <> "" THEN
+
+ SELECT CASE k$
+
+ CASE CHR$(0) + "M"
+ d1 = d1 - 1
+
+ CASE CHR$(0) + "K"
+ d1 = d1 + 1
+
+ CASE CHR$(0) + "P"
+ d2 = d2 + 1
+
+ CASE CHR$(0) + "H"
+ d2 = d2 - 1
+
+ CASE "w"
+ d3 = d3 - 1
+
+ CASE "z"
+ d3 = d3 + 1
+
+ CASE "-"
+ speed = speed - 1
+
+ CASE "+"
+ speed = speed + 1
+
+ CASE " "
+ d1 = 0
+ d2 = 0
+ d3 = 0
+ speed = 0
+
+ CASE CHR$(27)
+ SYSTEM
+
+ END SELECT
+ k$ = ""
+ END IF
+LOOP
+END SUB
+
+SUB setTracks
+' Updating tank position
+Tracksxp = Tracksxp + ssu
+smes = smes + ssu
+IF smes > 15 THEN smes = 1
+IF smes < 1 THEN smes = 15
+b = smes
+
+FOR a = TracksBeginp TO TracksBeginp + 48 STEP 2
+ pointX(a) = Tracksx(b) - Tracksxp
+ pointY(a) = Tracksy(b)
+ pointZ(a) = 50
+ pointX(a + 1) = Tracksx(b) - Tracksxp
+ pointY(a + 1) = Tracksy(b)
+ pointZ(a + 1) = 30
+ b = b + 15
+NEXT a
+
+b = smes
+FOR a = TracksBeginp + 48 TO TracksBeginp + 94 STEP 2
+ pointX(a) = Tracksx(b) - Tracksxp
+ pointY(a) = Tracksy(b)
+ pointZ(a) = -50
+ pointX(a + 1) = Tracksx(b) - Tracksxp
+ pointY(a + 1) = Tracksy(b)
+ pointZ(a + 1) = -30
+ b = b + 15
+NEXT a
+
+REM Moving the tank
+FOR a = 0 TO 84
+ pointX(a) = pointX(a) - ssu
+NEXT a
+
+IF pointX(84) > 0 THEN ssu = 1
+IF pointX(83) < -400 THEN ssu = -1
+
+END SUB
+
+SUB start
+' Initializing the program
+SCREEN 12
+CLS
+speed = 0
+
+deg1 = 210
+deg2 = 20
+deg3 = 90
+
+smes = 1
+Tracksxp = 0
+
+myxp = 0
+myyp = 0
+myzp = 0
+myx = 0
+myy = -300
+myz = 100
+smes = 1
+
+ssu = 1
+
+calcsin
+
+getcor
+teemaad
+getTracks
+
+END SUB
+
+SUB teemaad
+' Adding new points and connected points
+BridgeBeginl = nl
+np = np + 0
+BridgeBeginp = np
+
+5
+READ pointX(np), pointY(np), pointZ(np)
+IF pointX(np) = 999 THEN pointX(np) = 0: pointY(np) = 0: pointZ(np) = 0: GOTO 3
+np = np + 1
+GOTO 5
+
+3
+READ pointers1(nl), pointers2(nl)
+IF pointers1(nl) = 999 THEN GOTO 4
+pointers1(nl) = pointers1(nl) + BridgeBeginp
+pointers2(nl) = pointers2(nl) + BridgeBeginp
+nl = nl + 1
+GOTO 3
+4
+
+END SUB
+++ /dev/null
-' Program to render animated 3D tank that drives back and forth on the 3D bridge.
-' Notably, tracks on the tank are properly synchronized with the tank movement.
-' User can freely look and fly around in the space.
-'
-' By Svjatoslav Agejenko.
-' Email: svjatoslav@svjatoslav.eu
-' Homepage: http://www.svjatoslav.eu
-'
-' Changelog:
-' 2000, Initial version
-' 2024, Improved program readability using AI
-
-' Use keys to move around:
-' Left, Right, Up, Down look around
-' + move forward
-' - move back
-' q quit
-' <space> - stop
-
-DECLARE SUB start ()
-DECLARE SUB savepos (x1%, y1%, x2%, y2%)
-DECLARE SUB teemaad ()
-DECLARE SUB setTracks ()
-DECLARE SUB getTracks ()
-DECLARE SUB getTracks1 (x1%, y1%, x2%, y2%)
-DECLARE SUB kiri ()
-DECLARE SUB getcor ()
-DECLARE SUB mulcor ()
-DECLARE SUB nait3d ()
-DECLARE SUB calcsin ()
-DEFINT A-Y
-DIM SHARED xn(1000), yn(1000), czn(1000) ' points transformed to on-screen coordinates
-DIM SHARED pointX(1000), pointY(1000), pointZ(1000) ' points in 3D space
-DIM SHARED Xs1(1000), Ys1(1000), Xe1(1000), Ye1(1000) ' Old rotated points
-DIM SHARED pointers1(1000), pointers2(1000) ' Connected points
-DIM SHARED cosine&(360), sine&(360) ' SIN & COS table
-DIM SHARED np, nl
-
-DIM SHARED Tracksx(1 TO 1000)
-DIM SHARED Tracksy(1 TO 1000)
-DIM SHARED mitTracks
-DIM SHARED smes
-
-' Pointers to the beginning of the tank tracks, this is needed to animate tank tracks
-DIM SHARED TracksBeginp ' point index
-DIM SHARED TracksBeginl ' line index
-
-' Pointers to the beginning of the bridge
-DIM SHARED BridgeBeginp ' point index
-DIM SHARED BridgeBeginl ' line index
-
-DIM SHARED Tracksxp
-DIM SHARED myx, myy, myz
-DIM SHARED myxp, myyp, myzp
-
-DIM SHARED deg1, deg2, deg3
-DIM SHARED speed
-
-DIM SHARED ssu
-
-start
-
-nait3d
-
-DATA -10,-30,-20
-DATA 30,-30,-20
-DATA 30,-10,-20
-DATA -10,-10,-20
-
-DATA -10,-30,20
-DATA 30,-30,20
-DATA 30,-10,20
-DATA -10,-10,20
-
-DATA -10,-40,-15
-DATA 30,-40,-15
-DATA -10,-40,15
-DATA 30,-40,15
-
-DATA -20,-30,-15
-DATA -20,-30, 15
-
-DATA -70,-10,-50
-DATA 60,-10, -50
-DATA 70, 0, -50
-DATA 70, 20, -50
-DATA 60, 30, -50
-DATA -70,30, -50
-DATA -80,20, -50
-DATA -80, 0, -50
-
-DATA -70,-10,-30
-DATA 60,-10, -30
-DATA 70, 0, -30
-DATA 70, 20, -30
-DATA 60, 30, -30
-DATA -70,30, -30
-DATA -80,20, -30
-DATA -80, 0, -30
-
-DATA -70,-10, 50
-DATA 60,-10, 50
-DATA 70, 0, 50
-DATA 70, 20, 50
-DATA 60, 30, 50
-DATA -70,30, 50
-DATA -80,20, 50
-DATA -80, 0, 50
-
-DATA -70,-10, 30
-DATA 60,-10, 30
-DATA 70, 0, 30
-DATA 70, 20, 30
-DATA 60, 30, 30
-DATA -70,30, 30
-DATA -80,20, 30
-DATA -80, 0, 30
-
-DATA -50,-7,-30
-DATA 50,-7,-30
-DATA 50, 15,-30
-DATA -50, 15,-30
-
-DATA -50,-7, 30
-DATA 50,-7, 30
-DATA 50, 15,30
-DATA -50, 15,30
-
-DATA -20,-20,-5
-DATA -20,-20, 5
-DATA -20,-30, 5
-DATA -20,-30,-5
-
-DATA -100,-30,-5
-DATA -100,-30, 5
-DATA -100,-40, 5
-DATA -100,-40,-5
-
-DATA 999,999,999
-
-DATA 0,1
-DATA 1,2
-DATA 2,3
-DATA 3,0
-
-DATA 4,5
-DATA 5,6
-DATA 6,7
-DATA 7,4
-
-DATA 0,8
-DATA 1,9
-DATA 4,10
-DATA 5,11
-
-DATA 0,12
-DATA 4,13
-DATA 12,8
-DATA 13,10
-
-DATA 8,9
-DATA 10,11
-DATA 8,10
-DATA 9,11
-
-DATA 12,13
-DATA 12,3
-DATA 13,7
-DATA 3,7
-DATA 1,5
-DATA 2,6
-
-DATA 14,15
-DATA 15,16
-DATA 16,17
-DATA 17,18
-DATA 18,19
-DATA 19,20
-DATA 20,21
-DATA 21,14
-
-DATA 22,23
-DATA 23,24
-DATA 24,25
-DATA 25,26
-DATA 26,27
-DATA 27,28
-DATA 28,29
-DATA 29,22
-
-DATA 30,31
-DATA 31,32
-DATA 32,33
-DATA 33,34
-DATA 34,35
-DATA 35,36
-DATA 36,37
-DATA 37,30
-
-DATA 38,39
-DATA 39,40
-DATA 40,41
-DATA 41,42
-DATA 42,43
-DATA 43,44
-DATA 44,45
-DATA 45,38
-
-DATA 46,47
-DATA 47,48
-DATA 48,49
-DATA 49,46
-
-DATA 50,51
-DATA 51,52
-DATA 52,53
-DATA 53,50
-
-DATA 50,46
-DATA 51,47
-DATA 52,48
-DATA 53,49
-
-DATA 54,55
-DATA 55,56
-DATA 56,57
-DATA 57,54
-
-DATA 54,58
-DATA 55,59
-DATA 56,60
-DATA 57,61
-
-DATA 58,59
-DATA 59,60
-DATA 60,61
-DATA 61,58
-
-DATA 54,3
-DATA 55,7
-
-DATA 999, 999
-' BRIDGE
-' right handlebars
-DATA 100,0,100
-DATA 100,50,100
-
-DATA 50,0,100
-DATA 50,50,100
-
-DATA 0,0,100
-DATA 0,50,100
-
-DATA -50,0,100
-DATA -50,50,100
-
-DATA -100,0,100
-DATA -100,50,100
- ' 5
-DATA -150,0,100
-DATA -150,50,100
-
-DATA -200,0,100
-DATA -200,50,100
-
-DATA -250,0,100
-DATA -250,50,100
-
-DATA -300,0,100
-DATA -300,50,100
-
-DATA -350,0,100
-DATA -350,50,100
- ' 10
-
-DATA -400,0,100
-DATA -400,50,100
-
-DATA -450,0,100
-DATA -450,50,100
-
-DATA -500,0,100
-DATA -500,50,100
-
-DATA -550,0,100
-DATA -550,50,100
-
-DATA -600,0,100
-DATA -600,50,100
-
-DATA -650,0,100
-DATA -650,50,100
-
- ' left handlebars
-DATA 100,0,-100
-DATA 100,50,-100
-
-DATA 50,0,-100
-DATA 50,50,-100
-
-DATA 0,0,-100
-DATA 0,50,-100
-
-DATA -50,0,-100
-DATA -50,50,-100
-
-DATA -100,0,-100
-DATA -100,50,-100
- ' 5
-DATA -150,0,-100
-DATA -150,50,-100
-
-DATA -200,0,-100
-DATA -200,50,-100
-
-DATA -250,0,-100
-DATA -250,50,-100
-
-DATA -300,0,-100
-DATA -300,50,-100
-
-DATA -350,0,-100
-DATA -350,50,-100
- ' 10
-
-DATA -400,0,-100
-DATA -400,50,-100
-
-DATA -450,0,-100
-DATA -450,50,-100
-
-DATA -500,0,-100
-DATA -500,50,-100
-
-DATA -550,0,-100
-DATA -550,50,-100
-
-DATA -600,0,-100
-DATA -600,50,-100
-
-DATA -650,0,-100
-DATA -650,50,-100
- ' bottom line
-DATA 100,75,-100
-DATA -650,75,-100
-
-DATA 100,75,100
-DATA -650,75,100
- ' shore
-DATA 75,75,-100
-DATA 75,75,100
- 'right
-DATA -50,200,-100
-DATA -50,200,100
-
-DATA 75,200,-190
-DATA 75,200, 190
- 'left
-DATA -525,200,-100
-DATA -525,200, 100
-
-DATA -600,200,-190
-DATA -600,200, 190
-
-'
-
-DATA 999,999,999
-
- 'right handlebars
-
-DATA 2,3
-DATA 4,5
-DATA 6,7
-DATA 8,9
-
-DATA 10,11
-DATA 12,13
-DATA 14,15
-DATA 16,17
-DATA 18,19
-
-DATA 20,21
-DATA 22,23
-DATA 24,25
-DATA 26,27
-DATA 28,29
-
-
- 'left handlebars
-DATA 34,35
-DATA 36,37
-DATA 38,39
-DATA 40,41
-
-DATA 42,43
-DATA 44,45
-DATA 46,47
-DATA 48,49
-DATA 50,51
-
-DATA 52,53
-DATA 54,55
-DATA 56,57
-DATA 58,59
-DATA 60,61
-
-' long features
-DATA 0,4
-DATA 4,8
-DATA 8,12
-DATA 12,16
-DATA 16,20
-DATA 20,24
-DATA 24,28
-DATA 28,30
-
-DATA 1,5
-DATA 5,9
-DATA 9,13
-DATA 13,17
-DATA 17,21
-DATA 21,25
-DATA 25,29
-DATA 29,31
-
-DATA 32,36
-DATA 36,40
-DATA 40,44
-DATA 44,48
-DATA 48,52
-DATA 52,56
-DATA 56,60
-DATA 60,62
-
-DATA 33,37
-DATA 37,41
-DATA 41,45
-DATA 45,49
-DATA 49,53
-DATA 53,57
-DATA 57,61
-DATA 61,63
-
-'
-
-' end
-
-DATA 1,33
-DATA 31,63
-
-DATA 64,65
-DATA 66,67
-DATA 64,66
-DATA 65,67
-
-DATA 0,66
-DATA 32,64
-DATA 30,67
-DATA 62,65
- ' shore
-DATA 68,69
-DATA 70,71
-DATA 68,70
-DATA 69,71
-
-DATA 72,70
-DATA 72,68
-
-DATA 73,71
-DATA 73,69
- 'left
-DATA 74,76
-DATA 75,77
-DATA 74,75
-
-DATA 74,65
-DATA 76,65
-
-DATA 75,67
-DATA 77,67
-
-DATA 999, 999
-
-DEFINT Z
-SUB calcsin
-' precalculating sine and cosine tables
-
-FOR a! = 0 TO 359 / 57.29577951# STEP 1 / 57.29577951#
- cosine&(a) = INT(.5 + COS(a!) * 1024)
- sine&(a) = INT(.5 + SIN(a!) * 1024)
- a = a + 1
-NEXT
-CLS
-END SUB
-
-DEFSNG Z
-SUB getcor
-' Loading original points and connected points
-FOR a = 0 TO 10000
- READ pointX(a), pointY(a), pointZ(a)
- IF pointX(a) = 999 THEN pointX(a) = 0: pointY(a) = 0: pointZ(a) = 0: GOTO 1
-NEXT
-1
-np = a
-FOR a = 0 TO 10000
- READ pointers1(a), pointers2(a)
- IF pointers1(a) = 999 THEN GOTO 2
-NEXT
-2
-nl = a
-
-TracksBeginp = np
-TracksBeginl = nl
-
-' Initializing connected points
-FOR a = 1 TO 48
-pointers1(nl) = np
-np = np + 1
-pointers2(nl) = np
-np = np + 1
-nl = nl + 1
-NEXT a
-
-END SUB
-
-DEFINT Z
-SUB getTracks
-
-' Initialize the number of segments
-mitTracks = 1
-getTracks1 -70, -10, -80, 0
-getTracks1 -80, 0, -80, 20
-getTracks1 -80, 20, -70, 30
-getTracks1 -70, 30, 60, 30
-getTracks1 60, 30, 70, 20
-getTracks1 70, 20, 70, 0
-getTracks1 70, 0, 60, -10
-getTracks1 60, -10, -70, -10
-
-END SUB
-
-DEFSNG Z
-SUB getTracks1 (x1%, y1%, x2%, y2%)
-REM Calculating points for a segment
-z1 = ABS(x1 - x2)
-z2 = ABS(y2 - y1)
-mi = SQR(z1 ^ 2 + z2 ^ 2) * 1.017142857#
-
-' Calculating direction vectors
-zxp = (x1 - x2) / mi
-zyp = (y2 - y1) / mi
-zx = x1
-zy = y1
-
-FOR a = 1 TO mi
- zx = zx - zxp
- zy = zy + zyp
- Tracksx(mitTracks) = zx
- Tracksy(mitTracks) = zy
- mitTracks = mitTracks + 1
-NEXT a
-
-END SUB
-
-
-
-DEFSNG Z
-SUB nait3d
-' Main loop to render the scene
-DO
-
- setTracks
-
- ' Updating rotation angles
- deg1 = deg1 + d1
- deg2 = deg2 + d2
- deg3 = deg3 + d3
-
- ' Normalizing angles
- IF deg1 <= 0 THEN deg1 = deg1 + 360
- IF deg2 <= 0 THEN deg2 = deg2 + 360
- IF deg3 <= 0 THEN deg3 = deg3 + 360
-
- IF deg1 >= 360 THEN deg1 = deg1 - 360
- IF deg2 >= 360 THEN deg2 = deg2 - 360
- IF deg3 >= 360 THEN deg3 = deg3 - 360
-
- ' sine and cosine values lookup
- c1& = cosine&(deg1)
- s1& = sine&(deg1)
- c2& = cosine&(deg2)
- s2& = sine&(deg2)
- c3& = cosine&(deg3)
- S3& = sine&(deg3)
-
- ' Updating tank position
- myx = myx - (s1& * speed / 100)
- myy = myy - (c1& * speed / 100)
- myz = myz - (s2& * speed / 100)
-
- ' Rotating points
- FOR a = 0 TO np - 1
- x1 = pointX(a) + myx
- y1 = pointY(a) + myz
- pz1 = pointZ(a) + myy
-
- ' Applying rotation matrix
- x2 = (x1 * c1& - pz1 * s1&) \ 1024
- pz2 = (x1 * s1& + pz1 * c1&) \ 1024
-
- y2 = (y1 * c2& - pz2 * s2&) \ 1024
- pz3 = (y1 * s2& + pz2 * c2&) \ 1024
-
- x3 = (y2 * c3& - x2 * S3&) \ 1024
- y3 = (y2 * S3& + x2 * c3&) \ 1024
-
- ' Checking if point is within view
- IF pz3 > 10 THEN
- xn(a) = 320 + (x3 / pz3 * 500)
- yn(a) = 240 + (y3 / pz3 * 500)
- ELSE
- xn(a) = -1
- END IF
- NEXT
-
- ' Drawing lines between connected points
- FOR a1 = 0 TO nl - 1
- f1 = pointers1(a1)
- s1 = pointers2(a1)
-
- xn = xn(f1)
- yn = yn(f1)
-
- x1 = xn(s1)
- y1 = yn(s1)
-
- ' Drawing lines
- IF Xs1(a1) = -1 OR Xe1(a1) = -1 THEN
- ELSE
- LINE (Xs1(a1), Ys1(a1))-(Xe1(a1), Ye1(a1)), 0
- END IF
-
- IF x1 = -1 OR xn = -1 THEN
- ELSE
- LINE (x1, y1)-(xn, yn), 15
- END IF
-
- ' Updating old rotated points
- Xs1(a1) = x1
- Ys1(a1) = y1
-
- Xe1(a1) = xn
- Ye1(a1) = yn
- NEXT
-
- ' Handling user input
- k$ = INKEY$
- IF k$ <> "" THEN
-
- SELECT CASE k$
-
- CASE CHR$(0) + "M"
- d1 = d1 - 1
-
- CASE CHR$(0) + "K"
- d1 = d1 + 1
-
- CASE CHR$(0) + "P"
- d2 = d2 + 1
-
- CASE CHR$(0) + "H"
- d2 = d2 - 1
-
- CASE "w"
- d3 = d3 - 1
-
- CASE "z"
- d3 = d3 + 1
-
- CASE "-"
- speed = speed - 1
-
- CASE "+"
- speed = speed + 1
-
- CASE " "
- d1 = 0
- d2 = 0
- d3 = 0
- speed = 0
-
- CASE CHR$(27)
- SYSTEM
-
- END SELECT
- k$ = ""
- END IF
-LOOP
-END SUB
-
-SUB setTracks
-' Updating tank position
-Tracksxp = Tracksxp + ssu
-smes = smes + ssu
-IF smes > 15 THEN smes = 1
-IF smes < 1 THEN smes = 15
-b = smes
-
-FOR a = TracksBeginp TO TracksBeginp + 48 STEP 2
- pointX(a) = Tracksx(b) - Tracksxp
- pointY(a) = Tracksy(b)
- pointZ(a) = 50
- pointX(a + 1) = Tracksx(b) - Tracksxp
- pointY(a + 1) = Tracksy(b)
- pointZ(a + 1) = 30
- b = b + 15
-NEXT a
-
-b = smes
-FOR a = TracksBeginp + 48 TO TracksBeginp + 94 STEP 2
- pointX(a) = Tracksx(b) - Tracksxp
- pointY(a) = Tracksy(b)
- pointZ(a) = -50
- pointX(a + 1) = Tracksx(b) - Tracksxp
- pointY(a + 1) = Tracksy(b)
- pointZ(a + 1) = -30
- b = b + 15
-NEXT a
-
-REM Moving the tank
-FOR a = 0 TO 84
- pointX(a) = pointX(a) - ssu
-NEXT a
-
-IF pointX(84) > 0 THEN ssu = 1
-IF pointX(83) < -400 THEN ssu = -1
-
-END SUB
-
-SUB start
-' Initializing the program
-SCREEN 12
-CLS
-speed = 0
-
-deg1 = 210
-deg2 = 20
-deg3 = 90
-
-smes = 1
-Tracksxp = 0
-
-myxp = 0
-myyp = 0
-myzp = 0
-myx = 0
-myy = -300
-myz = 100
-smes = 1
-
-ssu = 1
-
-calcsin
-
-getcor
-teemaad
-getTracks
-
-END SUB
-
-SUB teemaad
-' Adding new points and connected points
-BridgeBeginl = nl
-np = np + 0
-BridgeBeginp = np
-
-5
-READ pointX(np), pointY(np), pointZ(np)
-IF pointX(np) = 999 THEN pointX(np) = 0: pointY(np) = 0: pointZ(np) = 0: GOTO 3
-np = np + 1
-GOTO 5
-
-3
-READ pointers1(nl), pointers2(nl)
-IF pointers1(nl) = 999 THEN GOTO 4
-pointers1(nl) = pointers1(nl) + BridgeBeginp
-pointers2(nl) = pointers2(nl) + BridgeBeginp
-nl = nl + 1
-GOTO 3
-4
-
-END SUB