-' 3D heightmap explorer. Allows to visualize heightmap for arbitrary formula.\r
+DECLARE SUB formula (x!, y!, z!)\r
+DECLARE SUB graaf ()\r
+DECLARE SUB mkgr3 (x1!, y1!, z1!)\r
+DECLARE SUB mkgr2 (x1!, y1!, z1!)\r
+DECLARE SUB mkgr (x1!, y1!, z1!)\r
+DECLARE SUB start ()\r
+DECLARE SUB getcor ()\r
+DECLARE SUB nait3d ()\r
+' 3D heightmap explorer. Allows to visualize heightmap for arbitrary function.\r
+' Inspect and edit function "formula" to visualize alternative mathematical functions.\r
+\r
' By Svjatoslav Agejenko.\r
' Email: svjatoslav@svjatoslav.eu\r
' Homepage: http://www.svjatoslav.eu\r
-'\r
+\r
' Changelog:\r
' 2002, Initial version\r
' 2024.09, Improved program readability using AI\r
' + - fly down\r
' ESC - exit program\r
\r
-' Type your formula to sub module "valem".\r
+' Type your formula to sub module "formula".\r
' X & Y are surface coordinates. Z must be formula\r
' result, indicating height. "tm" variable counts\r
' frames. Use it in your formula to make graph moving in time.\r
\r
-DECLARE SUB valem (x!, y!, z!)\r
-DECLARE SUB graaf ()\r
-DECLARE SUB mkgr3 (x1!, y1!, z1!)\r
-DECLARE SUB mkgr2 (x1!, y1!, z1!)\r
-DECLARE SUB mkgr (x1!, y1!, z1!)\r
-DECLARE SUB ruut2 (x!, y!, z!, s!)\r
-DECLARE SUB ruut (x!, y!, z!, s!)\r
-DECLARE SUB kuus (x, y, z, s)\r
-DECLARE SUB porand ()\r
-DECLARE SUB addp (x, y, z)\r
-DECLARE SUB start ()\r
-DECLARE SUB addsq (x1%, y1%, z1%)\r
-DECLARE SUB getcor ()\r
-DECLARE SUB mulcor ()\r
-DECLARE SUB nait3d ()\r
-DECLARE SUB calcsin ()\r
DIM SHARED vertexX(4000), vertexY(4000), vertexZ(4000)\r
DIM SHARED x(4000), y(4000), z(4000)\r
\r
PRINT "Kuskil programmis l�ks mingi arv �le lubatud piiride!!!"\r
RESUME\r
\r
+' This subroutine initializes the coordinate system and sets up the grid.\r
SUB getcor\r
c = 12\r
\r
+ ' Create background 2D grids along every axis in 3D space\r
+ ' to help viewer perceive scale.\r
mkgr -500, 0, 0\r
mkgr2 0, 0, 500\r
mkgr3 0, -500, 0\r
\r
+ ' Place center-crossing pink lines across every axis (3D cross).\r
+ ' This is to help viewer to see where zero point on the graph is.\r
+\r
+ ' Add vertices for the 3D cross.\r
vertexX(vertexCount + 1) = 0\r
vertexY(vertexCount + 1) = -500\r
vertexZ(vertexCount + 1) = 0\r
vertexY(vertexCount + 6) = 0\r
vertexZ(vertexCount + 6) = 500\r
\r
+ ' Add lines for the 3D cross.\r
linePoint1(lineCount + 1) = vertexCount + 1\r
linePoint2(lineCount + 1) = vertexCount + 2\r
lineColor(lineCount + 1) = c\r
linePoint2(lineCount + 3) = vertexCount + 6\r
lineColor(lineCount + 3) = c\r
\r
+ ' Update the vertex and line counts\r
vertexCount = vertexCount + 6\r
lineCount = lineCount + 3\r
tmvertexCount = vertexCount\r
tmlineCount = lineCount\r
END SUB\r
\r
+' This subroutine generates a grid of points based on the formula\r
SUB graaf\r
c = 14\r
\r
FOR x = -500 TO 500 STEP 50\r
FOR z = -500 TO 500 STEP 50\r
\r
+ ' Increment the vertex count and add a new vertex\r
d = d + 1\r
vertexX(vertexCount + d) = x\r
- valem x / 50, z / 50, y\r
+ formula x / 50, z / 50, y ' evaluate formula that we want to visualize\r
vertexY(vertexCount + d) = y * 50\r
vertexZ(vertexCount + d) = z\r
\r
+ ' Connect current point on the grid with neighbors\r
IF z > -500 THEN\r
e = e + 1\r
linePoint1(lineCount + e) = vertexCount + d\r
NEXT z\r
NEXT x\r
\r
+ ' Update the vertex and line counts\r
vertexCount = vertexCount + d\r
lineCount = lineCount + e\r
END SUB\r
\r
+' This subroutine generates a measuring grid in the ZY plane.\r
SUB mkgr (x1, y1, z1)\r
c = 3\r
\r
FOR z = -500 TO 500 STEP 100\r
FOR y = -500 TO 500 STEP 100\r
\r
+ ' Increment the vertex count and add a new vertex\r
d = d + 1\r
vertexX(vertexCount + d) = x1\r
vertexY(vertexCount + d) = y1 + y\r
vertexZ(vertexCount + d) = z1 + z\r
\r
+ ' Add lines to the line array if necessary\r
IF y > -500 THEN\r
e = e + 1\r
linePoint1(lineCount + e) = vertexCount + d\r
NEXT y\r
NEXT z\r
\r
+ ' Update the vertex and line counts\r
vertexCount = vertexCount + d\r
lineCount = lineCount + e\r
END SUB\r
\r
+' This subroutine generates a measuring grid XY plane.\r
SUB mkgr2 (x1, y1, z1)\r
c = 3\r
\r
FOR x = -500 TO 500 STEP 100\r
FOR y = -500 TO 500 STEP 100\r
\r
+ ' Increment the vertex count and add a new vertex\r
d = d + 1\r
vertexX(vertexCount + d) = x1 + x\r
vertexY(vertexCount + d) = y1 + y\r
vertexZ(vertexCount + d) = z1\r
\r
+ ' Add lines to the line array if necessary\r
IF y > -500 THEN\r
e = e + 1\r
linePoint1(lineCount + e) = vertexCount + d\r
NEXT y\r
NEXT x\r
\r
+ ' Update the vertex and line counts\r
vertexCount = vertexCount + d\r
lineCount = lineCount + e\r
END SUB\r
\r
+' This subroutine generates a measuring grid in the XZ plane.\r
SUB mkgr3 (x1, y1, z1)\r
c = 3\r
\r
FOR x = -500 TO 500 STEP 100\r
FOR z = -500 TO 500 STEP 100\r
\r
+ ' Increment the vertex count and add a new vertex\r
d = d + 1\r
vertexX(vertexCount + d) = x1 + x\r
vertexY(vertexCount + d) = y1\r
vertexZ(vertexCount + d) = z\r
\r
+ ' Add lines to the line array if necessary\r
IF z > -500 THEN\r
e = e + 1\r
linePoint1(lineCount + e) = vertexCount + d\r
NEXT z\r
NEXT x\r
\r
+ ' Update the vertex and line counts\r
vertexCount = vertexCount + d\r
lineCount = lineCount + e\r
END SUB\r
\r
+' This subroutine renders the 3D scene.\r
SUB nait3d\r
\r
1\r
C1 = COS(deg1): S1 = SIN(deg1)\r
C2 = COS(Deg2): S2 = SIN(Deg2)\r
\r
+' Transform the vertices to 3D space\r
FOR a = 1 TO vertexCount\r
\r
xo = vertexX(a) - myx\r
yo = -vertexY(a) - myy\r
zo = vertexZ(a) - myz\r
\r
+ ' Apply rotation transformations\r
x1 = (xo * C1 - zo * S1)\r
z1 = (xo * S1 + zo * C1)\r
\r
y1 = (yo * C2 - z1 * S2)\r
z2 = (yo * S2 + z1 * C2)\r
\r
+ ' Project the vertices onto the 2D screen\r
xo(a) = x(a)\r
yo(a) = y(a)\r
\r
END IF\r
NEXT\r
\r
+' Draw the lines on the screen\r
FOR a = 1 TO lineCount\r
p1 = linePoint1(a)\r
p2 = linePoint2(a)\r
\r
+ ' Skip drawing if either point is off-screen\r
IF xo(p1) = -1 OR xo(p2) = -1 THEN\r
' Do nothing\r
ELSE\r
+ ' erase line at previous position\r
LINE (xo(p1), yo(p1))-(xo(p2), yo(p2)), 0\r
+ ' draw line at new position\r
LINE (x(p1), y(p1))-(x(p2), y(p2)), lineColor(a)\r
END IF\r
\r
NEXT\r
\r
+' Handle keyboard input\r
K$ = INKEY$\r
IF K$ <> "" THEN\r
\r
END SELECT\r
END IF\r
\r
-\r
GOTO 1\r
END SUB\r
\r
+' This subroutine initializes the graphics and sets up the program.\r
SUB start\r
SCREEN 12\r
CLS\r
\r
END SUB\r
\r
-SUB valem (x, y, z)\r
+' This subroutine calculates the height of a point based on the formula\r
+SUB formula (x, y, z)\r
z = 0\r
-v = SQR(x * x + y * y) ' v = distance from center, some formulas needs it.\r
+v = SQR(x * x + y * y) ' v = distance from center, some formulas need it.\r
\r
+' Apply the formula to calculate the height\r
z = z + SIN(x + y) * SIN(tm / 10) ' diagonal lines\r
z = z + (SQR((15 + v) * (15 - v)) - 10) ' top of the ball\r
-' here I mixed 2 formulas.\r
-\r
-'z = z + RND * 1 ' noise\r
-'z = z + SIN((y + tm) / 2) ' forward moving wave\r
-'z = z + SIN(v / 2) * 2 ' circular waves\r
-'z = z - SQR(v * 6) ' sharp\r
-\r
-'z = z + SIN(y / 1.5) / 1.5 + COS(x / 1.5) / 1.5' custom 1\r
-'z = z + SIN(y / 1.5) * COS(x / 1.5) / 1.5 ' custom 2\r
-'z = z + INT(SIN(1.5 * x * SIN(tm / 10))) * 3 ' custom 3\r
-'z = z - INT(v / 5) * 3 + 3 ' custom 4\r
-'z = z + 3 * ((-INT((x - .3) / 20) * INT((23 + x - ABS(y * 1.2)) / 15)) + -INT(-y / 20) * -INT(-x / 20) * INT(-((x - 2) * (x - 2) + (y * 1.2 - 4) * (y * 1.2 - 4)) / 2000 + 1.01) + -INT(y / 20) * -INT(-x / 20) * INT(-((x - 2) * (x - 2) + (y * 1.2 + 4) * (y * 1.2 + 4)) / 2000 + 1.01)) ' heart\r
+\r
+' As you see, multiple formulas can be enabled simultaneously.\r
+' Few more example formulas that you can uncomment and enable.\r
+' z = z + RND * 1 ' noise\r
+' z = z + SIN((y + tm) / 2) ' forward moving wave\r
+' z = z + SIN(v / 2) * 2 ' circular waves\r
+' z = z - SQR(v * 6) ' sharp peak\r
+' z = z + SIN(y / 1.5) / 1.5 + COS(x / 1.5) / 1.5' custom 1\r
+' z = z + SIN(y / 1.5) * COS(x / 1.5) / 1.5 ' custom 2\r
+' z = z + INT(SIN(1.5 * x * SIN(tm / 10))) * 3 ' custom 3\r
+' z = z - INT(v / 5) * 3 + 3 ' custom 4\r
+' z = z + 3 * ((-INT((x - .3) / 20) * INT((23 + x - ABS(y * 1.2)) / 15)) + -INT(-y / 20) * -INT(-x / 20) * INT(-((x - 2) * (x - 2) + (y * 1.2 - 4) * (y * 1.2 - 4)) / 2000 + 1.01) + -INT(y / 20) * -INT(-x / 20) * INT(-((x - 2) * (x - 2) + (y * 1.2 + 4) * (y * 1.2 + 4)) / 2000 + 1.01)) ' heart\r
\r
END SUB\r
\r