Author Topic: Sanctum: Open world 3D engine using CIRCLE and LINE  (Read 4250 times)

0 Members and 1 Guest are viewing this topic.

Offline keybone

  • Forum Regular
  • Posts: 116
  • My name a Nursultan Tulyakbay.
Re: Sanctum: Open world 3D engine using CIRCLE and LINE
« Reply #15 on: February 05, 2019, 12:02:43 am »
hi res... but something still isnt working right. :D anyways kinda looks like the matrix or something.
maybe a monochrome monitor from the 80s. lol

Code: QB64: [Select]
  1. TYPE aGrayscale
  2.     Black AS _UNSIGNED LONG
  3.     Darkest AS _UNSIGNED LONG
  4.     Darker AS _UNSIGNED LONG
  5.     Dark AS _UNSIGNED LONG
  6.     Neutral AS _UNSIGNED LONG
  7.     Light AS _UNSIGNED LONG
  8.     Lighter AS _UNSIGNED LONG
  9.     Lightest AS _UNSIGNED LONG
  10.     White AS _UNSIGNED LONG
  11.  
  12. TYPE aPrimaryColour
  13.     Red AS _UNSIGNED LONG
  14.     Green AS _UNSIGNED LONG
  15.     Blue AS _UNSIGNED LONG
  16.  
  17. TYPE aSecondaryColour
  18.     Cyan AS _UNSIGNED LONG
  19.     Magenta AS _UNSIGNED LONG
  20.     Yellow AS _UNSIGNED LONG
  21.  
  22. TYPE aTertiaryColour
  23.     Azure AS _UNSIGNED LONG
  24.     Violet AS _UNSIGNED LONG
  25.     Rose AS _UNSIGNED LONG
  26.     Orange AS _UNSIGNED LONG
  27.     Chartreuse AS _UNSIGNED LONG
  28.     springGreen AS _UNSIGNED LONG
  29.  
  30. TYPE aCompositeColour
  31.     Brown AS _UNSIGNED LONG
  32.  
  33. TYPE aColourShade
  34.     Red AS _UNSIGNED LONG
  35.     Green AS _UNSIGNED LONG
  36.     Blue AS _UNSIGNED LONG
  37.     Cyan AS _UNSIGNED LONG
  38.     Magenta AS _UNSIGNED LONG
  39.     Yellow AS _UNSIGNED LONG
  40.     Azure AS _UNSIGNED LONG
  41.     Violet AS _UNSIGNED LONG
  42.     Rose AS _UNSIGNED LONG
  43.     Orange AS _UNSIGNED LONG
  44.     Chartreuse AS _UNSIGNED LONG
  45.     springGreen AS _UNSIGNED LONG
  46.     Brown AS _UNSIGNED LONG
  47.  
  48. TYPE aColourTint
  49.     Red AS _UNSIGNED LONG
  50.     Green AS _UNSIGNED LONG
  51.     Blue AS _UNSIGNED LONG
  52.     Cyan AS _UNSIGNED LONG
  53.     Magenta AS _UNSIGNED LONG
  54.     Yellow AS _UNSIGNED LONG
  55.     Azure AS _UNSIGNED LONG
  56.     Violet AS _UNSIGNED LONG
  57.     Rose AS _UNSIGNED LONG
  58.     Orange AS _UNSIGNED LONG
  59.     Chartreuse AS _UNSIGNED LONG
  60.     springGreen AS _UNSIGNED LONG
  61.     Brown AS _UNSIGNED LONG
  62.  
  63. TYPE aPalette
  64.     Grayscale AS aGrayscale
  65.     Primary AS aPrimaryColour
  66.     Secondary AS aSecondaryColour
  67.     Tertiary AS aTertiaryColour
  68.     Composite AS aCompositeColour
  69.     Shade AS aColourShade
  70.     Tint AS aColourTint
  71.  
  72. ' Declare RGB Colors (Primary, Secondary, and Tertiary)
  73. DIM SHARED thePalette AS aPalette
  74.  
  75. ' Initialize Grayscales (8 Brightnesses)
  76. thePalette.Grayscale.Black = _RGBA32(0, 0, 0, 255)
  77. thePalette.Grayscale.Darkest = _RGBA32(31, 31, 31, 255)
  78. thePalette.Grayscale.Darker = _RGBA32(63, 63, 63, 255)
  79. thePalette.Grayscale.Dark = _RGBA32(95, 95, 95, 255)
  80. thePalette.Grayscale.Neutral = _RGBA32(127, 127, 127, 255)
  81. thePalette.Grayscale.Light = _RGBA32(159, 159, 159, 255)
  82. thePalette.Grayscale.Lighter = _RGBA32(191, 191, 191, 255)
  83. thePalette.Grayscale.Lightest = _RGBA32(223, 223, 223, 255)
  84. thePalette.Grayscale.White = _RGBA32(255, 255, 255, 255)
  85.  
  86. ' Initialize Colors (Primary, Secondary, and Tertiary)
  87. thePalette.Primary.Red = _RGBA32(127, 0, 0, 255)
  88. thePalette.Primary.Green = _RGBA32(0, 127, 0, 255)
  89. thePalette.Primary.Blue = _RGBA32(0, 0, 127, 255)
  90. thePalette.Secondary.Cyan = _RGBA32(0, 91, 117, 255)
  91. thePalette.Secondary.Magenta = _RGBA32(101, 15, 61, 255)
  92. thePalette.Secondary.Yellow = _RGBA32(127, 127, 0, 255)
  93. thePalette.Tertiary.Azure = _RGBA32(0, 63, 127, 255)
  94. thePalette.Tertiary.Violet = _RGBA32(63, 0, 127, 255)
  95. thePalette.Tertiary.Rose = _RGBA32(127, 51, 102, 255)
  96. thePalette.Tertiary.springGreen = _RGBA32(83, 126, 0, 255)
  97. thePalette.Tertiary.Orange = _RGBA32(127, 63, 0, 255)
  98. thePalette.Tertiary.Chartreuse = _RGBA32(111, 127, 0, 255)
  99. thePalette.Composite.Brown = _RGBA32(75, 37, 0, 255)
  100.  
  101. ' Initialize Shades
  102.  
  103. thePalette.Shade.Red = _RGBA32(63, 0, 0, 255)
  104. thePalette.Shade.Green = _RGBA32(0, 63, 0, 255)
  105. thePalette.Shade.Blue = _RGBA32(0, 0, 63, 255)
  106. thePalette.Shade.Cyan = _RGBA32(0, 45, 58, 255)
  107. thePalette.Shade.Magenta = _RGBA32(50, 7, 30, 255)
  108. thePalette.Shade.Yellow = _RGBA32(63, 63, 0, 255)
  109. thePalette.Shade.Azure = _RGBA32(0, 31, 63, 255)
  110. thePalette.Shade.Violet = _RGBA32(31, 0, 63, 255)
  111. thePalette.Shade.Rose = _RGBA32(63, 25, 51, 255)
  112. thePalette.Shade.springGreen = _RGBA32(41, 63, 0, 255)
  113. thePalette.Shade.Orange = _RGBA32(63, 31, 0, 255)
  114. thePalette.Shade.Chartreuse = _RGBA32(55, 63, 0, 255)
  115. thePalette.Shade.Brown = _RGBA32(37, 17, 0, 255)
  116.  
  117. ' Initialize Tints
  118.  
  119. thePalette.Tint.Red = _RGBA32(191, 0, 0, 255)
  120. thePalette.Tint.Green = _RGBA32(0, 191, 0, 255)
  121. thePalette.Tint.Blue = _RGBA32(0, 0, 191, 255)
  122. thePalette.Tint.Cyan = _RGBA32(0, 138, 167, 255)
  123. thePalette.Tint.Magenta = _RGBA32(150, 23, 93, 255)
  124. thePalette.Tint.Yellow = _RGBA32(191, 191, 0, 255)
  125. thePalette.Tint.Azure = _RGBA32(0, 95, 191, 255)
  126. thePalette.Tint.Violet = _RGBA32(95, 0, 191, 255)
  127. thePalette.Tint.Rose = _RGBA32(191, 77, 153, 255)
  128. thePalette.Tint.springGreen = _RGBA32(126, 190, 0, 255)
  129. thePalette.Tint.Orange = _RGBA32(191, 95, 0, 255)
  130. thePalette.Tint.Chartreuse = _RGBA32(168, 191, 0, 255)
  131. thePalette.Tint.Brown = _RGBA32(113, 57, 0, 255)
  132.  
  133.  
  134.  
  135. '#lang "qb"
  136.  
  137. ' Video.
  138. screenwidth = _DESKTOPWIDTH
  139. screenheight = _DESKTOPHEIGHT
  140. SCREEN _NEWIMAGE(screenwidth, screenheight, 32)
  141.  
  142. ' Memory.
  143. DIM bignumber AS LONG
  144. bignumber = 3000000
  145. DIM numparticleorig AS LONG
  146. numparticleorig = bignumber
  147. numparticlevisible = bignumber
  148. numgroupvisible = 0
  149.  
  150. ' Structure to store groups of particles.
  151. TYPE GroupElement
  152.     Identity AS LONG
  153.     Pointer AS LONG
  154.     Lagger AS LONG
  155.     ContentName AS STRING * 25
  156.     FirstParticle AS LONG
  157.     LastParticle AS LONG
  158.     COMx AS SINGLE
  159.     COMy AS SINGLE
  160.     COMz AS SINGLE
  161. DIM VectorGroup(bignumber / 10) AS GroupElement
  162.  
  163. ' Constant(s).
  164. pi = 3.1415926536
  165. ee = 2.7182818285
  166.  
  167. ' Camera orientation vectors.
  168. DIM uhat(1 TO 3), vhat(1 TO 3), nhat(1 TO 3)
  169.  
  170. ' Clipping planes.
  171. DIM nearplane(1 TO 4), farplane(1 TO 4), rightplane(1 TO 4), leftplane(1 TO 4), topplane(1 TO 4), bottomplane(1 TO 4)
  172.  
  173. ' Basis vectors defined in xyz three-space.
  174. DIM xhat(1 TO 4), yhat(1 TO 4), zhat(1 TO 4)
  175. xhat(1) = 1: xhat(2) = 0: xhat(3) = 0: xhat(4) = 4
  176. yhat(1) = 0: yhat(2) = 1: yhat(3) = 0: yhat(4) = 2
  177. zhat(1) = 0: zhat(2) = 0: zhat(3) = 1: zhat(4) = 1
  178.  
  179. ' Basis vectors projected in uv two-space.
  180. DIM xhatp(1 TO 2), yhatp(1 TO 2), zhatp(1 TO 2)
  181.  
  182. ' Particle vectors defined in xyz three-space.
  183. DIM vecgroupname(bignumber / 10) AS STRING
  184. DIM vecorig(numparticleorig, 3)
  185. DIM vecorigvel(numparticleorig, 3)
  186. DIM vecorigacc(numparticleorig, 3)
  187. DIM veccolor(numparticleorig)
  188. DIM vec(numparticleorig, 3)
  189. DIM vecvisible(numparticlevisible, 4)
  190.  
  191. ' Particle vectors projected in uv two-space.
  192. DIM vecpuv(numparticleorig, 1 TO 2)
  193. DIM vecvisiblepuv(numparticlevisible, 1 TO 2)
  194.  
  195. ' Particle projections adjusted for screen uv two-space.
  196. DIM vecpuvs(numparticleorig, 1 TO 2)
  197. DIM vecvisiblepuvs(numparticlevisible, 1 TO 2)
  198.  
  199. ' State.
  200. nearplane(4) = 1
  201. farplane(4) = -500
  202. rightplane(4) = 0 '*' fovd * (nhat(1) * rightplane(1) + nhat(2) * rightplane(2) + nhat(3) * rightplane(3))
  203. leftplane(4) = 0
  204. topplane(4) = 0
  205. bottomplane(4) = 0
  206. centerx = screenwidth / 2
  207. centery = screenheight / 2
  208. fovd = -256
  209. '
  210. numparticleorig = 0
  211. numparticlevisible = 0
  212. particleindex = 0
  213. vecgroupcounter = 0
  214. vecgroupindex = 0
  215.  
  216. '
  217. speeddamp = 1 / 66 ' Rotation damper.
  218. speedboost = 3.0 ' Linear boost.
  219. timevar = 0
  220. '
  221. uhat(1) = -.2078192: uhat(2) = -.9781672: uhat(3) = 0
  222. vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
  223. camx = -42
  224. camy = 28
  225. camz = 40
  226. '
  227. toggletimeanimate = 1
  228. toggleinvertmouse = -1
  229. togglehud = 1
  230.  
  231. ' Prime main loop.
  232. GOSUB initialize.objects
  233. GOSUB redraw
  234.  
  235. ' Begin main loop.
  236.     IF toggletimeanimate = 1 THEN flagredraw = 1
  237.     IF flagredraw = 1 THEN
  238.         GOSUB redraw
  239.         flagredraw = -1
  240.     END IF
  241.     GOSUB mouseprocess
  242.     GOSUB keyprocess
  243.  
  244.     _DISPLAY
  245.     _KEYCLEAR
  246.     '_LIMIT 120
  247.  
  248.  
  249. ' Gosubs.
  250.  
  251. mouseprocess:
  252. mx = 0
  253. my = 0
  254.     mx = mx + _MOUSEMOVEMENTX
  255.     my = my + _MOUSEMOVEMENTY
  256.  
  257.     IF _MOUSEWHEEL > 0 THEN GOSUB rotate.clockwise
  258.     IF _MOUSEWHEEL < 0 THEN GOSUB rotate.counterclockwise
  259.     IF mx > 0 THEN
  260.         GOSUB rotate.uhat.plus: GOSUB normalize.screen.vectors
  261.     END IF
  262.     IF mx < 0 THEN
  263.         GOSUB rotate.uhat.minus: GOSUB normalize.screen.vectors
  264.     END IF
  265.     IF my > 0 THEN
  266.         IF toggleinvertmouse = -1 THEN
  267.             GOSUB rotate.vhat.plus: GOSUB normalize.screen.vectors
  268.         ELSE
  269.             GOSUB rotate.vhat.minus: GOSUB normalize.screen.vectors
  270.         END IF
  271.     END IF
  272.     IF my < 0 THEN
  273.         IF toggleinvertmouse = -1 THEN
  274.             GOSUB rotate.vhat.minus: GOSUB normalize.screen.vectors
  275.         ELSE
  276.             GOSUB rotate.vhat.plus: GOSUB normalize.screen.vectors
  277.         END IF
  278.     END IF
  279.     mx = 0
  280.     my = 0
  281.  
  282. 'MouseLB = _MOUSEBUTTON(1)
  283. 'MouseRB = _MOUSEBUTTON(2)
  284. flagredraw = 1
  285.  
  286. keyprocess:
  287. IF key$ <> "" THEN flagredraw = 1
  288.     CASE "8", CHR$(0) + CHR$(73)
  289.         GOSUB rotate.vhat.plus
  290.     CASE "2", CHR$(0) + CHR$(81)
  291.         GOSUB rotate.vhat.minus
  292.     CASE "4", CHR$(0) + CHR$(75)
  293.         GOSUB rotate.uhat.minus
  294.     CASE "6", CHR$(0) + CHR$(77)
  295.         GOSUB rotate.uhat.plus
  296.     CASE "7"
  297.         GOSUB rotate.clockwise
  298.     CASE "9"
  299.         GOSUB rotate.counterclockwise
  300.     CASE "1"
  301.         GOSUB rotate.uhat.minus: GOSUB normalize.screen.vectors: GOSUB rotate.clockwise
  302.     CASE "3"
  303.         GOSUB rotate.uhat.plus: GOSUB normalize.screen.vectors: GOSUB rotate.counterclockwise
  304.     CASE "s", CHR$(0) + CHR$(80)
  305.         GOSUB strafe.camera.nhat.plus
  306.     CASE "w", CHR$(0) + CHR$(72)
  307.         GOSUB strafe.camera.nhat.minus
  308.     CASE "d"
  309.         GOSUB strafe.camera.uhat.plus
  310.     CASE "a"
  311.         GOSUB strafe.camera.uhat.minus
  312.     CASE "e"
  313.         GOSUB strafe.camera.vhat.plus
  314.     CASE "q"
  315.         GOSUB strafe.camera.vhat.minus
  316.     CASE "x"
  317.         uhat(1) = 0: uhat(2) = 1: uhat(3) = 0
  318.         vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
  319.     CASE "X"
  320.         uhat(1) = 0: uhat(2) = -1: uhat(3) = 0
  321.         vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
  322.     CASE "y"
  323.         uhat(1) = -1: uhat(2) = 0: uhat(3) = 0
  324.         vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
  325.     CASE "Y"
  326.         uhat(1) = 1: uhat(2) = 0: uhat(3) = 0
  327.         vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
  328.     CASE "z"
  329.         uhat(1) = 1: uhat(2) = 0: uhat(3) = 0
  330.         vhat(1) = 0: vhat(2) = 1: vhat(3) = 0
  331.         GOSUB normalize.screen.vectors
  332.     CASE "Z"
  333.         uhat(1) = 0: uhat(2) = 1: uhat(3) = 0
  334.         vhat(1) = 1: vhat(2) = 0: vhat(3) = 0
  335.     CASE "]"
  336.         farplane(4) = farplane(4) - 1
  337.     CASE "["
  338.         farplane(4) = farplane(4) + 1
  339.     CASE " "
  340.         togglehud = -togglehud
  341.     CASE "t"
  342.         toggletimeanimate = -toggletimeanimate
  343.     CASE "i"
  344.         toggleinvertmouse = -toggleinvertmouse
  345.     CASE CHR$(27)
  346.         SYSTEM
  347.     CASE "f"
  348.         explodex = camx - nhat(1) * (1 - .1 * RND) * 60
  349.         explodey = camy - nhat(2) * (1 - .1 * RND) * 60
  350.         explodez = camz - nhat(3) * (1 - .1 * RND) * 60
  351.         GOSUB explode
  352.     CASE "k"
  353.         IF LTRIM$(RTRIM$(VectorGroup(closestgroup).ContentName)) <> "Sparks" THEN
  354.             explodex = VectorGroup(closestgroup).COMx
  355.             explodey = VectorGroup(closestgroup).COMy
  356.             explodez = VectorGroup(closestgroup).COMz
  357.             GOSUB explode
  358.             p = VectorGroup(closestgroup).Pointer
  359.             l = VectorGroup(closestgroup).Lagger
  360.             VectorGroup(l).Pointer = p
  361.             IF p <> -999 THEN
  362.                 VectorGroup(p).Lagger = l
  363.             ELSE
  364.                 'determine last object id
  365.                 p = 1
  366.                 DO
  367.                     k = VectorGroup(p).Identity
  368.                     p = VectorGroup(k).Pointer
  369.                     IF p = -999 THEN EXIT DO
  370.                 LOOP
  371.                 lastobjectid = k
  372.                 VectorGroup(lastobjectid).Pointer = -999
  373.             END IF
  374.         END IF
  375.     CASE "b"
  376.         'determine last object id
  377.         p = 1
  378.         DO
  379.             k = VectorGroup(p).Identity
  380.             p = VectorGroup(k).Pointer
  381.             IF p = -999 THEN EXIT DO
  382.         LOOP
  383.         lastobjectid = k
  384.         particleindex = VectorGroup(lastobjectid).LastParticle
  385.         'create new group
  386.         vecgroupcounter = vecgroupcounter + 1
  387.         vecgroupindex = vecgroupcounter
  388.         VectorGroup(vecgroupindex).Identity = vecgroupindex
  389.         VectorGroup(vecgroupindex).Pointer = -999
  390.         VectorGroup(vecgroupindex).Lagger = lastobjectid
  391.         VectorGroup(vecgroupindex).ContentName = "Block"
  392.         VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  393.         FOR r = 1 TO 400
  394.             particleindex = particleindex + 1
  395.             vecorig(particleindex, 1) = camx + -40 * nhat(1) + RND * tilesize / 2
  396.             vecorig(particleindex, 2) = camy + -40 * nhat(2) + RND * tilesize / 2
  397.             vecorig(particleindex, 3) = camz + -40 * nhat(3) + RND * tilesize / 2
  398.             IF RND > .5 THEN
  399.                 veccolor(particleindex) = thePalette.Tertiary.Violet
  400.             ELSE
  401.                 veccolor(particleindex) = thePalette.Tertiary.Orange
  402.             END IF
  403.             GOSUB calccom
  404.         NEXT
  405.         VectorGroup(vecgroupindex).LastParticle = particleindex
  406.         GOSUB adjustcom
  407.         'connect new group to last group
  408.         VectorGroup(lastobjectid).Pointer = vecgroupindex
  409.  
  410. convert:
  411. ' Convert graphics from uv-cartesian coordinates to monitor coordinates.
  412. x0 = x: y0 = y
  413. x = x0 + centerx
  414. y = -y0 + centery
  415.  
  416. rotate.uhat.plus:
  417. uhat(1) = uhat(1) + nhat(1) * speeddamp
  418. uhat(2) = uhat(2) + nhat(2) * speeddamp
  419. uhat(3) = uhat(3) + nhat(3) * speeddamp
  420.  
  421. rotate.uhat.minus:
  422. uhat(1) = uhat(1) - nhat(1) * speeddamp
  423. uhat(2) = uhat(2) - nhat(2) * speeddamp
  424. uhat(3) = uhat(3) - nhat(3) * speeddamp
  425.  
  426. rotate.vhat.plus:
  427. vhat(1) = vhat(1) + nhat(1) * speeddamp
  428. vhat(2) = vhat(2) + nhat(2) * speeddamp
  429. vhat(3) = vhat(3) + nhat(3) * speeddamp
  430.  
  431. rotate.vhat.minus:
  432. vhat(1) = vhat(1) - nhat(1) * speeddamp
  433. vhat(2) = vhat(2) - nhat(2) * speeddamp
  434. vhat(3) = vhat(3) - nhat(3) * speeddamp
  435.  
  436. rotate.counterclockwise:
  437. v1 = vhat(1)
  438. v2 = vhat(2)
  439. v3 = vhat(3)
  440. vhat(1) = vhat(1) + uhat(1) * speeddamp
  441. vhat(2) = vhat(2) + uhat(2) * speeddamp
  442. vhat(3) = vhat(3) + uhat(3) * speeddamp
  443. uhat(1) = uhat(1) - v1 * speeddamp
  444. uhat(2) = uhat(2) - v2 * speeddamp
  445. uhat(3) = uhat(3) - v3 * speeddamp
  446.  
  447. rotate.clockwise:
  448. v1 = vhat(1)
  449. v2 = vhat(2)
  450. v3 = vhat(3)
  451. vhat(1) = vhat(1) - uhat(1) * speeddamp
  452. vhat(2) = vhat(2) - uhat(2) * speeddamp
  453. vhat(3) = vhat(3) - uhat(3) * speeddamp
  454. uhat(1) = uhat(1) + v1 * speeddamp
  455. uhat(2) = uhat(2) + v2 * speeddamp
  456. uhat(3) = uhat(3) + v3 * speeddamp
  457.  
  458. strafe.camera.uhat.plus:
  459. camx = camx + uhat(1) * speedboost
  460. camy = camy + uhat(2) * speedboost
  461. camz = camz + uhat(3) * speedboost
  462.  
  463. strafe.camera.uhat.minus:
  464. camx = camx - uhat(1) * speedboost
  465. camy = camy - uhat(2) * speedboost
  466. camz = camz - uhat(3) * speedboost
  467.  
  468. strafe.camera.vhat.plus:
  469. camx = camx + vhat(1) * speedboost
  470. camy = camy + vhat(2) * speedboost
  471. camz = camz + vhat(3) * speedboost
  472.  
  473. strafe.camera.vhat.minus:
  474. camx = camx - vhat(1) * speedboost
  475. camy = camy - vhat(2) * speedboost
  476. camz = camz - vhat(3) * speedboost
  477.  
  478. strafe.camera.nhat.plus:
  479. camx = camx + nhat(1) * speedboost
  480. camy = camy + nhat(2) * speedboost
  481. camz = camz + nhat(3) * speedboost
  482.  
  483. strafe.camera.nhat.minus:
  484. camx = camx - nhat(1) * speedboost
  485. camy = camy - nhat(2) * speedboost
  486. camz = camz - nhat(3) * speedboost
  487.  
  488. normalize.screen.vectors:
  489. uhatmag = SQR(uhat(1) ^ 2 + uhat(2) ^ 2 + uhat(3) ^ 2)
  490. uhat(1) = uhat(1) / uhatmag: uhat(2) = uhat(2) / uhatmag: uhat(3) = uhat(3) / uhatmag
  491. vhatmag = SQR(vhat(1) ^ 2 + vhat(2) ^ 2 + vhat(3) ^ 2)
  492. vhat(1) = vhat(1) / vhatmag: vhat(2) = vhat(2) / vhatmag: vhat(3) = vhat(3) / vhatmag
  493. uhatdotvhat = uhat(1) * vhat(1) + uhat(2) * vhat(2) + uhat(3) * vhat(3)
  494. IF SQR(uhatdotvhat ^ 2) > .0005 THEN
  495.     BEEP ' ... if vectors are somenow not normalized. This has never happened.
  496.     uhat(1) = 0.8251367: uhat(2) = -0.564903: uhat(3) = -0.005829525
  497.     vhat(1) = 0.065519: vhat(2) = 0.08544215: vhat(3) = 0.9941866
  498. ' The normal vector points toward the eye.
  499. nhat(1) = uhat(2) * vhat(3) - uhat(3) * vhat(2)
  500. nhat(2) = uhat(3) * vhat(1) - uhat(1) * vhat(3)
  501. nhat(3) = uhat(1) * vhat(2) - uhat(2) * vhat(1)
  502. nhatmag = SQR(nhat(1) ^ 2 + nhat(2) ^ 2 + nhat(3) ^ 2)
  503. nhat(1) = nhat(1) / nhatmag: nhat(2) = nhat(2) / nhatmag: nhat(3) = nhat(3) / nhatmag
  504.  
  505. redraw:
  506. GOSUB normalize.screen.vectors
  507. GOSUB calculate.clippingplanes
  508. ' Project the three-space basis vectors onto the screen plane.
  509. xhatp(1) = xhat(1) * uhat(1) + xhat(2) * uhat(2) + xhat(3) * uhat(3)
  510. xhatp(2) = xhat(1) * vhat(1) + xhat(2) * vhat(2) + xhat(3) * vhat(3)
  511. yhatp(1) = yhat(1) * uhat(1) + yhat(2) * uhat(2) + yhat(3) * uhat(3)
  512. yhatp(2) = yhat(1) * vhat(1) + yhat(2) * vhat(2) + yhat(3) * vhat(3)
  513. zhatp(1) = zhat(1) * uhat(1) + zhat(2) * uhat(2) + zhat(3) * uhat(3)
  514. zhatp(2) = zhat(1) * vhat(1) + zhat(2) * vhat(2) + zhat(3) * vhat(3)
  515. GOSUB compute.visible.particles
  516. GOSUB project.particles
  517. GOSUB draw.all.objects
  518.  
  519. compute.visible.particles:
  520. numparticlevisible = 0
  521. numgroupvisible = 0
  522. closestdist2 = 50 ^ 2 '10000 ^ 2
  523. closestgroup = 1
  524.  
  525. k = 1
  526. k = VectorGroup(k).Identity
  527.  
  528.     xcom = VectorGroup(k).COMx
  529.     ycom = VectorGroup(k).COMy
  530.     zcom = VectorGroup(k).COMz
  531.  
  532.     dist2 = (camx - xcom) ^ 2 + (camy - ycom) ^ 2 + (camz - zcom) ^ 2
  533.  
  534.     IF dist2 < farplane(4) ^ 2 THEN
  535.  
  536.         groupinview = 1 ' Disable near plane group clipping to make things more interesting at zero distance.
  537.         'IF (xcom - camx) * nearplane(1) + (ycom - camy) * nearplane(2) + (zcom - camz) * nearplane(3) - nearplane(4) < 0 THEN groupinview = 0
  538.         'IF (xcom - camx) * farplane(1) + (ycom - camy) * farplane(2) + (zcom - camz) * farplane(3) - farplane(4) < 0 THEN groupinview = 0
  539.         IF (xcom - camx) * rightplane(1) + (ycom - camy) * rightplane(2) + (zcom - camz) * rightplane(3) - rightplane(4) < 0 THEN groupinview = 0
  540.         IF (xcom - camx) * leftplane(1) + (ycom - camy) * leftplane(2) + (zcom - camz) * leftplane(3) - leftplane(4) < 0 THEN groupinview = 0
  541.         IF (xcom - camx) * topplane(1) + (ycom - camy) * topplane(2) + (zcom - camz) * topplane(3) - topplane(4) < 0 THEN groupinview = 0
  542.         IF (xcom - camx) * bottomplane(1) + (ycom - camy) * bottomplane(2) + (zcom - camz) * bottomplane(3) - bottomplane(4) < 0 THEN groupinview = 0
  543.         IF groupinview = 1 THEN
  544.  
  545.             IF dist2 < closestdist2 AND LTRIM$(RTRIM$(VectorGroup(k).ContentName)) <> "Sparks" THEN
  546.                 closestdist2 = dist2
  547.                 closestgroup = k
  548.             END IF
  549.  
  550.             numgroupvisible = numgroupvisible + 1
  551.  
  552.             FOR i = VectorGroup(k).FirstParticle TO VectorGroup(k).LastParticle
  553.                 vec(i, 1) = vecorig(i, 1) - camx
  554.                 vec(i, 2) = vecorig(i, 2) - camy
  555.                 vec(i, 3) = vecorig(i, 3) - camz
  556.             NEXT
  557.  
  558.             IF toggletimeanimate = 1 THEN
  559.                 vecgroupindex = k
  560.                 GOSUB timeanimate
  561.             END IF
  562.  
  563.             FOR i = VectorGroup(k).FirstParticle TO VectorGroup(k).LastParticle
  564.                 GOSUB clip.particle.viewplanes
  565.             NEXT
  566.  
  567.         END IF
  568.  
  569.     END IF
  570.  
  571.     k = VectorGroup(k).Pointer
  572.     IF k = -999 THEN EXIT DO
  573.     k = VectorGroup(k).Identity
  574.  
  575.  
  576. 'NEXT
  577.  
  578. clip.particle.viewplanes:
  579. particleinview = 1
  580. fogswitch = -1
  581. ' Perform standard view plane clipping and implement fog effect.
  582. IF vec(i, 1) * nearplane(1) + vec(i, 2) * nearplane(2) + vec(i, 3) * nearplane(3) - nearplane(4) < 0 THEN particleinview = 0
  583. IF vec(i, 1) * farplane(1) + vec(i, 2) * farplane(2) + vec(i, 3) * farplane(3) - farplane(4) < 0 THEN particleinview = 0
  584. IF vec(i, 1) * farplane(1) + vec(i, 2) * farplane(2) + vec(i, 3) * farplane(3) - farplane(4) * .9 < 0 THEN fogswitch = 1
  585. IF vec(i, 1) * rightplane(1) + vec(i, 2) * rightplane(2) + vec(i, 3) * rightplane(3) - rightplane(4) < 0 THEN particleinview = 0
  586. IF vec(i, 1) * leftplane(1) + vec(i, 2) * leftplane(2) + vec(i, 3) * leftplane(3) - leftplane(4) < 0 THEN particleinview = 0
  587. IF vec(i, 1) * topplane(1) + vec(i, 2) * topplane(2) + vec(i, 3) * topplane(3) - topplane(4) < 0 THEN particleinview = 0
  588. IF vec(i, 1) * bottomplane(1) + vec(i, 2) * bottomplane(2) + vec(i, 3) * bottomplane(3) - bottomplane(4) < 0 THEN particleinview = 0
  589. IF particleinview = 1 THEN
  590.     numparticlevisible = numparticlevisible + 1
  591.     vecvisible(numparticlevisible, 1) = vec(i, 1)
  592.     vecvisible(numparticlevisible, 2) = vec(i, 2)
  593.     vecvisible(numparticlevisible, 3) = vec(i, 3)
  594.     IF closestgroup = k THEN
  595.         vecvisible(numparticlevisible, 4) = 14
  596.     ELSE
  597.         vecvisible(numparticlevisible, 4) = veccolor(i)
  598.     END IF
  599.     IF fogswitch = 1 THEN vecvisible(numparticlevisible, 4) = 8
  600.  
  601. project.particles:
  602. ' Project vectors onto the screen plane.
  603. FOR i = 1 TO numparticlevisible
  604.     vecvisibledotnhat = vecvisible(i, 1) * nhat(1) + vecvisible(i, 2) * nhat(2) + vecvisible(i, 3) * nhat(3)
  605.     vecvisiblepuv(i, 1) = vecvisible(i, 1) * uhat(1) + vecvisible(i, 2) * uhat(2) + vecvisible(i, 3) * uhat(3)
  606.     vecvisiblepuv(i, 2) = vecvisible(i, 1) * vhat(1) + vecvisible(i, 2) * vhat(2) + vecvisible(i, 3) * vhat(3)
  607.     vecvisiblepuvs(i, 1) = vecvisiblepuv(i, 1) * fovd / vecvisibledotnhat
  608.     vecvisiblepuvs(i, 2) = vecvisiblepuv(i, 2) * fovd / vecvisibledotnhat
  609.  
  610. draw.all.objects:
  611. GOSUB plot.particles
  612. ' Redraw compass.
  613. x = 30 * xhatp(1): y = 30 * xhatp(2): GOSUB convert
  614. LINE (centerx, centery)-(x, y), xhat(4)
  615. x = 30 * yhatp(1): y = 30 * yhatp(2): GOSUB convert
  616. LINE (centerx, centery)-(x, y), yhat(4)
  617. x = 30 * zhatp(1): y = 30 * zhatp(2): GOSUB convert
  618. LINE (centerx, centery)-(x, y), zhat(4)
  619. IF togglehud = 1 THEN
  620.     COLOR thePalette.Secondary.Yellow
  621.     _PRINTSTRING (20, 475), "Press b to create a block."
  622.     _PRINTSTRING (20, 490), "Press k to delete closest."
  623.     _PRINTSTRING (20, 445), "SPACE = toggle Info,  ESC = quit."
  624.     _PRINTSTRING (20, 295), "- MOVE - ALIGN -"
  625.     COLOR thePalette.Grayscale.Lighter
  626.     _PRINTSTRING (20, 310), " q w e - x y z"
  627.     _PRINTSTRING (20, 325), " a s d - X Y Z"
  628.     COLOR thePalette.Secondary.Yellow
  629.     _PRINTSTRING (20, 370), "-  ROTATE  -"
  630.     COLOR thePalette.Grayscale.Lighter
  631.     _PRINTSTRING (20, 385), "7 8 9"
  632.     _PRINTSTRING (20, 400), "4 5 6"
  633.     _PRINTSTRING (20, 415), "1 2 3"
  634.     _PRINTSTRING (70, 385), "Mouse"
  635.     _PRINTSTRING (70, 400), "  +  "
  636.     _PRINTSTRING (70, 415), "Wheel"
  637.     COLOR thePalette.Secondary.Yellow
  638.     _PRINTSTRING (20, 10), "- World Info -"
  639.     COLOR thePalette.Grayscale.Lighter
  640.     _PRINTSTRING (20, 25), "Particles: " + STR$(numparticleorig)
  641.     _PRINTSTRING (20, 40), "Visible(g):" + STR$(numgroupvisible)
  642.     COLOR thePalette.Secondary.Yellow
  643.     _PRINTSTRING (20, 70), "- Camera -"
  644.     COLOR thePalette.Grayscale.Lighter
  645.     _PRINTSTRING (20, 85), STR$(INT(camx)) + STR$(INT(camy)) + STR$(INT(camz))
  646.     COLOR thePalette.Secondary.Yellow
  647.     _PRINTSTRING (20, 115), "- Closest: -"
  648.     COLOR thePalette.Grayscale.Lighter
  649.     _PRINTSTRING (20, 130), LTRIM$(RTRIM$(VectorGroup(closestgroup).ContentName))
  650.     COLOR thePalette.Secondary.Yellow
  651.     _PRINTSTRING (20, 160), "- View Distance -"
  652.     COLOR thePalette.Grayscale.Lighter
  653.     _PRINTSTRING (20, 175), "Depth:" + STR$(-farplane(4))
  654.     _PRINTSTRING (20, 190), "Adjust via [ ]"
  655.     COLOR thePalette.Secondary.Yellow
  656.     _PRINTSTRING (20, 220), "- Invert Mouse -"
  657.     COLOR thePalette.Grayscale.Lighter
  658.     _PRINTSTRING (20, 235), "Toggle via `i'"
  659.     COLOR thePalette.Secondary.Yellow
  660.     _PRINTSTRING (20, 265), "Press `T' to toggle animation."
  661.     COLOR thePalette.Grayscale.Lighter
  662.     LOCATE 28, 32: _PRINTSTRING (768, 384), "You See: " + LTRIM$(RTRIM$(VectorGroup(closestgroup).ContentName))
  663.  
  664. calculate.clippingplanes:
  665. ' Calculate normal vectors to all clipping planes.
  666. nearplane(1) = -nhat(1)
  667. nearplane(2) = -nhat(2)
  668. nearplane(3) = -nhat(3)
  669. farplane(1) = nhat(1)
  670. farplane(2) = nhat(2)
  671. farplane(3) = nhat(3)
  672. rightplane(1) = (screenheight / 2) * fovd * uhat(1) - (screenheight / 2) * (screenwidth / 2) * nhat(1)
  673. rightplane(2) = (screenheight / 2) * fovd * uhat(2) - (screenheight / 2) * (screenwidth / 2) * nhat(2)
  674. rightplane(3) = (screenheight / 2) * fovd * uhat(3) - (screenheight / 2) * (screenwidth / 2) * nhat(3)
  675. mag = SQR((rightplane(1)) ^ 2 + (rightplane(2)) ^ 2 + (rightplane(3)) ^ 2)
  676. rightplane(1) = rightplane(1) / mag
  677. rightplane(2) = rightplane(2) / mag
  678. rightplane(3) = rightplane(3) / mag
  679. leftplane(1) = -(screenheight / 2) * fovd * uhat(1) - (screenheight / 2) * (screenwidth / 2) * nhat(1)
  680. leftplane(2) = -(screenheight / 2) * fovd * uhat(2) - (screenheight / 2) * (screenwidth / 2) * nhat(2)
  681. leftplane(3) = -(screenheight / 2) * fovd * uhat(3) - (screenheight / 2) * (screenwidth / 2) * nhat(3)
  682. mag = SQR((leftplane(1)) ^ 2 + (leftplane(2)) ^ 2 + (leftplane(3)) ^ 2)
  683. leftplane(1) = leftplane(1) / mag
  684. leftplane(2) = leftplane(2) / mag
  685. leftplane(3) = leftplane(3) / mag
  686. topplane(1) = (screenwidth / 2) * fovd * vhat(1) - (screenheight / 2) * (screenwidth / 2) * nhat(1)
  687. topplane(2) = (screenwidth / 2) * fovd * vhat(2) - (screenheight / 2) * (screenwidth / 2) * nhat(2)
  688. topplane(3) = (screenwidth / 2) * fovd * vhat(3) - (screenheight / 2) * (screenwidth / 2) * nhat(3)
  689. mag = SQR((topplane(1)) ^ 2 + (topplane(2)) ^ 2 + (topplane(3)) ^ 2)
  690. topplane(1) = topplane(1) / mag
  691. topplane(2) = topplane(2) / mag
  692. topplane(3) = topplane(3) / mag
  693. bottomplane(1) = -(screenwidth / 2) * fovd * vhat(1) - (screenheight / 2) * (screenwidth / 2) * nhat(1)
  694. bottomplane(2) = -(screenwidth / 2) * fovd * vhat(2) - (screenheight / 2) * (screenwidth / 2) * nhat(2)
  695. bottomplane(3) = -(screenwidth / 2) * fovd * vhat(3) - (screenheight / 2) * (screenwidth / 2) * nhat(3)
  696. mag = SQR((bottomplane(1)) ^ 2 + (bottomplane(2)) ^ 2 + (bottomplane(3)) ^ 2)
  697. bottomplane(1) = bottomplane(1) / mag
  698. bottomplane(2) = bottomplane(2) / mag
  699. bottomplane(3) = bottomplane(3) / mag
  700.  
  701. plot.particles:
  702. FOR i = 1 TO numparticlevisible - 1
  703.     x = vecvisiblepuvs(i, 1): y = vecvisiblepuvs(i, 2): GOSUB convert: x1 = x: y1 = y
  704.     x = vecvisiblepuvs(i + 1, 1): y = vecvisiblepuvs(i + 1, 2): GOSUB convert: x2 = x: y2 = y
  705.     IF ((x2 - x1) ^ 2 + (y2 - y1) ^ 2) < 15 ^ 2 THEN
  706.         LINE (x1, y1)-(x2, y2), vecvisible(i, 4) ', B
  707.     ELSE
  708.         CIRCLE (x1, y1), 1, vecvisible(i, 4)
  709.     END IF
  710.  
  711. ' Data.
  712.  
  713. initialize.objects:
  714. particleindex = 0
  715. vecgroupcounter = 0
  716. gridsize = 550
  717. tilesize = 15
  718.  
  719. '__AAA
  720. vecgroupcounter = vecgroupcounter + 1
  721. vecgroupindex = vecgroupcounter
  722. VectorGroup(vecgroupindex).Identity = vecgroupindex
  723. VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  724. VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  725. VectorGroup(vecgroupindex).ContentName = "__AAA"
  726. VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  727. FOR r = 1 TO 5
  728.     particleindex = particleindex + 1
  729.     vecorig(particleindex, 1) = -1000
  730.     vecorig(particleindex, 2) = -1000
  731.     vecorig(particleindex, 3) = -1000
  732.     veccolor(particleindex) = thePalette.Grayscale.White
  733.     GOSUB calccom
  734. VectorGroup(vecgroupindex).LastParticle = particleindex
  735. GOSUB adjustcom
  736.  
  737. 'Banner
  738. vecgroupcounter = vecgroupcounter + 1
  739. vecgroupindex = vecgroupcounter
  740. VectorGroup(vecgroupindex).Identity = vecgroupindex
  741. VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  742. VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  743. VectorGroup(vecgroupindex).ContentName = "Banner"
  744. VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  745. xl = -1.9: xr = 1.9: dx = .32
  746. yl = -1: yr = 1: dy = .32
  747. xl = xl * 4: xr = xr * 4: yl = yl * 4: yr = yr * 4
  748. xrange = 1 + INT((-xl + xr) / dx)
  749. yrange = 1 + INT((-yl + yr) / dy)
  750. t = 0
  751. FOR i = xl TO xr STEP dx
  752.     FOR j = yl TO yr STEP dy
  753.         particleindex = particleindex + 1
  754.         vecorig(particleindex, 1) = 70 + 1.25 * COS(i - 2 * t) ^ 2 - 1.25 * SIN(j - t) ^ 2
  755.         vecorig(particleindex, 2) = 30 + i
  756.         vecorig(particleindex, 3) = 40 + j
  757.         IF vecorig(particleindex, 1) < 70 THEN
  758.             veccolor(particleindex) = thePalette.Secondary.Cyan
  759.         ELSE
  760.             veccolor(particleindex) = thePalette.Tertiary.Orange
  761.         END IF
  762.         GOSUB calccom
  763.     NEXT
  764. VectorGroup(vecgroupindex).LastParticle = particleindex
  765. GOSUB adjustcom
  766.  
  767. 'Clock Face (Rolex)
  768. vecgroupcounter = vecgroupcounter + 1
  769. vecgroupindex = vecgroupcounter
  770. VectorGroup(vecgroupindex).Identity = vecgroupindex
  771. VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  772. VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  773. VectorGroup(vecgroupindex).ContentName = "Clock Face (Rolex)"
  774. VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  775. FOR q = 0 TO 2 * pi STEP (2 * pi / 12) / 25
  776.     FOR r = 10 TO 12 STEP .5
  777.         particleindex = particleindex + 1
  778.         vecorig(particleindex, 1) = 40 + r * COS(q)
  779.         vecorig(particleindex, 2) = -20 + r
  780.         vecorig(particleindex, 3) = 40 + r * SIN(q)
  781.         veccolor(particleindex) = thePalette.Grayscale.White
  782.         GOSUB calccom
  783.     NEXT
  784. VectorGroup(vecgroupindex).LastParticle = particleindex
  785. GOSUB adjustcom
  786.  
  787. 'Clock Hands
  788. vecgroupcounter = vecgroupcounter + 1
  789. vecgroupindex = vecgroupcounter
  790. VectorGroup(vecgroupindex).Identity = vecgroupindex
  791. VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  792. VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  793. VectorGroup(vecgroupindex).ContentName = "Clock Hands"
  794. VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  795. DIM hands(3, 2)
  796. hands(1, 1) = VAL(LEFT$(TIME$, 2)) * (2 * pi / 12)
  797. hands(2, 1) = VAL(MID$(TIME$, 4, 2)) * (2 * pi / 60)
  798. hands(3, 1) = VAL(RIGHT$(TIME$, 2)) * (2 * pi / 60)
  799. phase = pi / 2
  800. hands(1, 2) = 3
  801. hands(2, 2) = 5
  802. hands(3, 2) = 9
  803. FOR q = 1 TO 3
  804.     FOR r = 0 TO 5 + q STEP .1
  805.         particleindex = particleindex + 1
  806.         vecorig(particleindex, 1) = 40 + r * COS(hands(q, 1) + phase)
  807.         vecorig(particleindex, 2) = -10
  808.         vecorig(particleindex, 3) = 40 + r * SIN(hands(q, 1) + phase)
  809.         veccolor(particleindex) = hands(q, 2)
  810.         GOSUB calccom
  811.     NEXT
  812. VectorGroup(vecgroupindex).LastParticle = particleindex
  813. GOSUB adjustcom
  814.  
  815. 'Dirt
  816. h = 5
  817. FOR w = 1 TO 5
  818.     FOR u = -gridsize TO gridsize STEP tilesize
  819.         FOR v = -gridsize TO gridsize STEP tilesize
  820.             vecgroupcounter = vecgroupcounter + 1
  821.             vecgroupindex = vecgroupcounter
  822.             VectorGroup(vecgroupindex).Identity = vecgroupindex
  823.             VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  824.             VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  825.             VectorGroup(vecgroupindex).ContentName = "Dirt"
  826.             VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  827.             FOR i = u TO u + tilesize STEP h
  828.                 FOR j = v TO v + tilesize STEP h
  829.                     IF RND > 1 - w / 5 THEN
  830.                         particleindex = particleindex + 1
  831.                         vecorig(particleindex, 1) = i + RND * h - RND * h
  832.                         vecorig(particleindex, 2) = j + RND * h - RND * h
  833.                         vecorig(particleindex, 3) = -(w - 1) * 70 - RND * 70
  834.                         IF RND > .5 THEN
  835.                             veccolor(particleindex) = thePalette.Tertiary.Orange
  836.                         ELSE
  837.                             IF RND > .5 THEN
  838.                                 veccolor(particleindex) = thePalette.Grayscale.Lighter
  839.                             ELSE
  840.                                 veccolor(particleindex) = thePalette.Primary.Green
  841.                             END IF
  842.                         END IF
  843.                         GOSUB calccom
  844.                     END IF
  845.                 NEXT
  846.             NEXT
  847.             VectorGroup(vecgroupindex).LastParticle = particleindex
  848.             GOSUB adjustcom
  849.         NEXT
  850.     NEXT
  851.  
  852. 'Grass and Puddles
  853. h = 2
  854. FOR u = -gridsize TO gridsize STEP tilesize
  855.     FOR v = -gridsize TO gridsize STEP tilesize
  856.         vecgroupcounter = vecgroupcounter + 1
  857.         vecgroupindex = vecgroupcounter
  858.         VectorGroup(vecgroupindex).Identity = vecgroupindex
  859.         VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  860.         VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  861.         VectorGroup(vecgroupindex).ContentName = "Grass and Puddles"
  862.         VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  863.         FOR i = u TO u + tilesize STEP h
  864.             FOR j = v TO v + tilesize STEP h
  865.                 particleindex = particleindex + 1
  866.                 vecorig(particleindex, 1) = i + RND * h - RND * h
  867.                 vecorig(particleindex, 2) = j + RND * h - RND * h
  868.                 vecorig(particleindex, 3) = .5 + 1 * COS((i - 15) * .08) - 1 * COS((j - 6) * .12)
  869.                 IF vecorig(particleindex, 3) > 0 THEN
  870.                     veccolor(particleindex) = thePalette.Primary.Green
  871.                 ELSE
  872.                     IF RND > .2 THEN
  873.                         veccolor(particleindex) = thePalette.Tint.Blue
  874.                     ELSE
  875.                         veccolor(particleindex) = thePalette.Primary.Blue
  876.                     END IF
  877.                 END IF
  878.                 GOSUB calccom
  879.             NEXT
  880.         NEXT
  881.         VectorGroup(vecgroupindex).LastParticle = particleindex
  882.         GOSUB adjustcom
  883.     NEXT
  884.  
  885. 'Grave
  886. 'xloc = -90
  887. 'yloc = 0
  888. thickness = 2.5
  889. span = 20
  890. height = 30
  891. crux = 22
  892. FOR xloc = -90 TO -290 STEP -60
  893.     FOR yloc = 0 TO 180 STEP 45
  894.         FOR k = 0 TO height
  895.             vecgroupcounter = vecgroupcounter + 1
  896.             vecgroupindex = vecgroupcounter
  897.             VectorGroup(vecgroupindex).Identity = vecgroupindex
  898.             VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  899.             VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  900.             VectorGroup(vecgroupindex).ContentName = "Grave"
  901.             VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  902.             FOR i = -thickness TO thickness STEP thickness / 2
  903.                 FOR j = -thickness TO thickness STEP thickness / 2
  904.                     particleindex = particleindex + 1
  905.                     vecorig(particleindex, 1) = xloc + i + (RND - .5) * 2
  906.                     vecorig(particleindex, 2) = yloc + j + (RND - .5) * 2
  907.                     vecorig(particleindex, 3) = k + (RND - .5) * 2
  908.                     IF RND > .5 THEN
  909.                         veccolor(particleindex) = thePalette.Grayscale.Lighter
  910.                     ELSE
  911.                         veccolor(particleindex) = thePalette.Grayscale.Darker
  912.                     END IF
  913.                     GOSUB calccom
  914.                 NEXT
  915.             NEXT
  916.             VectorGroup(vecgroupindex).LastParticle = particleindex
  917.             GOSUB adjustcom
  918.         NEXT
  919.         FOR j = -span / 2 TO -thickness
  920.             vecgroupcounter = vecgroupcounter + 1
  921.             vecgroupindex = vecgroupcounter
  922.             VectorGroup(vecgroupindex).Identity = vecgroupindex
  923.             VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  924.             VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  925.             VectorGroup(vecgroupindex).ContentName = "Grave"
  926.             VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  927.             FOR k = -thickness TO thickness STEP thickness / 2
  928.                 FOR i = -thickness TO thickness STEP thickness / 2
  929.                     particleindex = particleindex + 1
  930.                     vecorig(particleindex, 1) = xloc + i + (RND - .5) * 2
  931.                     vecorig(particleindex, 2) = yloc + j + (RND - .5) * 2
  932.                     vecorig(particleindex, 3) = crux + k + (RND - .5) * 2
  933.                     IF RND > .5 THEN
  934.                         veccolor(particleindex) = thePalette.Grayscale.Lighter
  935.                     ELSE
  936.                         veccolor(particleindex) = thePalette.Grayscale.Darker
  937.                     END IF
  938.                     GOSUB calccom
  939.                 NEXT
  940.             NEXT
  941.             VectorGroup(vecgroupindex).LastParticle = particleindex
  942.             GOSUB adjustcom
  943.         NEXT
  944.         FOR j = thickness TO span / 2
  945.             vecgroupcounter = vecgroupcounter + 1
  946.             vecgroupindex = vecgroupcounter
  947.             VectorGroup(vecgroupindex).Identity = vecgroupindex
  948.             VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  949.             VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  950.             VectorGroup(vecgroupindex).ContentName = "Grave"
  951.             VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  952.             FOR k = -thickness TO thickness STEP thickness / 2
  953.                 FOR i = -thickness TO thickness STEP thickness / 2
  954.                     particleindex = particleindex + 1
  955.                     vecorig(particleindex, 1) = xloc + i + (RND - .5) * 2
  956.                     vecorig(particleindex, 2) = yloc + j + (RND - .5) * 2
  957.                     vecorig(particleindex, 3) = crux + k + (RND - .5) * 2
  958.                     IF RND > .5 THEN
  959.                         veccolor(particleindex) = thePalette.Grayscale.Lighter
  960.                     ELSE
  961.                         veccolor(particleindex) = thePalette.Grayscale.Darker
  962.                     END IF
  963.                     GOSUB calccom
  964.                 NEXT
  965.             NEXT
  966.             VectorGroup(vecgroupindex).LastParticle = particleindex
  967.             GOSUB adjustcom
  968.         NEXT
  969.     NEXT
  970.  
  971. 'Heaven's Bottom Layer
  972. h = 2
  973. FOR u = -gridsize TO gridsize STEP tilesize
  974.     FOR v = -gridsize TO gridsize STEP tilesize
  975.         vecgroupcounter = vecgroupcounter + 1
  976.         vecgroupindex = vecgroupcounter
  977.         VectorGroup(vecgroupindex).Identity = vecgroupindex
  978.         VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  979.         VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  980.         VectorGroup(vecgroupindex).ContentName = "Heaven's Bottom Layer"
  981.         VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  982.         FOR i = u TO u + tilesize STEP h
  983.             FOR j = v TO v + tilesize STEP h
  984.                 particleindex = particleindex + 1
  985.                 vecorig(particleindex, 1) = i + RND * h - RND * h
  986.                 vecorig(particleindex, 2) = j + RND * h - RND * h
  987.                 vecorig(particleindex, 3) = 420 - RND
  988.                 IF RND > .5 THEN
  989.                     veccolor(particleindex) = thePalette.Secondary.Cyan
  990.                 ELSE
  991.                     veccolor(particleindex) = thePalette.Tertiary.Violet
  992.                 END IF
  993.                 GOSUB calccom
  994.             NEXT
  995.         NEXT
  996.         VectorGroup(vecgroupindex).LastParticle = particleindex
  997.         GOSUB adjustcom
  998.     NEXT
  999.  
  1000. 'Hell Spawn
  1001. FOR u = -gridsize TO gridsize STEP tilesize
  1002.     FOR v = -gridsize TO gridsize STEP tilesize
  1003.         vecgroupcounter = vecgroupcounter + 1
  1004.         vecgroupindex = vecgroupcounter
  1005.         VectorGroup(vecgroupindex).Identity = vecgroupindex
  1006.         VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1007.         VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1008.         VectorGroup(vecgroupindex).ContentName = "Hell Spawn"
  1009.         VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1010.         FOR i = u TO u + tilesize STEP tilesize / 5
  1011.             FOR j = v TO v + tilesize STEP tilesize / 5
  1012.                 particleindex = particleindex + 1
  1013.                 vecorig(particleindex, 1) = i + RND * tilesize / 5
  1014.                 vecorig(particleindex, 2) = j + RND * tilesize / 5
  1015.                 vecorig(particleindex, 3) = -350 - RND * 70
  1016.                 IF RND > .2 THEN
  1017.                     veccolor(particleindex) = thePalette.Primary.Red
  1018.                 ELSE
  1019.                     veccolor(particleindex) = thePalette.Tint.Green
  1020.                 END IF
  1021.                 GOSUB calccom
  1022.             NEXT
  1023.         NEXT
  1024.         VectorGroup(vecgroupindex).LastParticle = particleindex
  1025.         GOSUB adjustcom
  1026.     NEXT
  1027.  
  1028. 'Icewall East
  1029. h = 2
  1030. FOR u = -gridsize TO gridsize STEP tilesize
  1031.     FOR v = 0 TO 70 STEP tilesize
  1032.         vecgroupcounter = vecgroupcounter + 1
  1033.         vecgroupindex = vecgroupcounter
  1034.         VectorGroup(vecgroupindex).Identity = vecgroupindex
  1035.         VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1036.         VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1037.         VectorGroup(vecgroupindex).ContentName = "Icewall East"
  1038.         VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1039.         FOR i = u TO u + tilesize STEP h
  1040.             FOR j = v TO v + tilesize STEP h
  1041.                 particleindex = particleindex + 1
  1042.                 vecorig(particleindex, 1) = gridsize
  1043.                 vecorig(particleindex, 2) = i + RND * h - RND * h
  1044.                 vecorig(particleindex, 3) = j + RND * h - RND * h
  1045.                 IF RND > .5 THEN
  1046.                     veccolor(particleindex) = thePalette.Grayscale.White
  1047.                 ELSE
  1048.                     veccolor(particleindex) = thePalette.Grayscale.Lighter
  1049.                 END IF
  1050.                 GOSUB calccom
  1051.             NEXT
  1052.         NEXT
  1053.         VectorGroup(vecgroupindex).LastParticle = particleindex
  1054.         GOSUB adjustcom
  1055.     NEXT
  1056.  
  1057. 'Icewall South
  1058. h = 2
  1059. FOR u = -gridsize TO gridsize STEP tilesize
  1060.     FOR v = 0 TO 70 STEP tilesize
  1061.         vecgroupcounter = vecgroupcounter + 1
  1062.         vecgroupindex = vecgroupcounter
  1063.         VectorGroup(vecgroupindex).Identity = vecgroupindex
  1064.         VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1065.         VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1066.         VectorGroup(vecgroupindex).ContentName = "Icewall South"
  1067.         VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1068.         FOR i = u TO u + tilesize STEP h
  1069.             FOR j = v TO v + tilesize STEP h
  1070.                 particleindex = particleindex + 1
  1071.                 vecorig(particleindex, 1) = -gridsize
  1072.                 vecorig(particleindex, 2) = i + RND * h - RND * h
  1073.                 vecorig(particleindex, 3) = j + RND * h - RND * h
  1074.                 IF RND > .5 THEN
  1075.                     veccolor(particleindex) = thePalette.Grayscale.White
  1076.                 ELSE
  1077.                     veccolor(particleindex) = thePalette.Grayscale.Lighter
  1078.                 END IF
  1079.                 GOSUB calccom
  1080.             NEXT
  1081.         NEXT
  1082.         VectorGroup(vecgroupindex).LastParticle = particleindex
  1083.         GOSUB adjustcom
  1084.     NEXT
  1085.  
  1086. 'Icewall North
  1087. h = 2
  1088. FOR u = -gridsize TO gridsize STEP tilesize
  1089.     FOR v = 0 TO 70 STEP tilesize
  1090.         vecgroupcounter = vecgroupcounter + 1
  1091.         vecgroupindex = vecgroupcounter
  1092.         VectorGroup(vecgroupindex).Identity = vecgroupindex
  1093.         VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1094.         VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1095.         VectorGroup(vecgroupindex).ContentName = "Icewall North"
  1096.         VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1097.         FOR i = u TO u + tilesize STEP h
  1098.             FOR j = v TO v + tilesize STEP h
  1099.                 particleindex = particleindex + 1
  1100.                 vecorig(particleindex, 1) = i + RND * h - RND * h
  1101.                 vecorig(particleindex, 2) = gridsize
  1102.                 vecorig(particleindex, 3) = j + RND * h - RND * h
  1103.                 IF RND > .5 THEN
  1104.                     veccolor(particleindex) = thePalette.Grayscale.White
  1105.                 ELSE
  1106.                     veccolor(particleindex) = thePalette.Grayscale.Lighter
  1107.                 END IF
  1108.                 GOSUB calccom
  1109.             NEXT
  1110.         NEXT
  1111.         VectorGroup(vecgroupindex).LastParticle = particleindex
  1112.         GOSUB adjustcom
  1113.     NEXT
  1114.  
  1115. 'Icewall West
  1116. h = 2
  1117. FOR u = -gridsize TO gridsize STEP tilesize
  1118.     FOR v = 0 TO 70 STEP tilesize
  1119.         vecgroupcounter = vecgroupcounter + 1
  1120.         vecgroupindex = vecgroupcounter
  1121.         VectorGroup(vecgroupindex).Identity = vecgroupindex
  1122.         VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1123.         VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1124.         VectorGroup(vecgroupindex).ContentName = "Icewall West"
  1125.         VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1126.         FOR i = u TO u + tilesize STEP h
  1127.             FOR j = v TO v + tilesize STEP h
  1128.                 particleindex = particleindex + 1
  1129.                 vecorig(particleindex, 1) = i + RND * h - RND * h
  1130.                 vecorig(particleindex, 2) = -gridsize
  1131.                 vecorig(particleindex, 3) = j + RND * h - RND * h
  1132.                 IF RND > .5 THEN
  1133.                     veccolor(particleindex) = thePalette.Grayscale.White
  1134.                 ELSE
  1135.                     veccolor(particleindex) = thePalette.Grayscale.Lighter
  1136.                 END IF
  1137.                 GOSUB calccom
  1138.             NEXT
  1139.         NEXT
  1140.         VectorGroup(vecgroupindex).LastParticle = particleindex
  1141.         GOSUB adjustcom
  1142.     NEXT
  1143.  
  1144. 'Lake of Fire
  1145. h = 2
  1146. FOR u = -gridsize TO gridsize STEP tilesize
  1147.     FOR v = -gridsize TO gridsize STEP tilesize
  1148.         vecgroupcounter = vecgroupcounter + 1
  1149.         vecgroupindex = vecgroupcounter
  1150.         VectorGroup(vecgroupindex).Identity = vecgroupindex
  1151.         VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1152.         VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1153.         VectorGroup(vecgroupindex).ContentName = "Lake of Fire"
  1154.         VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1155.         FOR i = u TO u + tilesize STEP h
  1156.             FOR j = v TO v + tilesize STEP h
  1157.                 particleindex = particleindex + 1
  1158.                 vecorig(particleindex, 1) = i + RND * h - RND * h
  1159.                 vecorig(particleindex, 2) = j + RND * h - RND * h
  1160.                 vecorig(particleindex, 3) = -350 - 70 - RND
  1161.                 IF RND > .2 THEN
  1162.                     veccolor(particleindex) = thePalette.Primary.Red
  1163.                 ELSE
  1164.                     veccolor(particleindex) = thePalette.Tint.Cyan
  1165.                 END IF
  1166.                 GOSUB calccom
  1167.             NEXT
  1168.         NEXT
  1169.         VectorGroup(vecgroupindex).LastParticle = particleindex
  1170.         GOSUB adjustcom
  1171.     NEXT
  1172.  
  1173. 'Megalith
  1174. ctrx = -90
  1175. ctry = -320
  1176. ctrz = 4
  1177. w = 8
  1178. h = 256
  1179. dens = 100
  1180. FOR k = 1 TO h STEP w
  1181.     FOR i = -h / 20 + k / 20 TO h / 20 - k / 20 STEP w
  1182.         FOR j = -h / 20 + k / 20 TO h / 20 - k / 20 STEP w
  1183.             vecgroupcounter = vecgroupcounter + 1
  1184.             vecgroupindex = vecgroupcounter
  1185.             VectorGroup(vecgroupindex).Identity = vecgroupindex
  1186.             VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1187.             VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1188.             VectorGroup(vecgroupindex).ContentName = "Megalith"
  1189.             VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1190.             FOR q = 1 TO dens
  1191.                 particleindex = particleindex + 1
  1192.                 vecorig(particleindex, 1) = ctrx + i + (RND - .5) * w
  1193.                 vecorig(particleindex, 2) = ctry + j + (RND - .5) * w
  1194.                 vecorig(particleindex, 3) = ctrz + k + (RND - .5) * w
  1195.                 IF RND > .5 THEN
  1196.                     veccolor(particleindex) = thePalette.Secondary.Cyan
  1197.                 ELSE
  1198.                     veccolor(particleindex) = thePalette.Grayscale.Lighter
  1199.                 END IF
  1200.                 GOSUB calccom
  1201.             NEXT
  1202.             VectorGroup(vecgroupindex).LastParticle = particleindex
  1203.             GOSUB adjustcom
  1204.         NEXT
  1205.     NEXT
  1206.  
  1207. 'Moon
  1208. vecgroupcounter = vecgroupcounter + 1
  1209. vecgroupindex = vecgroupcounter
  1210. VectorGroup(vecgroupindex).Identity = vecgroupindex
  1211. VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1212. VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1213. VectorGroup(vecgroupindex).ContentName = "Moon"
  1214. VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1215. radius = 4
  1216. au = 60
  1217. dx = (2 * pi / radius) * .05
  1218. dy = (2 * pi / radius) * .05
  1219. xl = 0: xr = 2 * pi
  1220. yl = 0: yr = pi
  1221. xrange = 1 + INT((-xl + xr) / dx)
  1222. yrange = 1 + INT((-yl + yr) / dy)
  1223. FOR i = 1 TO xrange
  1224.     FOR j = 1 TO yrange
  1225.         particleindex = particleindex + 1
  1226.         theta = i * dx - dx
  1227.         phi = j * dy - dy
  1228.         vecorig(particleindex, 1) = au + radius * SIN(phi) * COS(theta)
  1229.         vecorig(particleindex, 2) = radius * SIN(phi) * SIN(theta)
  1230.         vecorig(particleindex, 3) = 90 + radius * COS(phi)
  1231.         IF RND > .5 THEN
  1232.             veccolor(particleindex) = thePalette.Grayscale.Lighter
  1233.         ELSE
  1234.             veccolor(particleindex) = thePalette.Grayscale.Darker
  1235.         END IF
  1236.         GOSUB calccom
  1237.     NEXT
  1238. VectorGroup(vecgroupindex).LastParticle = particleindex
  1239. GOSUB adjustcom
  1240.  
  1241. 'Pyramid
  1242. ctrx = -90
  1243. ctry = -120
  1244. ctrz = 4
  1245. w = 8
  1246. h = 56
  1247. dens = 50
  1248. FOR k = 1 TO h STEP w
  1249.     FOR i = -h / 2 + k / 2 TO h / 2 - k / 2 STEP w
  1250.         FOR j = -h / 2 + k / 2 TO h / 2 - k / 2 STEP w
  1251.             vecgroupcounter = vecgroupcounter + 1
  1252.             vecgroupindex = vecgroupcounter
  1253.             VectorGroup(vecgroupindex).Identity = vecgroupindex
  1254.             VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1255.             VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1256.             VectorGroup(vecgroupindex).ContentName = "Pyramid"
  1257.             VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1258.             FOR q = 1 TO dens
  1259.                 particleindex = particleindex + 1
  1260.                 vecorig(particleindex, 1) = ctrx + i + (RND - .5) * w
  1261.                 vecorig(particleindex, 2) = ctry + j + (RND - .5) * w
  1262.                 vecorig(particleindex, 3) = ctrz + k + (RND - .5) * w
  1263.                 IF RND > .5 THEN
  1264.                     veccolor(particleindex) = thePalette.Tertiary.Orange
  1265.                 ELSE
  1266.                     veccolor(particleindex) = thePalette.Tint.Red
  1267.                 END IF
  1268.                 GOSUB calccom
  1269.             NEXT
  1270.             VectorGroup(vecgroupindex).LastParticle = particleindex
  1271.             GOSUB adjustcom
  1272.         NEXT
  1273.     NEXT
  1274.  
  1275. 'Rain
  1276. FOR u = -gridsize TO gridsize STEP tilesize
  1277.     FOR v = -gridsize TO gridsize STEP tilesize
  1278.         vecgroupcounter = vecgroupcounter + 1
  1279.         vecgroupindex = vecgroupcounter
  1280.         VectorGroup(vecgroupindex).Identity = vecgroupindex
  1281.         VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1282.         VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1283.         VectorGroup(vecgroupindex).ContentName = "Rain"
  1284.         VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1285.         FOR i = u TO u + tilesize STEP tilesize '/ 3
  1286.             FOR j = v TO v + tilesize STEP tilesize '/ 3
  1287.                 particleindex = particleindex + 1
  1288.                 vecorig(particleindex, 1) = i + RND * tilesize
  1289.                 vecorig(particleindex, 2) = j + RND * tilesize
  1290.                 vecorig(particleindex, 3) = RND * 70
  1291.                 IF RND > .66 THEN
  1292.                     veccolor(particleindex) = thePalette.Tint.Blue
  1293.                 ELSE
  1294.                     veccolor(particleindex) = thePalette.Grayscale.Lighter
  1295.                 END IF
  1296.                 GOSUB calccom
  1297.             NEXT
  1298.         NEXT
  1299.         VectorGroup(vecgroupindex).LastParticle = particleindex
  1300.         GOSUB adjustcom
  1301.     NEXT
  1302.  
  1303. 'Sky
  1304. h = 2
  1305. FOR u = -gridsize TO gridsize STEP tilesize
  1306.     FOR v = -gridsize TO gridsize STEP tilesize
  1307.         vecgroupcounter = vecgroupcounter + 1
  1308.         vecgroupindex = vecgroupcounter
  1309.         VectorGroup(vecgroupindex).Identity = vecgroupindex
  1310.         VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1311.         VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1312.         VectorGroup(vecgroupindex).ContentName = "Sky"
  1313.         VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1314.         FOR i = u TO u + tilesize STEP h
  1315.             FOR j = v TO v + tilesize STEP h
  1316.                 particleindex = particleindex + 1
  1317.                 vecorig(particleindex, 1) = i + RND * h - RND * h
  1318.                 vecorig(particleindex, 2) = j + RND * h - RND * h
  1319.                 vecorig(particleindex, 3) = 70 + RND * h - RND * h
  1320.                 IF RND > .5 THEN
  1321.                     veccolor(particleindex) = thePalette.Tint.Blue
  1322.                 ELSE
  1323.                     veccolor(particleindex) = thePalette.Grayscale.White
  1324.                 END IF
  1325.                 GOSUB calccom
  1326.             NEXT
  1327.         NEXT
  1328.         VectorGroup(vecgroupindex).LastParticle = particleindex
  1329.         GOSUB adjustcom
  1330.     NEXT
  1331.  
  1332. 'Snake?
  1333. vecgroupcounter = vecgroupcounter + 1
  1334. vecgroupindex = vecgroupcounter
  1335. VectorGroup(vecgroupindex).Identity = vecgroupindex
  1336. VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1337. VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1338. VectorGroup(vecgroupindex).ContentName = "Snake?"
  1339. VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1340. FOR i = -pi TO pi STEP .005
  1341.     particleindex = particleindex + 1
  1342.     vecorig(particleindex, 1) = -10 + 5 * COS(i)
  1343.     vecorig(particleindex, 2) = -20 + 5 * SIN(i)
  1344.     vecorig(particleindex, 3) = 25 - 3 * COS(6 * i) * SIN(3 * i)
  1345.     veccolor(particleindex) = thePalette.Tint.Red
  1346.     GOSUB calccom
  1347. VectorGroup(vecgroupindex).LastParticle = particleindex
  1348. GOSUB adjustcom
  1349.  
  1350. 'Sparks
  1351. vecgroupcounter = vecgroupcounter + 1
  1352. vecgroupindex = vecgroupcounter
  1353. VectorGroup(vecgroupindex).Identity = vecgroupindex
  1354. VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1355. VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1356. VectorGroup(vecgroupindex).ContentName = "Sparks"
  1357. VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1358. u = 0
  1359. v = 0
  1360. FOR i = 1 TO 300
  1361.     particleindex = particleindex + 1
  1362.     vecorig(particleindex, 1) = RND - .5
  1363.     vecorig(particleindex, 2) = RND - .5
  1364.     vecorig(particleindex, 3) = 20 + RND - .5
  1365.     vecorigvel(particleindex, 1) = 8 * (RND - .5)
  1366.     vecorigvel(particleindex, 2) = 8 * (RND - .5)
  1367.     vecorigvel(particleindex, 3) = 20 * RND
  1368.     vecorigacc(particleindex, 1) = 0
  1369.     vecorigacc(particleindex, 2) = 0
  1370.     vecorigacc(particleindex, 3) = -40
  1371.     veccolor(particleindex) = _RGBA32(INT(RND * 254) + 1, INT(RND * 254) + 1, INT(RND * 254) + 1, 255)
  1372.     GOSUB calccom
  1373. VectorGroup(vecgroupindex).LastParticle = particleindex
  1374. GOSUB adjustcom
  1375.  
  1376. 'Stars
  1377. h = 5
  1378. FOR w = 1 TO 5
  1379.     FOR u = -gridsize TO gridsize STEP tilesize
  1380.         FOR v = -gridsize TO gridsize STEP tilesize
  1381.             vecgroupcounter = vecgroupcounter + 1
  1382.             vecgroupindex = vecgroupcounter
  1383.             VectorGroup(vecgroupindex).Identity = vecgroupindex
  1384.             VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1385.             VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1386.             VectorGroup(vecgroupindex).ContentName = "Stars"
  1387.             VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1388.             FOR i = u TO u + tilesize STEP h
  1389.                 FOR j = v TO v + tilesize STEP h
  1390.                     IF RND > 1 - w / 5 THEN
  1391.                         particleindex = particleindex + 1
  1392.                         vecorig(particleindex, 1) = i + RND * h - RND * h
  1393.                         vecorig(particleindex, 2) = j + RND * h - RND * h
  1394.                         vecorig(particleindex, 3) = w * 70 + RND * 70
  1395.                         IF RND > .5 THEN
  1396.                             veccolor(particleindex) = thePalette.Grayscale.White
  1397.                         ELSE
  1398.                             IF RND > .5 THEN
  1399.                                 veccolor(particleindex) = thePalette.Grayscale.Lighter
  1400.                             ELSE
  1401.                                 veccolor(particleindex) = thePalette.Grayscale.Darker
  1402.                             END IF
  1403.                         END IF
  1404.                         GOSUB calccom
  1405.                     END IF
  1406.                 NEXT
  1407.             NEXT
  1408.             VectorGroup(vecgroupindex).LastParticle = particleindex
  1409.             GOSUB adjustcom
  1410.         NEXT
  1411.     NEXT
  1412.  
  1413. 'Sun
  1414. radius = 10
  1415. dx = .0628
  1416. dy = .0628
  1417. xl = 0: xr = 2 * pi
  1418. yl = 0: yr = pi
  1419. xrange = 1 + INT((-xl + xr) / dx)
  1420. yrange = 1 + INT((-yl + yr) / dy)
  1421. FOR i = 1 TO xrange STEP 10
  1422.     FOR j = 1 TO yrange STEP 10
  1423.         vecgroupcounter = vecgroupcounter + 1
  1424.         vecgroupindex = vecgroupcounter
  1425.         VectorGroup(vecgroupindex).Identity = vecgroupindex
  1426.         VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1427.         VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1428.         VectorGroup(vecgroupindex).ContentName = "Sun"
  1429.         VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1430.         FOR u = i TO i + 10 STEP 1
  1431.             FOR v = j TO j + 10 STEP 1
  1432.                 particleindex = particleindex + 1
  1433.                 theta = u * dx - dx
  1434.                 phi = v * dy - dy
  1435.                 vecorig(particleindex, 1) = radius * SIN(phi) * COS(theta)
  1436.                 vecorig(particleindex, 2) = radius * SIN(phi) * SIN(theta)
  1437.                 vecorig(particleindex, 3) = 90 + radius * COS(phi)
  1438.                 veccolor(particleindex) = thePalette.Secondary.Yellow
  1439.                 GOSUB calccom
  1440.             NEXT
  1441.         NEXT
  1442.         VectorGroup(vecgroupindex).LastParticle = particleindex
  1443.         GOSUB adjustcom
  1444.     NEXT
  1445.  
  1446. 'UFO!!!
  1447. vecgroupcounter = vecgroupcounter + 1
  1448. vecgroupindex = vecgroupcounter
  1449. VectorGroup(vecgroupindex).Identity = vecgroupindex
  1450. VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1451. VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1452. VectorGroup(vecgroupindex).ContentName = "UFO!!!"
  1453. VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1454. FOR q = 0 TO 2 * pi STEP (2 * pi / 12) / 25
  1455.     FOR r = 10 TO 12 STEP .5
  1456.         particleindex = particleindex + 1
  1457.         vecorig(particleindex, 1) = -90 + r * COS(q)
  1458.         vecorig(particleindex, 2) = -120 + r * SIN(q)
  1459.         vecorig(particleindex, 3) = 100 + r - 12
  1460.         veccolor(particleindex) = thePalette.Tint.Violet
  1461.         GOSUB calccom
  1462.     NEXT
  1463.     FOR r = 12 TO 10 STEP -.5
  1464.         particleindex = particleindex + 1
  1465.         vecorig(particleindex, 1) = -90 + r * COS(q)
  1466.         vecorig(particleindex, 2) = -120 + r * SIN(q)
  1467.         vecorig(particleindex, 3) = 100 - r + 12
  1468.         veccolor(particleindex) = thePalette.Tint.Red
  1469.         GOSUB calccom
  1470.     NEXT
  1471. r = 5
  1472. h = 30
  1473. FOR w = 1 TO 400
  1474.     xx = (RND - .5) * 2 * r
  1475.     yy = (RND - .5) * 2 * r
  1476.     IF xx ^ 2 + yy ^ 2 < r ^ 2 THEN
  1477.         particleindex = particleindex + 1
  1478.         vecorig(particleindex, 1) = -90 + xx
  1479.         vecorig(particleindex, 2) = -120 + yy
  1480.         vecorig(particleindex, 3) = 100 - RND * h
  1481.         IF RND > .5 THEN
  1482.             veccolor(particleindex) = thePalette.Secondary.Cyan
  1483.         ELSE
  1484.             veccolor(particleindex) = thePalette.Tint.Cyan
  1485.         END IF
  1486.         GOSUB calccom
  1487.     END IF
  1488. VectorGroup(vecgroupindex).LastParticle = particleindex
  1489. GOSUB adjustcom
  1490.  
  1491. 'Waves or Particles? (1)
  1492. FOR i = 1 TO 5 STEP 1
  1493.     FOR k = 1 TO 5 STEP 1
  1494.         vecgroupcounter = vecgroupcounter + 1
  1495.         vecgroupindex = vecgroupcounter
  1496.         VectorGroup(vecgroupindex).Identity = vecgroupindex
  1497.         VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1498.         VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1499.         VectorGroup(vecgroupindex).ContentName = "Waves or Particles?"
  1500.         VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1501.         FOR u = i TO i + 1 STEP .05
  1502.             FOR v = k TO k + 1 STEP .05
  1503.                 particleindex = particleindex + 1
  1504.                 vecorig(particleindex, 1) = 70 + 7 * u
  1505.                 vecorig(particleindex, 2) = 80 + 1 * COS((u ^ 2 - v ^ 2))
  1506.                 vecorig(particleindex, 3) = 10 + 7 * v
  1507.                 IF vecorig(particleindex, 2) < 80 THEN
  1508.                     veccolor(particleindex) = thePalette.Primary.Green
  1509.                 ELSE
  1510.                     veccolor(particleindex) = thePalette.Primary.Blue
  1511.                 END IF
  1512.                 GOSUB calccom
  1513.             NEXT
  1514.         NEXT
  1515.         VectorGroup(vecgroupindex).LastParticle = particleindex
  1516.         GOSUB adjustcom
  1517.     NEXT
  1518.  
  1519. 'Waves or Particles? (2)
  1520. FOR i = 1 TO 5 STEP 1
  1521.     FOR k = 1 TO 5 STEP 1
  1522.         vecgroupcounter = vecgroupcounter + 1
  1523.         vecgroupindex = vecgroupcounter
  1524.         VectorGroup(vecgroupindex).Identity = vecgroupindex
  1525.         VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1526.         VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1527.         VectorGroup(vecgroupindex).ContentName = "Waves or Particles?"
  1528.         VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1529.         FOR u = i TO i + 1 STEP .05
  1530.             FOR v = k TO k + 1 STEP .05
  1531.                 particleindex = particleindex + 1
  1532.                 vecorig(particleindex, 1) = -7 * u
  1533.                 vecorig(particleindex, 2) = 80 + 1 * COS(2 * ((u - 7) ^ 2 - (v - 5) ^ 2))
  1534.                 vecorig(particleindex, 3) = 10 + 7 * v
  1535.                 IF vecorig(particleindex, 2) < 80 THEN
  1536.                     veccolor(particleindex) = thePalette.Tint.Violet
  1537.                 ELSE
  1538.                     veccolor(particleindex) = thePalette.Primary.Red
  1539.                 END IF
  1540.                 GOSUB calccom
  1541.             NEXT
  1542.         NEXT
  1543.         VectorGroup(vecgroupindex).LastParticle = particleindex
  1544.         GOSUB adjustcom
  1545.     NEXT
  1546.  
  1547. 'File
  1548.     DO WHILE NOT EOF(1)
  1549.         INPUT #1, xx, yy, zz, co
  1550.         regularpoint = 1
  1551.         IF xx = -999999 AND yy = -999999 AND zz = -999999 AND co = -999999 THEN
  1552.             regularpoint = 0
  1553.             INPUT #1, n$
  1554.             vecgroupcounter = vecgroupcounter + 1
  1555.             vecgroupindex = vecgroupcounter
  1556.             VectorGroup(vecgroupindex).Identity = vecgroupindex
  1557.             VectorGroup(vecgroupindex).Pointer = vecgroupindex + 1
  1558.             VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1559.             VectorGroup(vecgroupindex).ContentName = n$
  1560.             VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1561.         END IF
  1562.         IF xx = -888888 AND yy = -888888 AND zz = -888888 AND co = -888888 THEN
  1563.             regularpoint = 0
  1564.             VectorGroup(vecgroupindex).LastParticle = particleindex
  1565.             GOSUB adjustcom
  1566.         END IF
  1567.         IF regularpoint = 1 THEN
  1568.             particleindex = particleindex + 1
  1569.             vecorig(particleindex, 1) = xx
  1570.             vecorig(particleindex, 2) = yy
  1571.             vecorig(particleindex, 3) = zz
  1572.             SELECT CASE co
  1573.                 CASE 0
  1574.                     veccolor(particleindex) = thePalette.Grayscale.Black
  1575.                 CASE 1
  1576.                     veccolor(particleindex) = thePalette.Primary.Blue
  1577.                 CASE 2
  1578.                     veccolor(particleindex) = thePalette.Primary.Green
  1579.                 CASE 3
  1580.                     veccolor(particleindex) = thePalette.Secondary.Cyan
  1581.                 CASE 4
  1582.                     veccolor(particleindex) = thePalette.Primary.Red
  1583.                 CASE 6
  1584.                     veccolor(particleindex) = thePalette.Tertiary.Orange
  1585.                 CASE 7
  1586.                     veccolor(particleindex) = thePalette.Grayscale.Lighter
  1587.                 CASE 8
  1588.                     veccolor(particleindex) = thePalette.Grayscale.Darker
  1589.                 CASE 9
  1590.                     veccolor(particleindex) = thePalette.Tint.Blue
  1591.                 CASE 10
  1592.                     veccolor(particleindex) = thePalette.Tint.Green
  1593.                 CASE 11
  1594.                     veccolor(particleindex) = thePalette.Tint.Cyan
  1595.                 CASE 12
  1596.                     veccolor(particleindex) = thePalette.Tint.Red
  1597.                 CASE 13
  1598.                     veccolor(particleindex) = thePalette.Tint.Violet
  1599.                 CASE 14
  1600.                     veccolor(particleindex) = thePalette.Secondary.Yellow
  1601.                 CASE 15
  1602.                     veccolor(particleindex) = thePalette.Grayscale.White
  1603.             END SELECT
  1604.             GOSUB calccom
  1605.         END IF
  1606.     LOOP
  1607.  
  1608. '__ZZZ
  1609. vecgroupcounter = vecgroupcounter + 1
  1610. vecgroupindex = vecgroupcounter
  1611. VectorGroup(vecgroupindex).Identity = vecgroupindex
  1612. VectorGroup(vecgroupindex).Pointer = -999
  1613. VectorGroup(vecgroupindex).Lagger = vecgroupindex - 1
  1614. VectorGroup(vecgroupindex).ContentName = "__ZZZ"
  1615. VectorGroup(vecgroupindex).FirstParticle = particleindex + 1
  1616. FOR r = 1 TO 5
  1617.     particleindex = particleindex + 1
  1618.     vecorig(particleindex, 1) = -1000
  1619.     vecorig(particleindex, 2) = -1000
  1620.     vecorig(particleindex, 3) = -1000
  1621.     veccolor(particleindex) = thePalette.Grayscale.White
  1622.     GOSUB calccom
  1623. VectorGroup(vecgroupindex).LastParticle = particleindex
  1624. GOSUB adjustcom
  1625.  
  1626. numparticleorig = particleindex
  1627.  
  1628. timeanimate:
  1629. ' requires vecgroupindex
  1630. ' protects timevar
  1631. timestep = .001
  1632. timevar = timevar + timestep
  1633. IF timevar > 10 ^ 6 THEN timevar = 0
  1634.  
  1635. IF LTRIM$(RTRIM$(VectorGroup(vecgroupindex).ContentName)) = "Clock Hands" THEN
  1636.     pin = VectorGroup(vecgroupindex).FirstParticle
  1637.     hands(1, 1) = VAL(LEFT$(TIME$, 2)) * (2 * pi / 12)
  1638.     hands(2, 1) = VAL(MID$(TIME$, 4, 2)) * (2 * pi / 60)
  1639.     hands(3, 1) = VAL(RIGHT$(TIME$, 2)) * (2 * pi / 60)
  1640.     FOR q = 1 TO 3
  1641.         FOR r = 0 TO 5 + q STEP .1
  1642.             pin = pin + 1
  1643.             vecorig(pin, 1) = 40 + r * COS(hands(q, 1) + pi / 2)
  1644.             vecorig(pin, 2) = -10
  1645.             vecorig(pin, 3) = 40 + r * SIN(hands(q, 1) + pi / 2)
  1646.         NEXT
  1647.     NEXT
  1648.  
  1649. IF LTRIM$(RTRIM$(VectorGroup(vecgroupindex).ContentName)) = "Banner" THEN
  1650.     pin = VectorGroup(vecgroupindex).FirstParticle
  1651.     t = timevar / 50
  1652.     xl = -1.9: xr = 1.9: dx = .32
  1653.     yl = -1: yr = 1: dy = .32
  1654.     xl = xl * 4: xr = xr * 4: yl = yl * 4: yr = yr * 4
  1655.     FOR i = xl TO xr STEP dx
  1656.         FOR j = yl TO yr STEP dy
  1657.             pin = pin + 1
  1658.             vecorig(pin, 1) = 70 + 1.25 * COS(i - 2 * t) ^ 2 - 1.25 * SIN(j - t) ^ 2
  1659.             vecorig(pin, 2) = 30 + i
  1660.             vecorig(pin, 3) = 40 + j
  1661.             IF vecorig(pin, 1) < 70 THEN
  1662.                 veccolor(pin) = 11
  1663.             ELSE
  1664.                 veccolor(pin) = 6
  1665.             END IF
  1666.         NEXT
  1667.     NEXT
  1668.  
  1669. IF LTRIM$(RTRIM$(VectorGroup(vecgroupindex).ContentName)) = "Hell Spawn" THEN
  1670.     FOR i = VectorGroup(vecgroupindex).FirstParticle TO VectorGroup(vecgroupindex).LastParticle
  1671.         vecorig(i, 3) = vecorig(i, 3) + .3
  1672.         IF vecorig(i, 3) > -350 THEN vecorig(i, 3) = -350 - 70
  1673.     NEXT
  1674.  
  1675. IF LTRIM$(RTRIM$(VectorGroup(vecgroupindex).ContentName)) = "Moon" THEN
  1676.     t = timevar * .00001
  1677.     FOR particleindex = VectorGroup(vecgroupindex).FirstParticle TO VectorGroup(vecgroupindex).LastParticle
  1678.         xx = vecorig(particleindex, 1)
  1679.         yy = vecorig(particleindex, 2)
  1680.         vecorig(particleindex, 1) = xx * COS(t) - yy * SIN(t)
  1681.         vecorig(particleindex, 2) = xx * SIN(t) + yy * COS(t)
  1682.         GOSUB calccom
  1683.     NEXT
  1684.     GOSUB adjustcom
  1685.  
  1686. IF LTRIM$(RTRIM$(VectorGroup(vecgroupindex).ContentName)) = "Rain" THEN
  1687.     FOR i = VectorGroup(vecgroupindex).FirstParticle TO VectorGroup(vecgroupindex).LastParticle
  1688.         vecorig(i, 3) = vecorig(i, 3) - .3
  1689.         IF vecorig(i, 3) < 0 THEN vecorig(i, 3) = 70
  1690.     NEXT
  1691.  
  1692. IF LTRIM$(RTRIM$(VectorGroup(vecgroupindex).ContentName)) = "Snake?" THEN
  1693.     pin = VectorGroup(vecgroupindex).FirstParticle
  1694.     t = timevar * .1
  1695.     FOR i = -pi TO pi STEP .005
  1696.         vecorig(pin, 1) = -10 + 5 * COS(i + t)
  1697.         vecorig(pin, 2) = -20 + 5 * SIN(i + t)
  1698.         vecorig(pin, 3) = 25 - 3 * COS(6 * i + t) * SIN(3 * i + t)
  1699.         pin = pin + 1
  1700.     NEXT
  1701.  
  1702. IF LTRIM$(RTRIM$(VectorGroup(vecgroupindex).ContentName)) = "Sparks" THEN
  1703.     dt = timestep * 100
  1704.     FOR particleindex = VectorGroup(vecgroupindex).FirstParticle TO VectorGroup(vecgroupindex).LastParticle
  1705.         vecorigvel(particleindex, 1) = vecorigvel(particleindex, 1) + vecorigacc(particleindex, 1) * timestep
  1706.         vecorigvel(particleindex, 2) = vecorigvel(particleindex, 2) + vecorigacc(particleindex, 2) * dt
  1707.         vecorigvel(particleindex, 3) = vecorigvel(particleindex, 3) + vecorigacc(particleindex, 3) * dt
  1708.         vecorig(particleindex, 1) = vecorig(particleindex, 1) + vecorigvel(particleindex, 1) * dt
  1709.         vecorig(particleindex, 2) = vecorig(particleindex, 2) + vecorigvel(particleindex, 2) * dt
  1710.         vecorig(particleindex, 3) = vecorig(particleindex, 3) + vecorigvel(particleindex, 3) * dt
  1711.         IF vecorig(particleindex, 3) < 0 THEN
  1712.             vecorig(particleindex, 3) = 0
  1713.             vecorigvel(particleindex, 1) = vecorigvel(particleindex, 1) * .75
  1714.             vecorigvel(particleindex, 2) = vecorigvel(particleindex, 2) * .75
  1715.             vecorigvel(particleindex, 3) = -vecorigvel(particleindex, 3) * .5
  1716.         END IF
  1717.         GOSUB calccom
  1718.     NEXT
  1719.     GOSUB adjustcom
  1720.  
  1721. IF LTRIM$(RTRIM$(VectorGroup(vecgroupindex).ContentName)) = "UFO!!!" THEN
  1722.     dt = timestep
  1723.     FOR particleindex = VectorGroup(vecgroupindex).FirstParticle TO VectorGroup(vecgroupindex).LastParticle
  1724.         xx = vecorig(particleindex, 1) - 150
  1725.         yy = vecorig(particleindex, 2) - 150
  1726.         vecorig(particleindex, 1) = xx * COS(dt) - yy * SIN(dt) + 150
  1727.         vecorig(particleindex, 2) = xx * SIN(dt) + yy * COS(dt) + 150
  1728.         GOSUB calccom
  1729.     NEXT
  1730.     GOSUB adjustcom
  1731.  
  1732.  
  1733. explode:
  1734. vecgroupindex = VectorGroup(1).Identity
  1735.     IF LTRIM$(RTRIM$(VectorGroup(vecgroupindex).ContentName)) = "Sparks" THEN
  1736.         FOR particleindex = VectorGroup(vecgroupindex).FirstParticle TO VectorGroup(vecgroupindex).LastParticle
  1737.             vecorig(particleindex, 1) = explodex
  1738.             vecorig(particleindex, 2) = explodey
  1739.             vecorig(particleindex, 3) = explodez
  1740.             vecorigvel(particleindex, 1) = (RND - .5) * 20
  1741.             vecorigvel(particleindex, 2) = (RND - .5) * 20
  1742.             vecorigvel(particleindex, 3) = (RND - .2) * 40
  1743.             vecorigacc(particleindex, 3) = -30
  1744.             GOSUB calccom
  1745.         NEXT
  1746.         GOSUB adjustcom
  1747.         EXIT DO
  1748.     END IF
  1749.     vecgroupindex = VectorGroup(vecgroupindex).Pointer
  1750.     IF vecgroupindex = -999 THEN EXIT DO
  1751.     vecgroupindex = VectorGroup(vecgroupindex).Identity
  1752.  
  1753. calccom:
  1754. VectorGroup(vecgroupindex).COMx = vecorig(particleindex, 1) + VectorGroup(vecgroupindex).COMx
  1755. VectorGroup(vecgroupindex).COMy = vecorig(particleindex, 2) + VectorGroup(vecgroupindex).COMy
  1756. VectorGroup(vecgroupindex).COMz = vecorig(particleindex, 3) + VectorGroup(vecgroupindex).COMz
  1757.  
  1758. adjustcom:
  1759. f = 1 + VectorGroup(vecgroupindex).LastParticle - VectorGroup(vecgroupindex).FirstParticle
  1760. VectorGroup(vecgroupindex).COMx = VectorGroup(vecgroupindex).COMx / f
  1761. VectorGroup(vecgroupindex).COMy = VectorGroup(vecgroupindex).COMy / f
  1762. VectorGroup(vecgroupindex).COMz = VectorGroup(vecgroupindex).COMz / f
  1763.  
  1764.  
  1765.  
matrix.png
* matrix.png (Filesize: 265.65 KB, Dimensions: 1366x768, Views: 220)
matrix2.png
* matrix2.png (Filesize: 308.91 KB, Dimensions: 1366x768, Views: 215)
I am from a Kazakhstan, we follow the hawk.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
Re: Sanctum: Open world 3D engine using CIRCLE and LINE
« Reply #16 on: February 05, 2019, 03:04:22 am »
Thanks keybone for giving it a stab.

The code in the top post, along with the attached level, has been updated to include an update I can't stop playing with - the creation and destruction of level elements. In a minecraft-like fashion, you can walk up to things and blow them up by pressing k, and place new blocks by pressing b. (Instructions are on screen.)

I captured a second video, but am reluctant to paste the link because it won't record without looking choppy. I guess you guys would be the first to know its not the programs fault, haha.

https://youtu.be/h-CoXJ-kT6k

Anyway, thanks for your interest and participation!

EDIT

Oh yeah, the color scheme has graduated from SCREEN 12 to 32 bit. You'll need Color32.BI attached at the top, something I gutted from one of Steve's projects. (Where this info was before he got it, I don't know, so the chain of citation stops there.)
« Last Edit: February 05, 2019, 03:07:00 am by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
Re: Sanctum: Open world 3D engine using CIRCLE and LINE
« Reply #17 on: February 06, 2019, 11:22:38 am »
Nice program STxAxTIC.  I think this would be a great look for a 3D surface plotting graphing calculator! Can it be used to plot parametric surfaces? https://en.wikipedia.org/wiki/Parametric_surface

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
Re: Sanctum: Open world 3D engine using CIRCLE and LINE
« Reply #18 on: February 07, 2019, 09:25:55 am »
Awesome 3D Explorer STxAxTIC!
I discovered sky, lake of fire, stars.... It is very beautifully coded. :)
BTW, What's the name of the girl whose picture is used in the program?
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
Re: Sanctum: Open world 3D engine using CIRCLE and LINE
« Reply #19 on: February 07, 2019, 09:54:52 am »
Ah, many thanks Ashish!

I appreciate your adventurous spirit to have explored so many aspects of the map.

So the girl, according to our new friend Robert Frost, is named Heather Thomas. By that picture, it looks like she flourished in the early 1990s, but I didn't search for her on Google or anything like that. A little more research is needed on my part if I'm going to keep that image in the long-term, I suppose.

Thanks again, and check again soon!
You're not done when it works, you're done when it's right.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
Re: Sanctum: Open world 3D engine using CIRCLE and LINE
« Reply #20 on: February 07, 2019, 10:22:39 am »
Heather Thomas was a hottie actress in Fall Guy, starring Lee Majors (formerly The Six Million Dollar Man, which today could only be a guy with a hip replacement, but I digress...) back in the 1980's, so you're only a decade off. Not bad. I recall, because I'm old as dirt and I used to watch the show. I just don't know why I recalled Lee Majors was in it? I hardly ever saw him when I was watching that series, for a couple of reasons I won't go into.

Pete :D
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
Re: Sanctum: Open world 3D engine using CIRCLE and LINE
« Reply #21 on: February 12, 2019, 07:20:56 pm »
@vince

Holy crap, how did I miss your question? Yes, this can be used to plot parametric equations in 3+1D. (in fact every object in here *is* a parametric plot) This project grew out of a ridiculous engine I wrote once... for history's sake I'll post it here but keep in mind it's a giant prototype. I was advised that there may even be patent-able code in here but I don't have a single entrepreneurial bone in my body, so never-mind that. (I haven't posted this in years.)

Code: QB64: [Select]
  1. '#lang "qb" '...for freebasic compiler. Must disable for QB64 features.
  2.  
  3. ' *** Video settings. ***
  4.  
  5. screenwidth = 640
  6. screenheight = 480
  7.  
  8. ' *** Performance settings. ***
  9.  
  10. bignumber = 500000 ' Maximum objects per array (determined by memory).
  11. globaldelayinit = 1000 ' Loop damping factor (fine adjustment below).
  12.  
  13. ' *** Initialize counters and array sizes. ***
  14.  
  15. numparticleorig = bignumber
  16. numparticlevisible = bignumber
  17. numdoubletorig = bignumber
  18. numdoubletclip = bignumber
  19. numdoubletclipwork = bignumber
  20. numdoubletsnip = bignumber
  21. numdoubletsnipwork = bignumber
  22. numdoubletintinfo = bignumber
  23. numtripletorig = bignumber
  24. numtripletfaceon = bignumber
  25. numtripletclip = bignumber
  26. numtripletclipwork = bignumber
  27. numtripletsnip = bignumber
  28. numtripletsnipimage = bignumber
  29. numtripletsnipwork = bignumber
  30. numtripletencpoint = bignumber
  31. numtripletintpointpair = bignumber
  32. numtripletfinal = bignumber
  33.  
  34. ' *** Define basis arrays and structures. ***
  35.  
  36. ' Screen vectors in three-space.
  37. ' These vectors define the camera angle.
  38. DIM uhat(1 TO 3), vhat(1 TO 3), nhat(1 TO 3)
  39.  
  40. ' View clipping planes defined in three-space.
  41. DIM nearplane(1 TO 4), farplane(1 TO 4), rightplane(1 TO 4), leftplane(1 TO 4), topplane(1 TO 4), bottomplane(1 TO 4)
  42. DIM nearplanespotlight(1 TO 4), farplanespotlight(1 TO 4), rightplanespotlight(1 TO 4), leftplanespotlight(1 TO 4), topplanespotlight(1 TO 4), bottomplanespotlight(1 TO 4)
  43.  
  44. ' Basis vectors defined in three-space.
  45. DIM xhat(1 TO 4), yhat(1 TO 4), zhat(1 TO 4)
  46. xhat(1) = 1: xhat(2) = 0: xhat(3) = 0: xhat(4) = 4
  47. yhat(1) = 0: yhat(2) = 1: yhat(3) = 0: yhat(4) = 2
  48. zhat(1) = 0: zhat(2) = 0: zhat(3) = 1: zhat(4) = 1
  49.  
  50. ' Basis vectors projected into uv two-space.
  51. DIM xhatp(1 TO 2), yhatp(1 TO 2), zhatp(1 TO 2)
  52. DIM xhatp.old(1 TO 2), yhatp.old(1 TO 2), zhatp.old(1 TO 2)
  53.  
  54. ' *** Define particle arrays and structures. ***
  55.  
  56. ' Particle vectors defined in three-space.
  57. DIM vec(numparticleorig, 4)
  58. DIM vecdotnhat(numparticleorig)
  59. DIM vecdotnhatunit.old(numparticleorig)
  60. DIM vecvisible(numparticlevisible, 4)
  61. DIM vecvisibledotnhat(numparticlevisible)
  62. DIM vecvisibledotnhatunit.old(numparticlevisible)
  63.  
  64. ' Particle vectors projected onto infinite uv two-space.
  65. DIM vecpuv(numparticleorig, 1 TO 2)
  66. DIM vecpuv.old(numparticleorig, 1 TO 2)
  67. DIM vecvisiblepuv(numparticlevisible, 1 TO 2)
  68. DIM vecvisiblepuv.old(numparticlevisible, 1 TO 2)
  69.  
  70. ' Particle projections adjusted for screen uv two-space.
  71. DIM vecpuvs(numparticleorig, 1 TO 2)
  72. DIM vecpuvs.old(numparticleorig, 1 TO 2)
  73. DIM vecvisiblepuvs(numparticlevisible, 1 TO 2)
  74. DIM vecvisiblepuvs.old(numparticlevisible, 1 TO 2)
  75.  
  76. ' *** Define doublet arrays and structures. ***
  77.  
  78. ' Doublet vectors defined in three-space.
  79. DIM doubletorig(numdoubletorig, 7)
  80.  
  81. ' Doublet vectors clipped by view planes.
  82. DIM doubletclip(numdoubletclip, 7)
  83. DIM doubletclipdotnhat(numdoubletclip, 2)
  84. DIM doubletclipdotnhat.old(numdoubletclip, 2)
  85. DIM doubletclipwork(numdoubletclipwork, 7)
  86. DIM doubletclipworkdotnhat(numdoubletclipwork, 2)
  87. DIM doubletclipworkdotnhat.old(numdoubletclipwork, 2)
  88.  
  89. ' Doublet vectors clipped and projected onto infinite uv two-space.
  90. DIM doubletclippuv(numdoubletclip, 4)
  91. DIM doubletclippuv.old(numdoubletclip, 4)
  92.  
  93. ' Doublet vectors snipped by apparent intersections.
  94. DIM doubletsnip(numdoubletsnip, 7)
  95. DIM doubletsnipwork(numdoubletsnipwork, 7)
  96. DIM doubletsnipdotnhat(numdoubletsnip, 2)
  97. DIM doubletsnipdotnhat.old(numdoubletsnip, 2)
  98.  
  99. ' Doublet vectors snipped and projected onto infinite uv two-space.
  100. DIM doubletsnippuv(numdoubletsnip, 4)
  101. DIM doubletsnippuv.old(numdoubletsnip, 4)
  102.  
  103. ' Array information inferred from apparent intersections.
  104. DIM doubletintinfo(numdoubletintinfo, 2)
  105.  
  106. ' Doublet projections adjusted for screen uv two-space.
  107. DIM doubletsnippuvs(numdoubletsnip, 4)
  108. DIM doubletsnippuvs.old(numdoubletsnip, 4)
  109. DIM doubletclippuvs(numdoubletclip, 4)
  110. DIM doubletclippuvs.old(numdoubletclip, 4)
  111.  
  112. ' *** Define triplet arrays and structures. ***
  113.  
  114. ' Triplet vectors defined in three-space.
  115. DIM tripletorig(numtripletorig, 10)
  116.  
  117. ' Triplet vectors after discarding outfacing members.
  118. DIM tripletfaceon(numtripletfaceon, 10)
  119. DIM tripletfaceondotnhat(numtripletfaceon, 3)
  120. DIM tripletfaceondotnhat.old(numtripletfaceon, 3)
  121.  
  122. ' Triplet vectors clipped by view planes.
  123. DIM tripletclip(numtripletclip, 10)
  124. DIM tripletclipdotnhat(numtripletclip, 3)
  125. DIM tripletclipdotnhat.old(numtripletclip, 3)
  126. DIM tripletclipwork(numtripletclipwork, 10)
  127. DIM tripletclipworkdotnhat(numtripletclipwork, 3)
  128. DIM tripletclipworkdotnhat.old(numtripletclipwork, 3)
  129.  
  130. ' Triplet vectors clipped and projected onto infinite uv two-space.
  131. DIM tripletfaceonpuv(numtripletfaceon, 6)
  132. DIM tripletfaceonpuv.old(numtripletfaceon, 6)
  133. DIM tripletclippuv(numtripletclip, 6)
  134. DIM tripletclippuv.old(numtripletclip, 6)
  135.  
  136. ' Triplet vectors snipped by apparent intersections.
  137. DIM tripletsnip(numtripletsnip, 10)
  138. DIM tripletsnipimage(numtripletsnipimage, 10)
  139. DIM tripletsnipwork(numtripletsnipwork, 10)
  140. DIM tripletsnipdotnhat(numtripletsnip, 3)
  141. DIM tripletsnipdotnhat.old(numtripletsnip, 3)
  142. DIM tripletfinal(numtripletfinal, 10)
  143. DIM tripletfinaldotnhat(numtripletfinal, 3)
  144. DIM tripletfinaldotnhat.old(numtripletfinal, 3)
  145.  
  146. ' Triplet vectors snipped and projected onto infinite uv two-space.
  147. 'DIM tripletsnippuv(numtripletsnip, 7)
  148. 'DIM tripletsnippuv.old(numtripletsnip, 7)
  149. DIM tripletfinalpuv(numtripletfinal, 7)
  150. DIM tripletfinalpuv.old(numtripletfinal, 7)
  151.  
  152. ' Array information inferred from apparent intersections.
  153. DIM tripletencpoint(9, 8)
  154. DIM tripletintpointpair(9, 21)
  155.  
  156. ' Triplet projections adjusted for screen uv two-space.
  157. DIM tripletfinalpuvs(numtripletfinal, 6)
  158. DIM tripletfinalpuvs.old(numtripletfinal, 6)
  159.  
  160. ' *** Define specialized arrays and structures. ***
  161.  
  162. ' Arrays for tech 2 mesh plotting.
  163. DIM plotflag(numparticleorig)
  164. DIM plotflag.old(numparticleorig)
  165.  
  166. ' Binary switches for triangle snip algorithm.
  167. snip000enabled = 1
  168. snip004enabled = 1
  169. snip030enabled = 1
  170. snip003enabled = 1
  171. snip006enabled = 1
  172. snip012enabled = 1
  173. snip102enabled = 1
  174. snip112enabled = 1
  175. snip022enabled = 1
  176. snip202enabled = 1
  177. snip122enabled = 1
  178. snip212enabled = 1
  179. snip014enabled = 1
  180. snip104enabled = 1
  181. snip114enabled = 1
  182.  
  183. ' *** Set mathematical constants. ***
  184.  
  185. pi = 3.1415926536
  186. ee = 2.7182818285
  187.  
  188. mainstart:
  189.  
  190. ' *** Initialize user input variables. ***
  191. key$ = ""
  192. 'mousekey$ = ""
  193.  
  194. ' *** Show first visual. ***
  195.  
  196. PRINT " *** Welcome to 3DCTRWGRAPH ***"
  197. PRINT "     by: William F. Barnes"
  198. PRINT " 3D Graphics and Physics Engine"
  199. PRINT " -3D World Prototypes-"
  200. PRINT " 1:  3D world made of only particles. (Type 'file' to load object3d.txt)"
  201. PRINT " 2:  3D world made of line segments with three-space clipping feature."
  202. PRINT " 3:  3D polygon world using advanded three-space clipping algorithm."
  203. PRINT " -Plotting and Geometry Demonstrations-"
  204. PRINT " 4:  Parameterized curve with linear point connecting."
  205. PRINT " 5:  Parameterized surface made of single points."
  206. PRINT " 6:  Molecule with atoms connected by lines."
  207. PRINT " 7:  Abstract 3D objects with near-neighbor tiling."
  208. PRINT " 8:  Time-animated surface in simple mesh tiling."
  209. PRINT " 9:  Time-animated surface in tech-2 mesh tiling."
  210. PRINT " 10: Spherical harmonics (in development) in single point plot mode."
  211. PRINT " -Physics Engine Demonstrations-"
  212. PRINT " 11: Solution to 2D Laplace equation via relaxation in tech-2 mesh tiling."
  213. PRINT " 12: Sphere with random surface features in tech-2 custom mesh tiling."
  214. PRINT " 13: Wave 2D propagation on flexible membrane in simple mesh tiling."
  215. PRINT " 14: Waves on infinite surface in simple mesh tiling."
  216. PRINT " 15: Brownian mating bacteria in custom single point plot mode."
  217. PRINT " 16: Elementary neural network with three-space neighbor-connections."
  218. PRINT: INPUT " Enter a choice (99 to quit) and press ENTER: ", a$
  219.  
  220. ' *** Process first user input. ***
  221.  
  222.     CASE "1": genscheme$ = "3denvparticles": plotmode$ = "3denvparticles"
  223.     CASE "file": genscheme$ = "3denvparticlesfile": plotmode$ = "3denvparticles"
  224.     CASE "2": genscheme$ = "3denvdoublets": plotmode$ = "3denvdoublets"
  225.     CASE "3": genscheme$ = "3denvtriplets": plotmode$ = "3denvtriplets"
  226.     CASE "4": genscheme$ = "curve": plotmode$ = "linearconnect"
  227.     CASE "5": genscheme$ = "simplepoints": plotmode$ = "simplepoints"
  228.     CASE "6": genscheme$ = "molecule": plotmode$ = "molecule"
  229.     CASE "7": genscheme$ = "neighbortile": plotmode$ = "neighbortile"
  230.     CASE "8": genscheme$ = "animatedflag": plotmode$ = "simplemesh"
  231.     CASE "9": genscheme$ = "animatedpretzel": plotmode$ = "meshtech2"
  232.     CASE "10": genscheme$ = "sphericalharmonics": plotmode$ = "simplepoints"
  233.     CASE "11": genscheme$ = "laplace2d": plotmode$ = "meshtech2"
  234.     CASE "12": genscheme$ = "planet": plotmode$ = "meshtech2planet"
  235.     CASE "13": genscheme$ = "wave2d": plotmode$ = "simplemesh"
  236.     CASE "14": genscheme$ = "wave2dinf": plotmode$ = "simplemesh"
  237.     CASE "15": genscheme$ = "bacteria": plotmode$ = "simplepointsbacteria"
  238.     CASE "16": genscheme$ = "neuron": plotmode$ = "linearneuron"
  239.     CASE "99": END
  240.     CASE ELSE: GOTO mainstart
  241.  
  242. substart:
  243.  
  244. ' *** Zero counters and array sizes. ***
  245.  
  246. numparticleorig = 0
  247. numparticlevisible = 0
  248. numdoubletorig = 0
  249. numdoubletclip = 0
  250. numdoubletclipwork = 0
  251. numdoubletsnip = 0
  252. numdoubletsnipwork = 0
  253. numdoubletintinfo = 0
  254. numtripletorig = 0
  255. numtripletfaceon = 0
  256. numtripletclip = 0
  257. numtripletclipwork = 0
  258. numtripletsnip = 0
  259. numtripletsnipimage = 0
  260. numtripletsnipwork = 0
  261. numtripletencpoint = 0
  262. numtripletintpointpair = 0
  263. numtripletfinal = 0
  264. pcountparticleorig = 0
  265. pcountdoubletorig = 0
  266. pcounttripletorig = 0
  267.  
  268. ' *** Constants and switch control. ***
  269.  
  270. ' Perspective and animation switches/defaults.
  271. fovd = -256
  272. nearplane(4) = 3
  273. farplane(4) = -100
  274. rightplane(4) = 0 '*' fovd * (nhat(1) * rightplane(1) + nhat(2) * rightplane(2) + nhat(3) * rightplane(3))
  275. leftplane(4) = 0
  276. topplane(4) = 0
  277. bottomplane(4) = 0
  278. spotlightwidth = 1.3
  279. spotlightthickness = 3
  280. spotlightwidth = 1.3
  281. spotlightcenter = 20
  282. nearplanespotlight(4) = spotlightcenter - spotlightthickness / 2
  283. farplanespotlight(4) = -(spotlightcenter + spotlightthickness / 2)
  284. rightplanespotlight(4) = 0
  285. leftplanespotlight(4) = 0
  286. topplanespotlight(4) = 0
  287. bottomplanespotlight(4) = 0
  288. centerx = screenwidth / 2
  289. centery = screenheight / 2
  290. speedconst = 50
  291. falsedepth = .01
  292. zoom = 30
  293. timevar = 0
  294. T = 0
  295. togglehud = 1
  296. toggleatomnumbers = -1
  297. toggletimeanimate = -1
  298. toggletimealert = 0
  299. camx = 0
  300. camy = 0
  301. camz = 0
  302. uhat(1) = -3: uhat(2) = 5: uhat(3) = 1 / 4
  303. vhat(1) = -1: vhat(2) = -1: vhat(3) = 8
  304.  
  305.  
  306. SELECT CASE LCASE$(genscheme$)
  307.     CASE "curve":
  308.         GOSUB genscheme.curve
  309.         numparticleorig = pcountparticleorig
  310.     CASE "simplepoints":
  311.         uhat(1) = -0.2376385: uhat(2) = 0.970313: uhat(3) = -0.04495043
  312.         vhat(1) = -0.8201708: vhat(2) = -0.1756434: vhat(3) = 0.5444899
  313.         GOSUB genscheme.simplepoints
  314.         numparticleorig = pcountparticleorig
  315.     CASE "3denvparticles":
  316.         globaldelay = globaldelayinit * 1000
  317.         uhat(1) = 0.8251367: uhat(2) = -0.564903: uhat(3) = -0.005829525
  318.         vhat(1) = 0.065519: vhat(2) = 0.08544215: vhat(3) = 0.9941866
  319.         falsedepth = 0
  320.         zoom = 1.95
  321.         toggletimeanimate = 1
  322.         togglehud = -1
  323.         toggletimealert = 1
  324.         camx = 30
  325.         camy = 25
  326.         camz = -25
  327.         GOSUB genscheme.3denvparticles.init
  328.         numparticleorig = pcountparticleorig
  329.     CASE "3denvparticlesfile":
  330.         uhat(1) = 0.8251367: uhat(2) = -0.564903: uhat(3) = -0.005829525
  331.         vhat(1) = 0.065519: vhat(2) = 0.08544215: vhat(3) = 0.9941866
  332.         falsedepth = 0
  333.         zoom = 1.95
  334.         togglehud = -1
  335.         camx = 30
  336.         camy = 30
  337.         camz = -25
  338.         pcountparticleorig = 0
  339.         OPEN "object3d.txt" FOR INPUT AS #1
  340.         DO
  341.             pcountparticleorig = pcountparticleorig + 1
  342.             INPUT #1, vec(pcountparticleorig, 1), vec(pcountparticleorig, 2), vec(pcountparticleorig, 3), vec(pcountparticleorig, 4)
  343.         LOOP WHILE EOF(1) = 0
  344.         CLOSE #1
  345.         numparticleorig = pcountparticleorig
  346.     CASE "molecule":
  347.         uhat(1) = -0.7027042: uhat(2) = 0.5818964: uhat(3) = -0.409394
  348.         vhat(1) = -0.6446534: vhat(2) = -0.2772641: vhat(3) = 0.7124231
  349.         zoom = 55
  350.         togglehud = -1
  351.         toggleatomnumbers = 1
  352.         numparticleorig = 12
  353.         REDIM vec(numparticleorig, 10)
  354.         REDIM vecvisible(numparticleorig, 10)
  355.         FOR i = 1 TO numparticleorig
  356.             READ vec(i, 1), vec(i, 2), vec(i, 3), vec(i, 4), vec(i, 5), vec(i, 6), vec(i, 7), vec(i, 8), vec(i, 9), vec(i, 10)
  357.         NEXT
  358.         GOSUB genscheme.molecule
  359.     CASE "neighbortile":
  360.         GOSUB genscheme.neighbortile
  361.         numparticleorig = pcountparticleorig
  362.     CASE "3denvdoublets":
  363.         uhat(1) = 0.7941225: uhat(2) = -0.6026734: uhat(3) = -0.07844898
  364.         vhat(1) = 0.2287595: vhat(2) = 0.1768191: vhat(3) = 0.95729
  365.         falsedepth = 0
  366.         zoom = 1.95
  367.         camx = 30
  368.         camy = 45
  369.         camz = -25
  370.         GOSUB genscheme.3denvdoublets
  371.         numparticleorig = pcountparticleorig
  372.         numdoubletorig = pcountdoubletorig
  373.     CASE "3denvtriplets":
  374.         uhat(1) = 0.470269: uhat(2) = -0.8823329: uhat(3) = -0.01832148
  375.         vhat(1) = -0.03788515: vhat(2) = -0.0409245: vhat(3) = 0.9984438
  376.         falsedepth = 0
  377.         zoom = 1.95
  378.         camx = 20
  379.         camy = 20
  380.         camz = 17
  381.         GOSUB genscheme.3denvtriplets
  382.         numparticleorig = pcountparticleorig
  383.         numtripletorig = pcounttripletorig
  384.     CASE "animatedflag":
  385.         globaldelay = globaldelayinit * 5000
  386.         toggletimeanimate = 1
  387.         togglehud = -1
  388.         toggletimealert = 1
  389.         uhat(1) = .7802773: uhat(2) = -.4759201: uhat(3) = .4058135
  390.         vhat(1) = .2502121: vhat(2) = .8321912: vhat(3) = .4948249
  391.         GOSUB genscheme.animatedsurface.init
  392.         numparticleorig = pcountparticleorig
  393.         REDIM vec2dztemp(xrange, yrange)
  394.         GOSUB genschemeUSAcolors
  395.     CASE "animatedpretzel":
  396.         globaldelay = globaldelayinit * 5000
  397.         uhat(1) = .7802773: uhat(2) = -.4759201: uhat(3) = .4058135
  398.         vhat(1) = .2502121: vhat(2) = .8321912: vhat(3) = .4948249
  399.         toggletimealert = 1
  400.         GOSUB genscheme.animatedpretzel.init
  401.         numparticleorig = pcountparticleorig
  402.     CASE "sphericalharmonics":
  403.         GOSUB genscheme.sphericalharmonics
  404.         numparticleorig = pcountparticleorig
  405.     CASE "laplace2d":
  406.         uhat(1) = 0.4919244: uhat(2) = 0.869175: uhat(3) = 0.0504497
  407.         vhat(1) = -0.2520696: vhat(2) = 0.08672012: vhat(3) = 0.9638156
  408.         globaldelay = globaldelayinit * 1500
  409.         togglehud = -1
  410.         toggletimealert = 1
  411.         GOSUB genscheme.laplace2d.init
  412.         numparticleorig = pcountparticleorig
  413.         REDIM vec2dz(xrange, yrange)
  414.         REDIM vec2dztemp(xrange, yrange)
  415.         REDIM vec2dzfixed(xrange, yrange)
  416.         GOSUB genscheme.laplace2d.gridinit
  417.     CASE "planet":
  418.         globaldelay = globaldelayinit * 1500
  419.         uhat(1) = 0.4868324: uhat(2) = 0.8719549: uhat(3) = -0.05185585
  420.         vhat(1) = 0.458436: vhat(2) = -0.2045161: vhat(3) = 0.8648755
  421.         togglehud = -1
  422.         toggletimealert = 1
  423.         GOSUB genscheme.planet.init
  424.         numparticleorig = pcountparticleorig
  425.         REDIM vec2ds(xrange, yrange)
  426.         REDIM vec2dstemp(xrange, yrange)
  427.         REDIM vec2dsfixed(xrange, yrange)
  428.         GOSUB genscheme.planet.gridinit
  429.     CASE "wave2d":
  430.         globaldelay = globaldelayinit * 1500
  431.         uhat(1) = .7802773: uhat(2) = -.4759201: uhat(3) = .4058135
  432.         vhat(1) = .2502121: vhat(2) = .8321912: vhat(3) = .4948249
  433.         togglehud = -1
  434.         toggletimealert = 1
  435.         GOSUB genscheme.wave2d.init
  436.         numparticleorig = pcountparticleorig
  437.         REDIM vec2dz(xrange, yrange)
  438.         REDIM vec2dztemp(xrange, yrange)
  439.         REDIM vec2dzprev(xrange, yrange)
  440.         GOSUB genschemeUSAcolors
  441.         GOSUB genscheme.wave2d.gridinit
  442.     CASE "wave2dinf":
  443.         globaldelay = globaldelayinit * 4000
  444.         uhat(1) = 0.6781088: uhat(2) = 0.7263383: uhat(3) = 0.1122552
  445.         vhat(1) = -0.4469305: vhat(2) = 0.2862689: vhat(3) = 0.8475278
  446.         toggletimeanimate = 1
  447.         togglehud = -1
  448.         toggletimealert = 1
  449.         GOSUB genscheme.wave2dinf.init
  450.         numparticleorig = pcountparticleorig
  451.         REDIM vec2dz(xrange, yrange)
  452.         REDIM vec2dztemp(xrange, yrange)
  453.         REDIM vec2dzfixed(xrange, yrange)
  454.         REDIM vec2dzprev(xrange, yrange)
  455.         GOSUB genscheme.wave2dinf.gridinit
  456.     CASE "bacteria":
  457.         falsedepth = 0.001
  458.         globaldelay = globaldelayinit
  459.         toggletimeanimate = 1
  460.         toggletimealert = 1
  461.         zoom = 3
  462.         numcreatures = 300
  463.         REDIM vec(numcreatures, 10)
  464.         REDIM vecvisible(numcreatures, 10)
  465.         GOSUB genscheme.bacteria.init
  466.         numparticleorig = pcountparticleorig
  467.     CASE "neuron":
  468.         globaldelay = globaldelayinit
  469.         uhat(1) = 0.3494484: uhat(2) = -0.9331037: uhat(3) = -0.08487199
  470.         vhat(1) = 0.4430568: vhat(2) = 0.08476364: vhat(3) = 0.8924774
  471.         toggletimeanimate = 1
  472.         toggletimealert = 1
  473.         togglehud = -1
  474.         zoom = 1.5
  475.         falsedepth = 0.001
  476.         REDIM vec(bignumber, 15)
  477.         REDIM vecvisible(bignumber, 15)
  478.         REDIM vecpuvsrev(bignumber, 15)
  479.         GOSUB genscheme.neuron.init
  480.         numparticleorig = pcountparticleorig
  481.  
  482. ' Move objects to accomodate initial camera position.
  483. IF camx <> 0 AND camy <> 0 AND camz <> 0 THEN
  484.     FOR i = 1 TO numparticleorig
  485.         vec(i, 1) = vec(i, 1) + camx
  486.         vec(i, 2) = vec(i, 2) + camy
  487.         vec(i, 3) = vec(i, 3) + camz
  488.     NEXT
  489.     FOR i = 1 TO numdoubletorig
  490.         doubletorig(i, 1) = doubletorig(i, 1) + camx
  491.         doubletorig(i, 2) = doubletorig(i, 2) + camy
  492.         doubletorig(i, 3) = doubletorig(i, 3) + camz
  493.         doubletorig(i, 4) = doubletorig(i, 4) + camx
  494.         doubletorig(i, 5) = doubletorig(i, 5) + camy
  495.         doubletorig(i, 6) = doubletorig(i, 6) + camz
  496.     NEXT
  497.     FOR i = 1 TO numtripletorig
  498.         tripletorig(i, 1) = tripletorig(i, 1) + camx
  499.         tripletorig(i, 2) = tripletorig(i, 2) + camy
  500.         tripletorig(i, 3) = tripletorig(i, 3) + camz
  501.         tripletorig(i, 4) = tripletorig(i, 4) + camx
  502.         tripletorig(i, 5) = tripletorig(i, 5) + camy
  503.         tripletorig(i, 6) = tripletorig(i, 6) + camz
  504.         tripletorig(i, 7) = tripletorig(i, 7) + camx
  505.         tripletorig(i, 8) = tripletorig(i, 8) + camy
  506.         tripletorig(i, 9) = tripletorig(i, 9) + camz
  507.     NEXT
  508.  
  509. GOSUB redraw
  510.  
  511. ' *** Begin main loop. ***
  512.     IF toggletimeanimate = 1 THEN
  513.         GOSUB timeanimate
  514.         flagredraw = 1
  515.     END IF
  516.     IF flagredraw = 1 THEN
  517.         GOSUB redraw
  518.         flagredraw = -1
  519.     END IF
  520.     'GOSUB mouseprocess
  521.     GOSUB keyprocess
  522.     IF toggletimeanimate = 1 THEN
  523.         FOR delaycount = 1 TO globaldelay: NEXT
  524.     END IF
  525. ' *** End main loop. ***
  526.  
  527. ' *** Begin function definitions. ***
  528.  
  529. ' Comment out the conents of this gosub for non-QB64 compiler.
  530. mouseprocess:
  531. 'DO
  532. '    IF _MOUSEMOVEMENTX > 0 THEN
  533. '        mousekey$ = "6"
  534. '        GOSUB rotate.uhat.plus: GOSUB normalize.screen.vectors: flagredraw = 1
  535. '    END IF
  536. '    IF _MOUSEMOVEMENTX < 0 THEN
  537. '        mousekey$ = "4"
  538. '        GOSUB rotate.uhat.minus: GOSUB normalize.screen.vectors: flagredraw = 1
  539. '    END IF
  540. '    IF _MOUSEMOVEMENTY > 0 THEN
  541. '        mousekey$ = "8"
  542. '        GOSUB rotate.vhat.plus: GOSUB normalize.screen.vectors: flagredraw = 1
  543. '    END IF
  544. '    IF _MOUSEMOVEMENTY < 0 THEN
  545. '       mousekey$ = "2"
  546. '       GOSUB rotate.vhat.minus: GOSUB normalize.screen.vectors: flagredraw = 1
  547. '   END IF
  548. '   MouseLB = _MOUSEBUTTON(1)
  549. '   MouseRB = _MOUSEBUTTON(2)
  550. 'LOOP WHILE _MOUSEINPUT
  551.  
  552. keyprocess:
  553. 'IF mousekey$ <> "" THEN
  554. '    key$ = mousekey$
  555. '    mousekey$ = ""
  556. 'ELSE
  557. 'END IF
  558. IF key$ <> "" THEN
  559.     flagredraw = 1
  560.     CASE "8":
  561.         GOSUB rotate.vhat.plus
  562.     CASE "2":
  563.         GOSUB rotate.vhat.minus
  564.     CASE "4":
  565.         GOSUB rotate.uhat.minus
  566.     CASE "6":
  567.         GOSUB rotate.uhat.plus
  568.     CASE "7":
  569.         GOSUB rotate.clockwise
  570.     CASE "9":
  571.         GOSUB rotate.counterclockwise
  572.     CASE "1":
  573.         GOSUB rotate.uhat.minus: GOSUB normalize.screen.vectors: GOSUB rotate.clockwise
  574.     CASE "3":
  575.         GOSUB rotate.uhat.plus: GOSUB normalize.screen.vectors: GOSUB rotate.counterclockwise
  576.     CASE "w"
  577.         GOSUB strafe.objects.nhat.plus
  578.         GOSUB strafe.camera.nhat.plus
  579.     CASE "s"
  580.         GOSUB strafe.objects.nhat.minus
  581.         GOSUB strafe.camera.nhat.minus
  582.     CASE "a"
  583.         GOSUB strafe.objects.uhat.plus
  584.         GOSUB strafe.camera.uhat.plus
  585.     CASE "d"
  586.         GOSUB strafe.objects.uhat.minus
  587.         GOSUB strafe.camera.uhat.minus
  588.     CASE "q"
  589.         GOSUB strafe.objects.vhat.plus
  590.         GOSUB strafe.camera.vhat.plus
  591.     CASE "e"
  592.         GOSUB strafe.objects.vhat.minus
  593.         GOSUB strafe.camera.vhat.minus
  594.     CASE "x"
  595.         uhat(1) = 0: uhat(2) = 1: uhat(3) = 0
  596.         vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
  597.     CASE "y"
  598.         uhat(1) = 0: uhat(2) = 0: uhat(3) = 1
  599.         vhat(1) = 1: vhat(2) = 0: vhat(3) = 0
  600.     CASE "z"
  601.         uhat(1) = 1: uhat(2) = 0: uhat(3) = 0
  602.         vhat(1) = 0: vhat(2) = 1: vhat(3) = 0
  603.     CASE ","
  604.         nearplane(4) = nearplane(4) - 1
  605.         IF nearplane(4) < 0 THEN nearplane(4) = 0
  606.     CASE "."
  607.         nearplane(4) = nearplane(4) + 1
  608.     CASE "]"
  609.         farplane(4) = farplane(4) - 1
  610.     CASE "["
  611.         farplane(4) = farplane(4) + 1
  612.     CASE "'"
  613.         spotlightcenter = spotlightcenter + spotlightthickness / 2
  614.     CASE ";"
  615.         spotlightcenter = spotlightcenter - spotlightthickness / 2
  616.         IF spotlightcenter < 0 THEN spotlightcenter = 0
  617.     CASE "t"
  618.         toggletimeanimate = -toggletimeanimate
  619.     CASE "r"
  620.         timevar = 0
  621.     CASE "f"
  622.         GOTO substart
  623.     CASE "g"
  624.         GOTO mainstart
  625.     CASE "-"
  626.         spotlightthickness = spotlightthickness - .25
  627.         IF spotlightthickness < 0 THEN spotlightthickness = 0
  628.         globaldelay = globaldelay * 1.1
  629.     CASE "="
  630.         spotlightthickness = spotlightthickness + .25
  631.         globaldelay = globaldelay * 0.9
  632.     CASE "`"
  633.         globaldelayinit = globaldelay
  634.     CASE " "
  635.         togglehud = -togglehud
  636.         CLS
  637.     CASE "n"
  638.         toggleatomnumbers = -toggleatomnumbers
  639.         CLS
  640.     CASE "/"
  641.         OPEN "uvn.txt" FOR OUTPUT AS #1
  642.         PRINT #1, uhat(1); uhat(2); uhat(3)
  643.         PRINT #1, vhat(1); vhat(2); vhat(3)
  644.         PRINT #1, nhat(1); nhat(2); nhat(3)
  645.         CLOSE #1
  646.         OPEN "vec1.txt" FOR OUTPUT AS #1
  647.         PRINT #1, vec(1, 1); vec(1, 2); vec(1, 3)
  648.         CLOSE #1
  649.         OPEN "object3d.txt" FOR OUTPUT AS #1
  650.         FOR i = 1 TO numparticleorig
  651.             PRINT #1, vec(i, 1); "   "; vec(i, 2); "   "; vec(i, 3); "   "; vec(i, 4)
  652.         NEXT
  653.         CLOSE #1
  654.     CASE CHR$(27)
  655.         END
  656.  
  657. convert:
  658. ' Convert graphics from uv-cartesian coordinates to monitor coordinates.
  659. x0 = x: y0 = y
  660. x = x0 + centerx
  661. y = -y0 + centery
  662. IF toggleatomnumbers = 1 THEN
  663.     xtext = (x0 + centerx) * (80 / 640)
  664.     ytext = (centery - y0) * (30 / 480) + 1
  665.     IF xtext < 1 THEN xtext = 1
  666.     IF xtext > 77 THEN xtext = 77
  667.     IF ytext < 1 THEN ytext = 1
  668.     IF ytext > 27 THEN ytext = 27
  669.  
  670. ' *** Define functions for view translation and rotation. ***
  671.  
  672. rotate.uhat.plus:
  673. uhat(1) = nhat(1) + speedconst * uhat(1)
  674. uhat(2) = nhat(2) + speedconst * uhat(2)
  675. uhat(3) = nhat(3) + speedconst * uhat(3)
  676.  
  677. rotate.uhat.minus:
  678. uhat(1) = -nhat(1) + speedconst * uhat(1)
  679. uhat(2) = -nhat(2) + speedconst * uhat(2)
  680. uhat(3) = -nhat(3) + speedconst * uhat(3)
  681.  
  682. rotate.vhat.plus:
  683. vhat(1) = nhat(1) + speedconst * vhat(1)
  684. vhat(2) = nhat(2) + speedconst * vhat(2)
  685. vhat(3) = nhat(3) + speedconst * vhat(3)
  686.  
  687. rotate.vhat.minus:
  688. vhat(1) = -nhat(1) + speedconst * vhat(1)
  689. vhat(2) = -nhat(2) + speedconst * vhat(2)
  690. vhat(3) = -nhat(3) + speedconst * vhat(3)
  691.  
  692. rotate.counterclockwise:
  693. v1 = vhat(1)
  694. v2 = vhat(2)
  695. v3 = vhat(3)
  696. vhat(1) = uhat(1) + speedconst * vhat(1)
  697. vhat(2) = uhat(2) + speedconst * vhat(2)
  698. vhat(3) = uhat(3) + speedconst * vhat(3)
  699. uhat(1) = -v1 + speedconst * uhat(1)
  700. uhat(2) = -v2 + speedconst * uhat(2)
  701. uhat(3) = -v3 + speedconst * uhat(3)
  702.  
  703. rotate.clockwise:
  704. v1 = vhat(1)
  705. v2 = vhat(2)
  706. v3 = vhat(3)
  707. vhat(1) = -uhat(1) + speedconst * vhat(1)
  708. vhat(2) = -uhat(2) + speedconst * vhat(2)
  709. vhat(3) = -uhat(3) + speedconst * vhat(3)
  710. uhat(1) = v1 + speedconst * uhat(1)
  711. uhat(2) = v2 + speedconst * uhat(2)
  712. uhat(3) = v3 + speedconst * uhat(3)
  713.  
  714. strafe.objects.uhat.plus:
  715. FOR i = 1 TO numparticleorig
  716.     vec(i, 1) = vec(i, 1) + uhat(1) * 1 / zoom
  717.     vec(i, 2) = vec(i, 2) + uhat(2) * 1 / zoom
  718.     vec(i, 3) = vec(i, 3) + uhat(3) * 1 / zoom
  719. FOR i = 1 TO numdoubletorig
  720.     doubletorig(i, 1) = doubletorig(i, 1) + uhat(1) * 1 / zoom
  721.     doubletorig(i, 2) = doubletorig(i, 2) + uhat(2) * 1 / zoom
  722.     doubletorig(i, 3) = doubletorig(i, 3) + uhat(3) * 1 / zoom
  723.     doubletorig(i, 4) = doubletorig(i, 4) + uhat(1) * 1 / zoom
  724.     doubletorig(i, 5) = doubletorig(i, 5) + uhat(2) * 1 / zoom
  725.     doubletorig(i, 6) = doubletorig(i, 6) + uhat(3) * 1 / zoom
  726. FOR i = 1 TO numtripletorig
  727.     tripletorig(i, 1) = tripletorig(i, 1) + uhat(1) * 1 / zoom
  728.     tripletorig(i, 2) = tripletorig(i, 2) + uhat(2) * 1 / zoom
  729.     tripletorig(i, 3) = tripletorig(i, 3) + uhat(3) * 1 / zoom
  730.     tripletorig(i, 4) = tripletorig(i, 4) + uhat(1) * 1 / zoom
  731.     tripletorig(i, 5) = tripletorig(i, 5) + uhat(2) * 1 / zoom
  732.     tripletorig(i, 6) = tripletorig(i, 6) + uhat(3) * 1 / zoom
  733.     tripletorig(i, 7) = tripletorig(i, 7) + uhat(1) * 1 / zoom
  734.     tripletorig(i, 8) = tripletorig(i, 8) + uhat(2) * 1 / zoom
  735.     tripletorig(i, 9) = tripletorig(i, 9) + uhat(3) * 1 / zoom
  736.  
  737. strafe.objects.uhat.minus:
  738. FOR i = 1 TO numparticleorig
  739.     vec(i, 1) = vec(i, 1) - uhat(1) * 1 / zoom
  740.     vec(i, 2) = vec(i, 2) - uhat(2) * 1 / zoom
  741.     vec(i, 3) = vec(i, 3) - uhat(3) * 1 / zoom
  742. FOR i = 1 TO numdoubletorig
  743.     doubletorig(i, 1) = doubletorig(i, 1) - uhat(1) * 1 / zoom
  744.     doubletorig(i, 2) = doubletorig(i, 2) - uhat(2) * 1 / zoom
  745.     doubletorig(i, 3) = doubletorig(i, 3) - uhat(3) * 1 / zoom
  746.     doubletorig(i, 4) = doubletorig(i, 4) - uhat(1) * 1 / zoom
  747.     doubletorig(i, 5) = doubletorig(i, 5) - uhat(2) * 1 / zoom
  748.     doubletorig(i, 6) = doubletorig(i, 6) - uhat(3) * 1 / zoom
  749. FOR i = 1 TO numtripletorig
  750.     tripletorig(i, 1) = tripletorig(i, 1) - uhat(1) * 1 / zoom
  751.     tripletorig(i, 2) = tripletorig(i, 2) - uhat(2) * 1 / zoom
  752.     tripletorig(i, 3) = tripletorig(i, 3) - uhat(3) * 1 / zoom
  753.     tripletorig(i, 4) = tripletorig(i, 4) - uhat(1) * 1 / zoom
  754.     tripletorig(i, 5) = tripletorig(i, 5) - uhat(2) * 1 / zoom
  755.     tripletorig(i, 6) = tripletorig(i, 6) - uhat(3) * 1 / zoom
  756.     tripletorig(i, 7) = tripletorig(i, 7) - uhat(1) * 1 / zoom
  757.     tripletorig(i, 8) = tripletorig(i, 8) - uhat(2) * 1 / zoom
  758.     tripletorig(i, 9) = tripletorig(i, 9) - uhat(3) * 1 / zoom
  759.  
  760. strafe.objects.vhat.plus:
  761. FOR i = 1 TO numparticleorig
  762.     vec(i, 1) = vec(i, 1) + vhat(1) * 1 / zoom
  763.     vec(i, 2) = vec(i, 2) + vhat(2) * 1 / zoom
  764.     vec(i, 3) = vec(i, 3) + vhat(3) * 1 / zoom
  765. FOR i = 1 TO numdoubletorig
  766.     doubletorig(i, 1) = doubletorig(i, 1) + vhat(1) * 1 / zoom
  767.     doubletorig(i, 2) = doubletorig(i, 2) + vhat(2) * 1 / zoom
  768.     doubletorig(i, 3) = doubletorig(i, 3) + vhat(3) * 1 / zoom
  769.     doubletorig(i, 4) = doubletorig(i, 4) + vhat(1) * 1 / zoom
  770.     doubletorig(i, 5) = doubletorig(i, 5) + vhat(2) * 1 / zoom
  771.     doubletorig(i, 6) = doubletorig(i, 6) + vhat(3) * 1 / zoom
  772. FOR i = 1 TO numtripletorig
  773.     tripletorig(i, 1) = tripletorig(i, 1) + vhat(1) * 1 / zoom
  774.     tripletorig(i, 2) = tripletorig(i, 2) + vhat(2) * 1 / zoom
  775.     tripletorig(i, 3) = tripletorig(i, 3) + vhat(3) * 1 / zoom
  776.     tripletorig(i, 4) = tripletorig(i, 4) + vhat(1) * 1 / zoom
  777.     tripletorig(i, 5) = tripletorig(i, 5) + vhat(2) * 1 / zoom
  778.     tripletorig(i, 6) = tripletorig(i, 6) + vhat(3) * 1 / zoom
  779.     tripletorig(i, 7) = tripletorig(i, 7) + vhat(1) * 1 / zoom
  780.     tripletorig(i, 8) = tripletorig(i, 8) + vhat(2) * 1 / zoom
  781.     tripletorig(i, 9) = tripletorig(i, 9) + vhat(3) * 1 / zoom
  782.  
  783. strafe.objects.vhat.minus:
  784. FOR i = 1 TO numparticleorig
  785.     vec(i, 1) = vec(i, 1) - vhat(1) * 1 / zoom
  786.     vec(i, 2) = vec(i, 2) - vhat(2) * 1 / zoom
  787.     vec(i, 3) = vec(i, 3) - vhat(3) * 1 / zoom
  788. FOR i = 1 TO numdoubletorig
  789.     doubletorig(i, 1) = doubletorig(i, 1) - vhat(1) * 1 / zoom
  790.     doubletorig(i, 2) = doubletorig(i, 2) - vhat(2) * 1 / zoom
  791.     doubletorig(i, 3) = doubletorig(i, 3) - vhat(3) * 1 / zoom
  792.     doubletorig(i, 4) = doubletorig(i, 4) - vhat(1) * 1 / zoom
  793.     doubletorig(i, 5) = doubletorig(i, 5) - vhat(2) * 1 / zoom
  794.     doubletorig(i, 6) = doubletorig(i, 6) - vhat(3) * 1 / zoom
  795. FOR i = 1 TO numtripletorig
  796.     tripletorig(i, 1) = tripletorig(i, 1) - vhat(1) * 1 / zoom
  797.     tripletorig(i, 2) = tripletorig(i, 2) - vhat(2) * 1 / zoom
  798.     tripletorig(i, 3) = tripletorig(i, 3) - vhat(3) * 1 / zoom
  799.     tripletorig(i, 4) = tripletorig(i, 4) - vhat(1) * 1 / zoom
  800.     tripletorig(i, 5) = tripletorig(i, 5) - vhat(2) * 1 / zoom
  801.     tripletorig(i, 6) = tripletorig(i, 6) - vhat(3) * 1 / zoom
  802.     tripletorig(i, 7) = tripletorig(i, 7) - vhat(1) * 1 / zoom
  803.     tripletorig(i, 8) = tripletorig(i, 8) - vhat(2) * 1 / zoom
  804.     tripletorig(i, 9) = tripletorig(i, 9) - vhat(3) * 1 / zoom
  805.  
  806. strafe.objects.nhat.plus:
  807. FOR i = 1 TO numparticleorig
  808.     vec(i, 1) = vec(i, 1) + nhat(1) * 1 / zoom
  809.     vec(i, 2) = vec(i, 2) + nhat(2) * 1 / zoom
  810.     vec(i, 3) = vec(i, 3) + nhat(3) * 1 / zoom
  811. FOR i = 1 TO numdoubletorig
  812.     doubletorig(i, 1) = doubletorig(i, 1) + nhat(1) * 1 / zoom
  813.     doubletorig(i, 2) = doubletorig(i, 2) + nhat(2) * 1 / zoom
  814.     doubletorig(i, 3) = doubletorig(i, 3) + nhat(3) * 1 / zoom
  815.     doubletorig(i, 4) = doubletorig(i, 4) + nhat(1) * 1 / zoom
  816.     doubletorig(i, 5) = doubletorig(i, 5) + nhat(2) * 1 / zoom
  817.     doubletorig(i, 6) = doubletorig(i, 6) + nhat(3) * 1 / zoom
  818. FOR i = 1 TO numtripletorig
  819.     tripletorig(i, 1) = tripletorig(i, 1) + nhat(1) * 1 / zoom
  820.     tripletorig(i, 2) = tripletorig(i, 2) + nhat(2) * 1 / zoom
  821.     tripletorig(i, 3) = tripletorig(i, 3) + nhat(3) * 1 / zoom
  822.     tripletorig(i, 4) = tripletorig(i, 4) + nhat(1) * 1 / zoom
  823.     tripletorig(i, 5) = tripletorig(i, 5) + nhat(2) * 1 / zoom
  824.     tripletorig(i, 6) = tripletorig(i, 6) + nhat(3) * 1 / zoom
  825.     tripletorig(i, 7) = tripletorig(i, 7) + nhat(1) * 1 / zoom
  826.     tripletorig(i, 8) = tripletorig(i, 8) + nhat(2) * 1 / zoom
  827.     tripletorig(i, 9) = tripletorig(i, 9) + nhat(3) * 1 / zoom
  828.  
  829. strafe.objects.nhat.minus:
  830. FOR i = 1 TO numparticleorig
  831.     vec(i, 1) = vec(i, 1) - nhat(1) * 1 / zoom
  832.     vec(i, 2) = vec(i, 2) - nhat(2) * 1 / zoom
  833.     vec(i, 3) = vec(i, 3) - nhat(3) * 1 / zoom
  834. FOR i = 1 TO numdoubletorig
  835.     doubletorig(i, 1) = doubletorig(i, 1) - nhat(1) * 1 / zoom
  836.     doubletorig(i, 2) = doubletorig(i, 2) - nhat(2) * 1 / zoom
  837.     doubletorig(i, 3) = doubletorig(i, 3) - nhat(3) * 1 / zoom
  838.     doubletorig(i, 4) = doubletorig(i, 4) - nhat(1) * 1 / zoom
  839.     doubletorig(i, 5) = doubletorig(i, 5) - nhat(2) * 1 / zoom
  840.     doubletorig(i, 6) = doubletorig(i, 6) - nhat(3) * 1 / zoom
  841. FOR i = 1 TO numtripletorig
  842.     tripletorig(i, 1) = tripletorig(i, 1) - nhat(1) * 1 / zoom
  843.     tripletorig(i, 2) = tripletorig(i, 2) - nhat(2) * 1 / zoom
  844.     tripletorig(i, 3) = tripletorig(i, 3) - nhat(3) * 1 / zoom
  845.     tripletorig(i, 4) = tripletorig(i, 4) - nhat(1) * 1 / zoom
  846.     tripletorig(i, 5) = tripletorig(i, 5) - nhat(2) * 1 / zoom
  847.     tripletorig(i, 6) = tripletorig(i, 6) - nhat(3) * 1 / zoom
  848.     tripletorig(i, 7) = tripletorig(i, 7) - nhat(1) * 1 / zoom
  849.     tripletorig(i, 8) = tripletorig(i, 8) - nhat(2) * 1 / zoom
  850.     tripletorig(i, 9) = tripletorig(i, 9) - nhat(3) * 1 / zoom
  851.  
  852. strafe.camera.uhat.plus:
  853. camx = camx + uhat(1) * 1 / zoom
  854. camy = camy + uhat(2) * 1 / zoom
  855. camz = camz + uhat(3) * 1 / zoom
  856.  
  857. strafe.camera.uhat.minus:
  858. camx = camx - uhat(1) * 1 / zoom
  859. camy = camy - uhat(2) * 1 / zoom
  860. camz = camz - uhat(3) * 1 / zoom
  861.  
  862. strafe.camera.vhat.plus:
  863. camx = camx + vhat(1) * 1 / zoom
  864. camy = camy + vhat(2) * 1 / zoom
  865. camz = camz + vhat(3) * 1 / zoom
  866.  
  867. strafe.camera.vhat.minus:
  868. camx = camx - vhat(1) * 1 / zoom
  869. camy = camy - vhat(2) * 1 / zoom
  870. camz = camz - vhat(3) * 1 / zoom
  871.  
  872. strafe.camera.nhat.plus:
  873. camx = camx + nhat(1) * 1 / zoom
  874. camy = camy + nhat(2) * 1 / zoom
  875. camz = camz + nhat(3) * 1 / zoom
  876.  
  877. strafe.camera.nhat.minus:
  878. camx = camx - nhat(1) * 1 / zoom
  879. camy = camy - nhat(2) * 1 / zoom
  880. camz = camz - nhat(3) * 1 / zoom
  881.  
  882. ' *** Define core functions. ***
  883.  
  884. timeanimate:
  885. timevar = timevar + 1
  886. IF timevar > 10 ^ 6 THEN timevar = 1
  887. SELECT CASE genscheme$
  888.     CASE "3denvparticles": GOSUB genscheme.3denvparticles.timeanimate
  889.     CASE "animatedflag": GOSUB genscheme.animatedsurface.timeanimate
  890.     CASE "animatedpretzel": GOSUB genscheme.animatedpretzel.timeanimate
  891.     CASE "laplace2d": GOSUB genscheme.laplace2d.timeanimate
  892.     CASE "planet": GOSUB genscheme.planet.timeanimate
  893.     CASE "wave2d": GOSUB genscheme.wave2d.timeanimate
  894.     CASE "wave2dinf": GOSUB genscheme.wave2dinf.timeanimate
  895.     CASE "bacteria": GOSUB genscheme.bacteria.timeanimate
  896.     CASE "neuron": GOSUB genscheme.neuron.timeanimate
  897.  
  898. normalize.screen.vectors:
  899. 'normalize the two vectors that define the screen orientation
  900. uhatmag = SQR(uhat(1) ^ 2 + uhat(2) ^ 2 + uhat(3) ^ 2)
  901. uhat(1) = uhat(1) / uhatmag: uhat(2) = uhat(2) / uhatmag: uhat(3) = uhat(3) / uhatmag
  902. vhatmag = SQR(vhat(1) ^ 2 + vhat(2) ^ 2 + vhat(3) ^ 2)
  903. vhat(1) = vhat(1) / vhatmag: vhat(2) = vhat(2) / vhatmag: vhat(3) = vhat(3) / vhatmag
  904. uhatdotvhat = uhat(1) * vhat(1) + uhat(2) * vhat(2) + uhat(3) * vhat(3)
  905. IF SQR(uhatdotvhat ^ 2) > .0005 THEN
  906.     CLS: COLOR 15: LOCATE 5, 5: PRINT "Screen vectors are not perpendicular. Press ESC to quit."
  907.     'DO: LOOP UNTIL INKEY$ = CHR$(27): END
  908. ' Compute the normal vector to the view plane.
  909. ' The normal vector points toward the eye, away from view frustum.
  910. nhat(1) = uhat(2) * vhat(3) - uhat(3) * vhat(2)
  911. nhat(2) = uhat(3) * vhat(1) - uhat(1) * vhat(3)
  912. nhat(3) = uhat(1) * vhat(2) - uhat(2) * vhat(1)
  913. nhatmag = SQR(nhat(1) ^ 2 + nhat(2) ^ 2 + nhat(3) ^ 2)
  914. nhat(1) = nhat(1) / nhatmag: nhat(2) = nhat(2) / nhatmag: nhat(3) = nhat(3) / nhatmag
  915.  
  916. redraw:
  917. GOSUB normalize.screen.vectors
  918. GOSUB compute.viewplanes
  919. ' Project the three-space basis vectors onto the screen plane.
  920. xhatp(1) = xhat(1) * uhat(1) + xhat(2) * uhat(2) + xhat(3) * uhat(3)
  921. xhatp(2) = xhat(1) * vhat(1) + xhat(2) * vhat(2) + xhat(3) * vhat(3)
  922. yhatp(1) = yhat(1) * uhat(1) + yhat(2) * uhat(2) + yhat(3) * uhat(3)
  923. yhatp(2) = yhat(1) * vhat(1) + yhat(2) * vhat(2) + yhat(3) * vhat(3)
  924. zhatp(1) = zhat(1) * uhat(1) + zhat(2) * uhat(2) + zhat(3) * uhat(3)
  925. zhatp(2) = zhat(1) * vhat(1) + zhat(2) * vhat(2) + zhat(3) * vhat(3)
  926. IF numparticleorig > 0 THEN
  927.     GOSUB compute.visible.particles
  928.     GOSUB project.particles
  929.     GOSUB depth.adjust.particles
  930. IF numdoubletorig > 0 THEN
  931.     GOSUB copy.doublets.orig.clip
  932.     GOSUB clip.doublets.viewplanes
  933.     GOSUB copy.doublets.clip.snip
  934.     GOSUB project.doublets
  935.     GOSUB depth.adjust.doublets
  936.     GOSUB snip.doublets
  937.     GOSUB copy.doublets.snipwork.snip
  938.     GOSUB project.doublets
  939.     GOSUB depth.adjust.doublets
  940. IF numtripletorig > 0 THEN
  941.     GOSUB reverse.uvnhat
  942.     GOSUB triplet.filter.faceon
  943.     GOSUB copy.triplets.faceon.clip
  944.     GOSUB clip.triplets.viewplanes
  945.     GOSUB copy.triplets.clip.snip
  946.     GOSUB snip.triplets
  947.     GOSUB copy.triplets.snip.final
  948.     GOSUB project.triplets
  949.     GOSUB depth.adjust.triplets
  950.     GOSUB reverse.uvnhat
  951. GOSUB draw.all.objects
  952. GOSUB store.screen.projections
  953.  
  954. reverse.uvnhat:
  955. uhat(1) = -uhat(1)
  956. uhat(2) = -uhat(2)
  957. uhat(3) = -uhat(3)
  958. GOSUB normalize.screen.vectors
  959.  
  960. compute.visible.particles:
  961. numparticlevisible = 0
  962. FOR i = 1 TO numparticleorig
  963.     IF falsedepth = 0 THEN
  964.         GOSUB clip.particle.viewplanes
  965.     ELSE
  966.         SELECT CASE genscheme$
  967.             CASE "molecule"
  968.                 numparticlevisible = numparticlevisible + 1
  969.                 vecvisible(numparticlevisible, 1) = vec(i, 1)
  970.                 vecvisible(numparticlevisible, 2) = vec(i, 2)
  971.                 vecvisible(numparticlevisible, 3) = vec(i, 3)
  972.                 vecvisible(numparticlevisible, 4) = vec(i, 4)
  973.                 vecvisible(numparticlevisible, 5) = vec(i, 5)
  974.                 vecvisible(numparticlevisible, 6) = vec(i, 6)
  975.                 vecvisible(numparticlevisible, 7) = vec(i, 7)
  976.                 vecvisible(numparticlevisible, 8) = vec(i, 8)
  977.                 vecvisible(numparticlevisible, 9) = vec(i, 9)
  978.                 vecvisible(numparticlevisible, 10) = vec(i, 10)
  979.             CASE "bacteria"
  980.                 numparticlevisible = numparticlevisible + 1
  981.                 vecvisible(numparticlevisible, 1) = vec(i, 1)
  982.                 vecvisible(numparticlevisible, 2) = vec(i, 2)
  983.                 vecvisible(numparticlevisible, 3) = vec(i, 3)
  984.                 vecvisible(numparticlevisible, 4) = vec(i, 4)
  985.                 vecvisible(numparticlevisible, 5) = vec(i, 5)
  986.                 vecvisible(numparticlevisible, 6) = vec(i, 6)
  987.                 vecvisible(numparticlevisible, 7) = vec(i, 7)
  988.                 vecvisible(numparticlevisible, 8) = vec(i, 8)
  989.                 vecvisible(numparticlevisible, 9) = vec(i, 9)
  990.                 vecvisible(numparticlevisible, 10) = vec(i, 10)
  991.             CASE "neuron"
  992.                 numparticlevisible = numparticlevisible + 1
  993.                 vecvisible(numparticlevisible, 1) = vec(i, 1)
  994.                 vecvisible(numparticlevisible, 2) = vec(i, 2)
  995.                 vecvisible(numparticlevisible, 3) = vec(i, 3)
  996.                 vecvisible(numparticlevisible, 4) = vec(i, 4)
  997.                 vecvisible(numparticlevisible, 5) = vec(i, 5)
  998.                 vecvisible(numparticlevisible, 6) = vec(i, 6)
  999.                 vecvisible(numparticlevisible, 7) = vec(i, 7)
  1000.                 vecvisible(numparticlevisible, 8) = vec(i, 8)
  1001.                 vecvisible(numparticlevisible, 9) = vec(i, 9)
  1002.                 vecvisible(numparticlevisible, 10) = vec(i, 10)
  1003.                 vecvisible(numparticlevisible, 11) = vec(i, 11)
  1004.                 vecvisible(numparticlevisible, 12) = vec(i, 12)
  1005.                 vecvisible(numparticlevisible, 13) = vec(i, 13)
  1006.                 vecvisible(numparticlevisible, 14) = vec(i, 14)
  1007.                 vecvisible(numparticlevisible, 15) = vec(i, 15)
  1008.             CASE ELSE
  1009.                 numparticlevisible = numparticlevisible + 1
  1010.                 vecvisible(numparticlevisible, 1) = vec(i, 1)
  1011.                 vecvisible(numparticlevisible, 2) = vec(i, 2)
  1012.                 vecvisible(numparticlevisible, 3) = vec(i, 3)
  1013.                 vecvisible(numparticlevisible, 4) = vec(i, 4)
  1014.         END SELECT
  1015.     END IF
  1016.  
  1017. clip.particle.viewplanes:
  1018. particleinview = 1
  1019. fogswitch = -1
  1020. ' Perform standard view plane clipping and determine depth 'fog effect'.
  1021. givenplanex = nearplane(1)
  1022. givenplaney = nearplane(2)
  1023. givenplanez = nearplane(3)
  1024. givenplaned = nearplane(4)
  1025. IF vec(i, 1) * givenplanex + vec(i, 2) * givenplaney + vec(i, 3) * givenplanez - givenplaned < 0 THEN particleinview = 0
  1026. givenplanex = farplane(1)
  1027. givenplaney = farplane(2)
  1028. givenplanez = farplane(3)
  1029. givenplaned = farplane(4)
  1030. IF vec(i, 1) * givenplanex + vec(i, 2) * givenplaney + vec(i, 3) * givenplanez - givenplaned < 0 THEN particleinview = 0
  1031. IF togglehud = -1 THEN IF vec(i, 1) * givenplanex + vec(i, 2) * givenplaney + vec(i, 3) * givenplanez - givenplaned * .9 < 0 THEN fogswitch = 1
  1032. givenplanex = rightplane(1)
  1033. givenplaney = rightplane(2)
  1034. givenplanez = rightplane(3)
  1035. givenplaned = rightplane(4)
  1036. IF vec(i, 1) * givenplanex + vec(i, 2) * givenplaney + vec(i, 3) * givenplanez - givenplaned < 0 THEN particleinview = 0
  1037. givenplanex = leftplane(1)
  1038. givenplaney = leftplane(2)
  1039. givenplanez = leftplane(3)
  1040. givenplaned = leftplane(4)
  1041. IF vec(i, 1) * givenplanex + vec(i, 2) * givenplaney + vec(i, 3) * givenplanez - givenplaned < 0 THEN particleinview = 0
  1042. givenplanex = topplane(1)
  1043. givenplaney = topplane(2)
  1044. givenplanez = topplane(3)
  1045. givenplaned = topplane(4)
  1046. IF vec(i, 1) * givenplanex + vec(i, 2) * givenplaney + vec(i, 3) * givenplanez - givenplaned < 0 THEN particleinview = 0
  1047. givenplanex = bottomplane(1)
  1048. givenplaney = bottomplane(2)
  1049. givenplanez = bottomplane(3)
  1050. givenplaned = bottomplane(4)
  1051. IF vec(i, 1) * givenplanex + vec(i, 2) * givenplaney + vec(i, 3) * givenplanez - givenplaned < 0 THEN particleinview = 0
  1052. IF particleinview = 1 AND togglehud = 1 THEN
  1053.     ' Apply spotlight effect.
  1054.     givenplanex = nearplanespotlight(1)
  1055.     givenplaney = nearplanespotlight(2)
  1056.     givenplanez = nearplanespotlight(3)
  1057.     givenplaned = nearplanespotlight(4)
  1058.     IF vec(i, 1) * givenplanex + vec(i, 2) * givenplaney + vec(i, 3) * givenplanez - givenplaned < 0 THEN fogswitch = 1
  1059.     givenplanex = farplanespotlight(1)
  1060.     givenplaney = farplanespotlight(2)
  1061.     givenplanez = farplanespotlight(3)
  1062.     givenplaned = farplanespotlight(4)
  1063.     IF vec(i, 1) * givenplanex + vec(i, 2) * givenplaney + vec(i, 3) * givenplanez - givenplaned < 0 THEN fogswitch = 1
  1064.     givenplanex = rightplanespotlight(1)
  1065.     givenplaney = rightplanespotlight(2)
  1066.     givenplanez = rightplanespotlight(3)
  1067.     givenplaned = rightplanespotlight(4)
  1068.     IF vec(i, 1) * givenplanex + vec(i, 2) * givenplaney + vec(i, 3) * givenplanez - givenplaned < 0 THEN fogswitch = 1
  1069.     givenplanex = leftplanespotlight(1)
  1070.     givenplaney = leftplanespotlight(2)
  1071.     givenplanez = leftplanespotlight(3)
  1072.     givenplaned = leftplanespotlight(4)
  1073.     IF vec(i, 1) * givenplanex + vec(i, 2) * givenplaney + vec(i, 3) * givenplanez - givenplaned < 0 THEN fogswitch = 1
  1074.     givenplanex = topplanespotlight(1)
  1075.     givenplaney = topplanespotlight(2)
  1076.     givenplanez = topplanespotlight(3)
  1077.     givenplaned = topplanespotlight(4)
  1078.     IF vec(i, 1) * givenplanex + vec(i, 2) * givenplaney + vec(i, 3) * givenplanez - givenplaned < 0 THEN fogswitch = 1
  1079.     givenplanex = bottomplanespotlight(1)
  1080.     givenplaney = bottomplanespotlight(2)
  1081.     givenplanez = bottomplanespotlight(3)
  1082.     givenplaned = bottomplanespotlight(4)
  1083.     IF vec(i, 1) * givenplanex + vec(i, 2) * givenplaney + vec(i, 3) * givenplanez - givenplaned < 0 THEN fogswitch = 1
  1084. IF particleinview = 1 THEN
  1085.     numparticlevisible = numparticlevisible + 1
  1086.     vecvisible(numparticlevisible, 1) = vec(i, 1)
  1087.     vecvisible(numparticlevisible, 2) = vec(i, 2)
  1088.     vecvisible(numparticlevisible, 3) = vec(i, 3)
  1089.     vecvisible(numparticlevisible, 4) = vec(i, 4)
  1090.     IF fogswitch = 1 THEN vecvisible(numparticlevisible, 4) = 8
  1091.  
  1092. project.particles:
  1093. ' Project object vectors onto the screen plane.
  1094. FOR i = 1 TO numparticlevisible
  1095.     vecvisibledotnhat(i) = vecvisible(i, 1) * nhat(1) + vecvisible(i, 2) * nhat(2) + vecvisible(i, 3) * nhat(3)
  1096.     vecvisiblepuv(i, 1) = (vecvisible(i, 1) * uhat(1) + vecvisible(i, 2) * uhat(2) + vecvisible(i, 3) * uhat(3))
  1097.     vecvisiblepuv(i, 2) = (vecvisible(i, 1) * vhat(1) + vecvisible(i, 2) * vhat(2) + vecvisible(i, 3) * vhat(3))
  1098.  
  1099. depth.adjust.particles:
  1100. IF falsedepth = 0 THEN
  1101.     FOR i = 1 TO numparticlevisible
  1102.         vecvisiblepuvs(i, 1) = vecvisiblepuv(i, 1) * fovd / vecvisibledotnhat(i)
  1103.         vecvisiblepuvs(i, 2) = vecvisiblepuv(i, 2) * fovd / vecvisibledotnhat(i)
  1104.     NEXT
  1105.     FOR i = 1 TO numparticlevisible
  1106.         vecvisiblepuvs(i, 1) = vecvisiblepuv(i, 1) * (1 + falsedepth * vecvisibledotnhat(i))
  1107.         vecvisiblepuvs(i, 2) = vecvisiblepuv(i, 2) * (1 + falsedepth * vecvisibledotnhat(i))
  1108.     NEXT
  1109.  
  1110. draw.all.objects:
  1111. SELECT CASE plotmode$
  1112.     CASE "molecule": GOSUB plotmode.molecule
  1113.     CASE "simplepoints": GOSUB plotmode.simplepoints
  1114.     CASE "neighbortile": GOSUB plotmode.neighbortile
  1115.     CASE "linearconnect": GOSUB plotmode.linearconnect
  1116.     CASE "3denvparticles": GOSUB plotmode.3denvparticles
  1117.     CASE "3denvdoublets"
  1118.         IF numparticleorig > 0 THEN GOSUB plotmode.simplepoints
  1119.         IF numdoubletorig > 0 THEN GOSUB plotmode.3denvdoublets
  1120.     CASE "3denvtriplets": GOSUB plotmode.3denvtriplets
  1121.     CASE "simplemesh": GOSUB plotmode.simplemesh
  1122.     CASE "meshtech2": GOSUB plotmode.meshtech2
  1123.     CASE "meshtech2planet": GOSUB plotmode.meshtech2planet
  1124.     CASE "simplepointsbacteria": GOSUB plotmode.simplepointsbacteria
  1125.     CASE "linearneuron": GOSUB plotmode.linearneuron
  1126. LOCATE 28, 23: PRINT "SPACE = toggle HUD,  ESC = quit."
  1127. IF togglehud = 1 THEN
  1128.     ' Replace basis vector triad.
  1129.     x = 50 * xhatp.old(1): y = 50 * xhatp.old(2): GOSUB convert
  1130.     LINE (centerx, centery)-(x, y), 0
  1131.     x = 50 * yhatp.old(1): y = 50 * yhatp.old(2): GOSUB convert
  1132.     LINE (centerx, centery)-(x, y), 0
  1133.     x = 50 * zhatp.old(1): y = 50 * zhatp.old(2): GOSUB convert
  1134.     LINE (centerx, centery)-(x, y), 0
  1135.     x = 50 * xhatp(1): y = 50 * xhatp(2): GOSUB convert
  1136.     LINE (centerx, centery)-(x, y), xhat(4)
  1137.     x = 50 * yhatp(1): y = 50 * yhatp(2): GOSUB convert
  1138.     LINE (centerx, centery)-(x, y), yhat(4)
  1139.     x = 50 * zhatp(1): y = 50 * zhatp(2): GOSUB convert
  1140.     LINE (centerx, centery)-(x, y), zhat(4)
  1141.     COLOR 14
  1142.     LOCATE 26, 2: PRINT "- MOVE -"
  1143.     COLOR 15
  1144.     LOCATE 27, 2: PRINT " q W e"
  1145.     LOCATE 28, 2: PRINT " A S D"
  1146.     COLOR 14
  1147.     LOCATE 25, 68: PRINT "-   VIEW   -"
  1148.     COLOR 15
  1149.     LOCATE 26, 68: PRINT "  8  "
  1150.     LOCATE 27, 68: PRINT "4   6"
  1151.     LOCATE 28, 68: PRINT "  2  "
  1152.     COLOR 7
  1153.     LOCATE 26, 75: PRINT "7   9"
  1154.     LOCATE 27, 75: PRINT "     "
  1155.     LOCATE 28, 75: PRINT "1   3"
  1156.     IF numparticleorig > 0 AND falsedepth = 0 THEN
  1157.         COLOR 7
  1158.         LOCATE 3, 2: PRINT "- Particle Info -"
  1159.         LOCATE 4, 2: PRINT "   Total:"; numparticleorig
  1160.         LOCATE 5, 2: PRINT " Visible:"; numparticlevisible
  1161.         LOCATE 6, 2: PRINT " Percent:"; INT(100 * numparticlevisible / numparticleorig)
  1162.         LOCATE 8, 2: PRINT " Press '/' to"
  1163.         LOCATE 9, 2: PRINT " export view."
  1164.         LOCATE 3, 65: PRINT "- View Planes -"
  1165.         LOCATE 4, 65: PRINT " Far dist:"; -farplane(4)
  1166.         LOCATE 5, 65: PRINT " Near dist:"; nearplane(4)
  1167.         LOCATE 6, 65: PRINT " [,] shift Far"
  1168.         LOCATE 7, 65: PRINT " <,> shift Near"
  1169.         LOCATE 9, 65: PRINT "- Spotlight -"
  1170.         LOCATE 10, 64: PRINT "  Center:"; spotlightcenter
  1171.         LOCATE 11, 64: PRINT "  Thick:"; spotlightthickness
  1172.         LOCATE 12, 64: PRINT "  Control keys:"
  1173.         LOCATE 13, 64: PRINT "    ; ' - ="
  1174.     END IF
  1175. IF toggletimealert = 1 THEN
  1176.     COLOR 7
  1177.     LOCATE 1, 25: PRINT "Press 'T' to toggle animation."
  1178.  
  1179. store.screen.projections:
  1180. xhatp.old(1) = xhatp(1): xhatp.old(2) = xhatp(2)
  1181. yhatp.old(1) = yhatp(1): yhatp.old(2) = yhatp(2)
  1182. zhatp.old(1) = zhatp(1): zhatp.old(2) = zhatp(2)
  1183. FOR i = 1 TO numparticlevisible
  1184.     vecvisiblepuvs.old(i, 1) = vecvisiblepuvs(i, 1)
  1185.     vecvisiblepuvs.old(i, 2) = vecvisiblepuvs(i, 2)
  1186. numparticlevisible.old = numparticlevisible
  1187. FOR i = 1 TO numdoubletsnip
  1188.     doubletsnippuvs.old(i, 1) = doubletsnippuvs(i, 1)
  1189.     doubletsnippuvs.old(i, 2) = doubletsnippuvs(i, 2)
  1190.     doubletsnippuvs.old(i, 3) = doubletsnippuvs(i, 3)
  1191.     doubletsnippuvs.old(i, 4) = doubletsnippuvs(i, 4)
  1192. numdoubletsnip.old = numdoubletsnip
  1193. FOR i = 1 TO numtripletfinal
  1194.     tripletfinalpuvs.old(i, 1) = tripletfinalpuvs(i, 1)
  1195.     tripletfinalpuvs.old(i, 2) = tripletfinalpuvs(i, 2)
  1196.     tripletfinalpuvs.old(i, 3) = tripletfinalpuvs(i, 3)
  1197.     tripletfinalpuvs.old(i, 4) = tripletfinalpuvs(i, 4)
  1198.     tripletfinalpuvs.old(i, 5) = tripletfinalpuvs(i, 5)
  1199.     tripletfinalpuvs.old(i, 6) = tripletfinalpuvs(i, 6)
  1200. numtripletfinal.old = numtripletfinal
  1201.  
  1202. compute.viewplanes:
  1203. ' Define normal vectors to all view planes.
  1204. nearplane(1) = -nhat(1)
  1205. nearplane(2) = -nhat(2)
  1206. nearplane(3) = -nhat(3)
  1207. farplane(1) = nhat(1)
  1208. farplane(2) = nhat(2)
  1209. farplane(3) = nhat(3)
  1210. rightplane(1) = (screenheight / 4) * fovd * uhat(1) - (screenheight / 4) * (screenwidth / 4) * nhat(1)
  1211. rightplane(2) = (screenheight / 4) * fovd * uhat(2) - (screenheight / 4) * (screenwidth / 4) * nhat(2)
  1212. rightplane(3) = (screenheight / 4) * fovd * uhat(3) - (screenheight / 4) * (screenwidth / 4) * nhat(3)
  1213. mag = SQR((rightplane(1)) ^ 2 + (rightplane(2)) ^ 2 + (rightplane(3)) ^ 2)
  1214. rightplane(1) = rightplane(1) / mag
  1215. rightplane(2) = rightplane(2) / mag
  1216. rightplane(3) = rightplane(3) / mag
  1217. leftplane(1) = -(screenheight / 4) * fovd * uhat(1) - (screenheight / 4) * (screenwidth / 4) * nhat(1)
  1218. leftplane(2) = -(screenheight / 4) * fovd * uhat(2) - (screenheight / 4) * (screenwidth / 4) * nhat(2)
  1219. leftplane(3) = -(screenheight / 4) * fovd * uhat(3) - (screenheight / 4) * (screenwidth / 4) * nhat(3)
  1220. mag = SQR((leftplane(1)) ^ 2 + (leftplane(2)) ^ 2 + (leftplane(3)) ^ 2)
  1221. leftplane(1) = leftplane(1) / mag
  1222. leftplane(2) = leftplane(2) / mag
  1223. leftplane(3) = leftplane(3) / mag
  1224. topplane(1) = (screenwidth / 4) * fovd * vhat(1) - (screenheight / 4) * (screenwidth / 4) * nhat(1)
  1225. topplane(2) = (screenwidth / 4) * fovd * vhat(2) - (screenheight / 4) * (screenwidth / 4) * nhat(2)
  1226. topplane(3) = (screenwidth / 4) * fovd * vhat(3) - (screenheight / 4) * (screenwidth / 4) * nhat(3)
  1227. mag = SQR((topplane(1)) ^ 2 + (topplane(2)) ^ 2 + (topplane(3)) ^ 2)
  1228. topplane(1) = topplane(1) / mag
  1229. topplane(2) = topplane(2) / mag
  1230. topplane(3) = topplane(3) / mag
  1231. bottomplane(1) = -(screenwidth / 4) * fovd * vhat(1) - (screenheight / 4) * (screenwidth / 4) * nhat(1)
  1232. bottomplane(2) = -(screenwidth / 4) * fovd * vhat(2) - (screenheight / 4) * (screenwidth / 4) * nhat(2)
  1233. bottomplane(3) = -(screenwidth / 4) * fovd * vhat(3) - (screenheight / 4) * (screenwidth / 4) * nhat(3)
  1234. mag = SQR((bottomplane(1)) ^ 2 + (bottomplane(2)) ^ 2 + (bottomplane(3)) ^ 2)
  1235. bottomplane(1) = bottomplane(1) / mag
  1236. bottomplane(2) = bottomplane(2) / mag
  1237. bottomplane(3) = bottomplane(3) / mag
  1238. IF togglehud = 1 THEN
  1239.     nearplanespotlight(4) = spotlightcenter - spotlightthickness / 2
  1240.     farplanespotlight(4) = -(spotlightcenter + spotlightthickness / 2)
  1241.     nearplanespotlight(1) = -nhat(1)
  1242.     nearplanespotlight(2) = -nhat(2)
  1243.     nearplanespotlight(3) = -nhat(3)
  1244.     farplanespotlight(1) = nhat(1)
  1245.     farplanespotlight(2) = nhat(2)
  1246.     farplanespotlight(3) = nhat(3)
  1247.     rightplanespotlight(1) = (screenheight / (4 * spotlightwidth)) * fovd * uhat(1) - (screenheight / (4 * spotlightwidth)) * (screenwidth / (4 * spotlightwidth)) * nhat(1)
  1248.     rightplanespotlight(2) = (screenheight / (4 * spotlightwidth)) * fovd * uhat(2) - (screenheight / (4 * spotlightwidth)) * (screenwidth / (4 * spotlightwidth)) * nhat(2)
  1249.     rightplanespotlight(3) = (screenheight / (4 * spotlightwidth)) * fovd * uhat(3) - (screenheight / (4 * spotlightwidth)) * (screenwidth / (4 * spotlightwidth)) * nhat(3)
  1250.     mag = SQR((rightplanespotlight(1)) ^ 2 + (rightplanespotlight(2)) ^ 2 + (rightplanespotlight(3)) ^ 2)
  1251.     rightplanespotlight(1) = rightplanespotlight(1) / mag
  1252.     rightplanespotlight(2) = rightplanespotlight(2) / mag
  1253.     rightplanespotlight(3) = rightplanespotlight(3) / mag
  1254.     leftplanespotlight(1) = -(screenheight / (4 * spotlightwidth)) * fovd * uhat(1) - (screenheight / (4 * spotlightwidth)) * (screenwidth / (4 * spotlightwidth)) * nhat(1)
  1255.     leftplanespotlight(2) = -(screenheight / (4 * spotlightwidth)) * fovd * uhat(2) - (screenheight / (4 * spotlightwidth)) * (screenwidth / (4 * spotlightwidth)) * nhat(2)
  1256.     leftplanespotlight(3) = -(screenheight / (4 * spotlightwidth)) * fovd * uhat(3) - (screenheight / (4 * spotlightwidth)) * (screenwidth / (4 * spotlightwidth)) * nhat(3)
  1257.     mag = SQR((leftplanespotlight(1)) ^ 2 + (leftplanespotlight(2)) ^ 2 + (leftplanespotlight(3)) ^ 2)
  1258.     leftplanespotlight(1) = leftplanespotlight(1) / mag
  1259.     leftplanespotlight(2) = leftplanespotlight(2) / mag
  1260.     leftplanespotlight(3) = leftplanespotlight(3) / mag
  1261.     topplanespotlight(1) = (screenwidth / (4 * spotlightwidth)) * fovd * vhat(1) - (screenheight / (4 * spotlightwidth)) * (screenwidth / (4 * spotlightwidth)) * nhat(1)
  1262.     topplanespotlight(2) = (screenwidth / (4 * spotlightwidth)) * fovd * vhat(2) - (screenheight / (4 * spotlightwidth)) * (screenwidth / (4 * spotlightwidth)) * nhat(2)
  1263.     topplanespotlight(3) = (screenwidth / (4 * spotlightwidth)) * fovd * vhat(3) - (screenheight / (4 * spotlightwidth)) * (screenwidth / (4 * spotlightwidth)) * nhat(3)
  1264.     mag = SQR((topplanespotlight(1)) ^ 2 + (topplanespotlight(2)) ^ 2 + (topplanespotlight(3)) ^ 2)
  1265.     topplanespotlight(1) = topplanespotlight(1) / mag
  1266.     topplanespotlight(2) = topplanespotlight(2) / mag
  1267.     topplanespotlight(3) = topplanespotlight(3) / mag
  1268.     bottomplanespotlight(1) = -(screenwidth / (4 * spotlightwidth)) * fovd * vhat(1) - (screenheight / (4 * spotlightwidth)) * (screenwidth / (4 * spotlightwidth)) * nhat(1)
  1269.     bottomplanespotlight(2) = -(screenwidth / (4 * spotlightwidth)) * fovd * vhat(2) - (screenheight / (4 * spotlightwidth)) * (screenwidth / (4 * spotlightwidth)) * nhat(2)
  1270.     bottomplanespotlight(3) = -(screenwidth / (4 * spotlightwidth)) * fovd * vhat(3) - (screenheight / (4 * spotlightwidth)) * (screenwidth / (4 * spotlightwidth)) * nhat(3)
  1271.     mag = SQR((bottomplanespotlight(1)) ^ 2 + (bottomplanespotlight(2)) ^ 2 + (bottomplanespotlight(3)) ^ 2)
  1272.     bottomplanespotlight(1) = bottomplanespotlight(1) / mag
  1273.     bottomplanespotlight(2) = bottomplanespotlight(2) / mag
  1274.     bottomplanespotlight(3) = bottomplanespotlight(3) / mag
  1275.  
  1276. ' *** Define functions for doublet manipulations. ***
  1277.  
  1278. project.doublets:
  1279. FOR i = 1 TO numdoubletclip
  1280.     doubletclipdotnhat(i, 1) = doubletclip(i, 1) * nhat(1) + doubletclip(i, 2) * nhat(2) + doubletclip(i, 3) * nhat(3)
  1281.     doubletclipdotnhat(i, 2) = doubletclip(i, 4) * nhat(1) + doubletclip(i, 5) * nhat(2) + doubletclip(i, 6) * nhat(3)
  1282.     doubletclippuv(i, 1) = doubletclip(i, 1) * uhat(1) + doubletclip(i, 2) * uhat(2) + doubletclip(i, 3) * uhat(3)
  1283.     doubletclippuv(i, 2) = doubletclip(i, 1) * vhat(1) + doubletclip(i, 2) * vhat(2) + doubletclip(i, 3) * vhat(3)
  1284.     doubletclippuv(i, 3) = doubletclip(i, 4) * uhat(1) + doubletclip(i, 5) * uhat(2) + doubletclip(i, 6) * uhat(3)
  1285.     doubletclippuv(i, 4) = doubletclip(i, 4) * vhat(1) + doubletclip(i, 5) * vhat(2) + doubletclip(i, 6) * vhat(3)
  1286. FOR i = 1 TO numdoubletsnip
  1287.     doubletsnipdotnhat(i, 1) = doubletsnip(i, 1) * nhat(1) + doubletsnip(i, 2) * nhat(2) + doubletsnip(i, 3) * nhat(3)
  1288.     doubletsnipdotnhat(i, 2) = doubletsnip(i, 4) * nhat(1) + doubletsnip(i, 5) * nhat(2) + doubletsnip(i, 6) * nhat(3)
  1289.     doubletsnippuv(i, 1) = doubletsnip(i, 1) * uhat(1) + doubletsnip(i, 2) * uhat(2) + doubletsnip(i, 3) * uhat(3)
  1290.     doubletsnippuv(i, 2) = doubletsnip(i, 1) * vhat(1) + doubletsnip(i, 2) * vhat(2) + doubletsnip(i, 3) * vhat(3)
  1291.     doubletsnippuv(i, 3) = doubletsnip(i, 4) * uhat(1) + doubletsnip(i, 5) * uhat(2) + doubletsnip(i, 6) * uhat(3)
  1292.     doubletsnippuv(i, 4) = doubletsnip(i, 4) * vhat(1) + doubletsnip(i, 5) * vhat(2) + doubletsnip(i, 6) * vhat(3)
  1293.  
  1294. depth.adjust.doublets:
  1295. FOR i = 1 TO numdoubletclip
  1296.     doubletclippuvs(i, 1) = doubletclippuv(i, 1) * fovd / doubletclipdotnhat(i, 1)
  1297.     doubletclippuvs(i, 2) = doubletclippuv(i, 2) * fovd / doubletclipdotnhat(i, 1)
  1298.     doubletclippuvs(i, 3) = doubletclippuv(i, 3) * fovd / doubletclipdotnhat(i, 2)
  1299.     doubletclippuvs(i, 4) = doubletclippuv(i, 4) * fovd / doubletclipdotnhat(i, 2)
  1300. FOR i = 1 TO numdoubletsnip
  1301.     doubletsnippuvs(i, 1) = doubletsnippuv(i, 1) * fovd / doubletsnipdotnhat(i, 1)
  1302.     doubletsnippuvs(i, 2) = doubletsnippuv(i, 2) * fovd / doubletsnipdotnhat(i, 1)
  1303.     doubletsnippuvs(i, 3) = doubletsnippuv(i, 3) * fovd / doubletsnipdotnhat(i, 2)
  1304.     doubletsnippuvs(i, 4) = doubletsnippuv(i, 4) * fovd / doubletsnipdotnhat(i, 2)
  1305.  
  1306. ' *** Define functions for doublet viewplane clipping. ***
  1307.  
  1308. copy.doublets.orig.clip:
  1309. FOR i = 1 TO numdoubletorig
  1310.     doubletclip(i, 1) = doubletorig(i, 1)
  1311.     doubletclip(i, 2) = doubletorig(i, 2)
  1312.     doubletclip(i, 3) = doubletorig(i, 3)
  1313.     doubletclip(i, 4) = doubletorig(i, 4)
  1314.     doubletclip(i, 5) = doubletorig(i, 5)
  1315.     doubletclip(i, 6) = doubletorig(i, 6)
  1316.     doubletclip(i, 7) = doubletorig(i, 7)
  1317. numdoubletclip = numdoubletorig
  1318.  
  1319. copy.doublets.clipwork.clip:
  1320. FOR i = 1 TO pcountdoubletclipwork
  1321.     doubletclip(i, 1) = doubletclipwork(i, 1)
  1322.     doubletclip(i, 2) = doubletclipwork(i, 2)
  1323.     doubletclip(i, 3) = doubletclipwork(i, 3)
  1324.     doubletclip(i, 4) = doubletclipwork(i, 4)
  1325.     doubletclip(i, 5) = doubletclipwork(i, 5)
  1326.     doubletclip(i, 6) = doubletclipwork(i, 6)
  1327.     doubletclip(i, 7) = doubletclipwork(i, 7)
  1328. numdoubletclip = pcountdoubletclipwork
  1329.  
  1330. 'clip.doublets.nearplane:
  1331. 'pcountdoubletclipwork = 0
  1332. 'FOR i = 1 TO numdoubletclip
  1333. '    doubletclip1dotnearplane = doubletclip(i, 1) * nearplane(1) + doubletclip(i, 2) * nearplane(2) + doubletclip(i, 3) * nearplane(3)
  1334. '    doubletclip2dotnearplane = doubletclip(i, 4) * nearplane(1) + doubletclip(i, 5) * nearplane(2) + doubletclip(i, 6) * nearplane(3)
  1335. '    gamma = doubletclip2dotnearplane / doubletclip1dotnearplane
  1336. '    Ax = (doubletclip(i, 1) - doubletclip(i, 4)) / (1 - gamma)
  1337. '    Ay = (doubletclip(i, 2) - doubletclip(i, 5)) / (1 - gamma)
  1338. '    Az = (doubletclip(i, 3) - doubletclip(i, 6)) / (1 - gamma)
  1339. '    Bx = gamma * Ax
  1340. '    By = gamma * Ay
  1341. '    Bz = gamma * Az
  1342. '    Adotnearplane = Ax * nearplane(1) + Ay * nearplane(2) + Az * nearplane(3)
  1343. '    Bdotnearplane = Bx * nearplane(1) + By * nearplane(2) + Bz * nearplane(3)
  1344. '    IF Adotnearplane > nearplane(4) AND Bdotnearplane > nearplane(4) THEN
  1345. '        pcountdoubletclipwork = pcountdoubletclipwork + 1
  1346. '        doubletclipwork(pcountdoubletclipwork, 1) = doubletclip(i, 1)
  1347. '        doubletclipwork(pcountdoubletclipwork, 2) = doubletclip(i, 2)
  1348. '        doubletclipwork(pcountdoubletclipwork, 3) = doubletclip(i, 3)
  1349. '        doubletclipwork(pcountdoubletclipwork, 4) = doubletclip(i, 4)
  1350. '        doubletclipwork(pcountdoubletclipwork, 5) = doubletclip(i, 5)
  1351. '        doubletclipwork(pcountdoubletclipwork, 6) = doubletclip(i, 6)
  1352. '        doubletclipwork(pcountdoubletclipwork, 7) = doubletclip(i, 7)
  1353. '    END IF
  1354. '    IF Adotnearplane < nearplane(4) AND Bdotnearplane < nearplane(4) THEN
  1355. '    END IF
  1356. '    IF Adotnearplane > nearplane(4) AND Bdotnearplane < nearplane(4) THEN
  1357. '        pcountdoubletclipwork = pcountdoubletclipwork + 1
  1358. '        doubletclipwork(pcountdoubletclipwork, 1) = doubletclip(i, 1)
  1359. '        doubletclipwork(pcountdoubletclipwork, 2) = doubletclip(i, 2)
  1360. '        doubletclipwork(pcountdoubletclipwork, 3) = doubletclip(i, 3)
  1361. '        doubletclipwork(pcountdoubletclipwork, 4) = doubletclip(i, 4) - Bx + nearplane(4) * nearplane(1)
  1362. '        doubletclipwork(pcountdoubletclipwork, 5) = doubletclip(i, 5) - By + nearplane(4) * nearplane(2)
  1363. '        doubletclipwork(pcountdoubletclipwork, 6) = doubletclip(i, 6) - Bz + nearplane(4) * nearplane(3)
  1364. '        doubletclipwork(pcountdoubletclipwork, 7) = doubletclip(i, 7)
  1365. '    END IF
  1366. '    IF Adotnearplane < nearplane(4) AND Bdotnearplane > nearplane(4) THEN
  1367. '        pcountdoubletclipwork = pcountdoubletclipwork + 1
  1368. '        doubletclipwork(pcountdoubletclipwork, 1) = doubletclip(i, 1) - Ax + nearplane(4) * nearplane(1)
  1369. '        doubletclipwork(pcountdoubletclipwork, 2) = doubletclip(i, 2) - Ay + nearplane(4) * nearplane(2)
  1370. '        doubletclipwork(pcountdoubletclipwork, 3) = doubletclip(i, 3) - Az + nearplane(4) * nearplane(3)
  1371. '        doubletclipwork(pcountdoubletclipwork, 4) = doubletclip(i, 4)
  1372. '        doubletclipwork(pcountdoubletclipwork, 5) = doubletclip(i, 5)
  1373. '        doubletclipwork(pcountdoubletclipwork, 6) = doubletclip(i, 6)
  1374. '        doubletclipwork(pcountdoubletclipwork, 7) = doubletclip(i, 7)
  1375. '    END IF
  1376. 'NEXT
  1377. 'RETURN
  1378.  
  1379. clip.doublets.viewplanes:
  1380. givenplanex = nearplane(1)
  1381. givenplaney = nearplane(2)
  1382. givenplanez = nearplane(3)
  1383. givenplaned = nearplane(4)
  1384. GOSUB clip.doublets.givenplane
  1385. GOSUB copy.doublets.clipwork.clip
  1386. givenplanex = rightplane(1)
  1387. givenplaney = rightplane(2)
  1388. givenplanez = rightplane(3)
  1389. givenplaned = rightplane(4)
  1390. GOSUB clip.doublets.givenplane
  1391. GOSUB copy.doublets.clipwork.clip
  1392. givenplanex = leftplane(1)
  1393. givenplaney = leftplane(2)
  1394. givenplanez = leftplane(3)
  1395. givenplaned = leftplane(4)
  1396. GOSUB clip.doublets.givenplane
  1397. GOSUB copy.doublets.clipwork.clip
  1398. givenplanex = topplane(1)
  1399. givenplaney = topplane(2)
  1400. givenplanez = topplane(3)
  1401. givenplaned = topplane(4)
  1402. GOSUB clip.doublets.givenplane
  1403. GOSUB copy.doublets.clipwork.clip
  1404. givenplanex = bottomplane(1)
  1405. givenplaney = bottomplane(2)
  1406. givenplanez = bottomplane(3)
  1407. givenplaned = bottomplane(4)
  1408. GOSUB clip.doublets.givenplane
  1409. GOSUB copy.doublets.clipwork.clip
  1410.  
  1411. clip.doublets.givenplane:
  1412. pcountdoubletclipwork = 0
  1413. FOR i = 1 TO numdoubletclip
  1414.     doubletclip1dotgivenplane = doubletclip(i, 1) * givenplanex + doubletclip(i, 2) * givenplaney + doubletclip(i, 3) * givenplanez
  1415.     doubletclip2dotgivenplane = doubletclip(i, 4) * givenplanex + doubletclip(i, 5) * givenplaney + doubletclip(i, 6) * givenplanez
  1416.     gamma = doubletclip2dotgivenplane / doubletclip1dotgivenplane
  1417.     Ax = (doubletclip(i, 1) - doubletclip(i, 4)) / (1 - gamma)
  1418.     Ay = (doubletclip(i, 2) - doubletclip(i, 5)) / (1 - gamma)
  1419.     Az = (doubletclip(i, 3) - doubletclip(i, 6)) / (1 - gamma)
  1420.     Bx = gamma * Ax
  1421.     By = gamma * Ay
  1422.     Bz = gamma * Az
  1423.     Adotgivenplane = Ax * givenplanex + Ay * givenplaney + Az * givenplanez - givenplaned
  1424.     Bdotgivenplane = Bx * givenplanex + By * givenplaney + Bz * givenplanez - givenplaned
  1425.     IF Adotgivenplane > 0 AND Bdotgivenplane > 0 THEN
  1426.         pcountdoubletclipwork = pcountdoubletclipwork + 1
  1427.         doubletclipwork(pcountdoubletclipwork, 1) = doubletclip(i, 1)
  1428.         doubletclipwork(pcountdoubletclipwork, 2) = doubletclip(i, 2)
  1429.         doubletclipwork(pcountdoubletclipwork, 3) = doubletclip(i, 3)
  1430.         doubletclipwork(pcountdoubletclipwork, 4) = doubletclip(i, 4)
  1431.         doubletclipwork(pcountdoubletclipwork, 5) = doubletclip(i, 5)
  1432.         doubletclipwork(pcountdoubletclipwork, 6) = doubletclip(i, 6)
  1433.         doubletclipwork(pcountdoubletclipwork, 7) = doubletclip(i, 7)
  1434.     END IF
  1435.     IF Adotgivenplane > 0 AND Bdotgivenplane < 0 THEN
  1436.         pcountdoubletclipwork = pcountdoubletclipwork + 1
  1437.         doubletclipwork(pcountdoubletclipwork, 1) = doubletclip(i, 1)
  1438.         doubletclipwork(pcountdoubletclipwork, 2) = doubletclip(i, 2)
  1439.         doubletclipwork(pcountdoubletclipwork, 3) = doubletclip(i, 3)
  1440.         doubletclipwork(pcountdoubletclipwork, 4) = doubletclip(i, 4) - Bx + givenplaned * givenplanex
  1441.         doubletclipwork(pcountdoubletclipwork, 5) = doubletclip(i, 5) - By + givenplaned * givenplaney
  1442.         doubletclipwork(pcountdoubletclipwork, 6) = doubletclip(i, 6) - Bz + givenplaned * givenplanez
  1443.         doubletclipwork(pcountdoubletclipwork, 7) = doubletclip(i, 7)
  1444.     END IF
  1445.     IF Adotgivenplane < 0 AND Bdotgivenplane > 0 THEN
  1446.         pcountdoubletclipwork = pcountdoubletclipwork + 1
  1447.         doubletclipwork(pcountdoubletclipwork, 1) = doubletclip(i, 1) - Ax + givenplaned * givenplanex
  1448.         doubletclipwork(pcountdoubletclipwork, 2) = doubletclip(i, 2) - Ay + givenplaned * givenplaney
  1449.         doubletclipwork(pcountdoubletclipwork, 3) = doubletclip(i, 3) - Az + givenplaned * givenplanez
  1450.         doubletclipwork(pcountdoubletclipwork, 4) = doubletclip(i, 4)
  1451.         doubletclipwork(pcountdoubletclipwork, 5) = doubletclip(i, 5)
  1452.         doubletclipwork(pcountdoubletclipwork, 6) = doubletclip(i, 6)
  1453.         doubletclipwork(pcountdoubletclipwork, 7) = doubletclip(i, 7)
  1454.     END IF
  1455.  
  1456. ' *** Define functions for doublet snipping. ***
  1457.  
  1458. copy.doublets.clip.snip:
  1459. FOR i = 1 TO numdoubletclip
  1460.     doubletsnip(i, 1) = doubletclip(i, 1)
  1461.     doubletsnip(i, 2) = doubletclip(i, 2)
  1462.     doubletsnip(i, 3) = doubletclip(i, 3)
  1463.     doubletsnip(i, 4) = doubletclip(i, 4)
  1464.     doubletsnip(i, 5) = doubletclip(i, 5)
  1465.     doubletsnip(i, 6) = doubletclip(i, 6)
  1466.     doubletsnip(i, 7) = doubletclip(i, 7)
  1467. numdoubletsnip = numdoubletclip
  1468.  
  1469. copy.doublets.snipwork.snip:
  1470. FOR i = 1 TO snipworkpcount
  1471.     doubletsnip(i, 1) = doubletsnipwork(i, 1)
  1472.     doubletsnip(i, 2) = doubletsnipwork(i, 2)
  1473.     doubletsnip(i, 3) = doubletsnipwork(i, 3)
  1474.     doubletsnip(i, 4) = doubletsnipwork(i, 4)
  1475.     doubletsnip(i, 5) = doubletsnipwork(i, 5)
  1476.     doubletsnip(i, 6) = doubletsnipwork(i, 6)
  1477.     doubletsnip(i, 7) = doubletsnipwork(i, 7)
  1478. numdoubletsnip = snipworkpcount
  1479.  
  1480. snip.doublets:
  1481. snipworkpcount = 0
  1482. FOR i = 1 TO numdoubletsnip
  1483.     Ax = doubletsnip(i, 1)
  1484.     Ay = doubletsnip(i, 2)
  1485.     Az = doubletsnip(i, 3)
  1486.     Bx = doubletsnip(i, 4)
  1487.     By = doubletsnip(i, 5)
  1488.     Bz = doubletsnip(i, 6)
  1489.     Au = doubletsnippuv(i, 1)
  1490.     Av = doubletsnippuv(i, 2)
  1491.     Bu = doubletsnippuv(i, 3)
  1492.     Bv = doubletsnippuv(i, 4)
  1493.     An = doubletsnipdotnhat(i, 1)
  1494.     Bn = doubletsnipdotnhat(i, 2)
  1495.     Asu = doubletsnippuvs(i, 1)
  1496.     Asv = doubletsnippuvs(i, 2)
  1497.     Bsu = doubletsnippuvs(i, 3)
  1498.     Bsv = doubletsnippuvs(i, 4)
  1499.     numintersections = 0
  1500.     FOR j = 1 TO numdoubletsnip
  1501.         IF i <> j THEN
  1502.             Cx = doubletsnip(j, 1)
  1503.             Cy = doubletsnip(j, 2)
  1504.             Cz = doubletsnip(j, 3)
  1505.             Dx = doubletsnip(j, 4)
  1506.             Dy = doubletsnip(j, 5)
  1507.             Dz = doubletsnip(j, 6)
  1508.             Cu = doubletsnippuv(j, 1)
  1509.             Cv = doubletsnippuv(j, 2)
  1510.             Du = doubletsnippuv(j, 3)
  1511.             Dv = doubletsnippuv(j, 4)
  1512.             Cn = doubletsnipdotnhat(j, 1)
  1513.             Dn = doubletsnipdotnhat(j, 2)
  1514.             Csu = doubletsnippuvs(j, 1)
  1515.             Csv = doubletsnippuvs(j, 2)
  1516.             Dsu = doubletsnippuvs(j, 3)
  1517.             Dsv = doubletsnippuvs(j, 4)
  1518.             magdoubletABps = SQR((Bsu - Asu) ^ 2 + (Bsv - Asv) ^ 2)
  1519.             magdoubletCDps = SQR((Dsu - Csu) ^ 2 + (Dsv - Csv) ^ 2)
  1520.             slopeAB = (Bsv - Asv) / (Bsu - Asu)
  1521.             intAB = Asv - slopeAB * Asu
  1522.             slopeCD = (Dsv - Csv) / (Dsu - Csu)
  1523.             intCD = Csv - slopeCD * Csu
  1524.             xstar = -(intAB - intCD) / (slopeAB - slopeCD)
  1525.             ystar = slopeAB * xstar + intAB
  1526.             alphaAB1u = -xstar + Asu
  1527.             alphaAB1v = -ystar + Asv
  1528.             alphaAB2u = -xstar + Bsu
  1529.             alphaAB2v = -ystar + Bsv
  1530.             alphaCD1u = -xstar + Csu
  1531.             alphaCD1v = -ystar + Csv
  1532.             alphaCD2u = -xstar + Dsu
  1533.             alphaCD2v = -ystar + Dsv
  1534.             magalphaAB1 = SQR(alphaAB1u ^ 2 + alphaAB1v ^ 2)
  1535.             magalphaAB2 = SQR(alphaAB2u ^ 2 + alphaAB2v ^ 2)
  1536.             magalphaCD1 = SQR(alphaCD1u ^ 2 + alphaCD1v ^ 2)
  1537.             magalphaCD2 = SQR(alphaCD2u ^ 2 + alphaCD2v ^ 2)
  1538.             IF magalphaAB1 < magdoubletABps AND magalphaAB2 < magdoubletABps AND magalphaCD1 < magdoubletCDps AND magalphaCD2 < magdoubletCDps THEN
  1539.                 qAB1u = (Asu - alphaAB1u) / fovd
  1540.                 '*'qAB1v = (Asv - alphaAB1v) / fovd ' (Nonessential but interesting.)
  1541.                 numerator = qAB1u * An - Au
  1542.                 denominator = Bu - Au + qAB1u * (An - Bn)
  1543.                 betaAB1 = numerator / denominator
  1544.                 '*'betaAB2 = 1 - betaAB1 ' (Nonessential but interesting.)
  1545.                 '*'qCD1u = (Csu - alphaCD1u) / fovd ' (Nonessential but interesting.)
  1546.                 '*'numerator = qCD1u * Cn - Cu ' (Nonessential but interesting.)
  1547.                 '*'denominator = Du - Cu + qCD1u * (Cn - Dn) ' (Nonessential but interesting.)
  1548.                 '*'betaCD1 = numerator / denominator ' (Nonessential but interesting.)
  1549.                 '*'betaCD2 = 1 - betaCD1 ' (Nonessential but interesting.)
  1550.                 numintersections = numintersections + 1
  1551.                 doubletintinfo(numintersections, 1) = j
  1552.                 doubletintinfo(numintersections, 2) = betaAB1
  1553.             END IF
  1554.         END IF
  1555.     NEXT
  1556.     IF numintersections = 0 THEN
  1557.         snipworkpcount = snipworkpcount + 1
  1558.         doubletsnipwork(snipworkpcount, 1) = Ax
  1559.         doubletsnipwork(snipworkpcount, 2) = Ay
  1560.         doubletsnipwork(snipworkpcount, 3) = Az
  1561.         doubletsnipwork(snipworkpcount, 4) = Bx
  1562.         doubletsnipwork(snipworkpcount, 5) = By
  1563.         doubletsnipwork(snipworkpcount, 6) = Bz
  1564.         doubletsnipwork(snipworkpcount, 7) = doubletsnip(i, 7)
  1565.     ELSE
  1566.         IF numintersections = 1 THEN
  1567.             snipworkpcount = snipworkpcount + 1
  1568.             doubletsnipwork(snipworkpcount, 1) = Ax
  1569.             doubletsnipwork(snipworkpcount, 2) = Ay
  1570.             doubletsnipwork(snipworkpcount, 3) = Az
  1571.             doubletsnipwork(snipworkpcount, 4) = Ax * (1 - doubletintinfo(1, 2)) + doubletintinfo(1, 2) * Bx
  1572.             doubletsnipwork(snipworkpcount, 5) = Ay * (1 - doubletintinfo(1, 2)) + doubletintinfo(1, 2) * By
  1573.             doubletsnipwork(snipworkpcount, 6) = Az * (1 - doubletintinfo(1, 2)) + doubletintinfo(1, 2) * Bz
  1574.             doubletsnipwork(snipworkpcount, 7) = doubletsnip(i, 7)
  1575.             snipworkpcount = snipworkpcount + 1
  1576.             doubletsnipwork(snipworkpcount, 1) = Ax * (1 - doubletintinfo(1, 2)) + doubletintinfo(1, 2) * Bx
  1577.             doubletsnipwork(snipworkpcount, 2) = Ay * (1 - doubletintinfo(1, 2)) + doubletintinfo(1, 2) * By
  1578.             doubletsnipwork(snipworkpcount, 3) = Az * (1 - doubletintinfo(1, 2)) + doubletintinfo(1, 2) * Bz
  1579.             doubletsnipwork(snipworkpcount, 4) = Bx
  1580.             doubletsnipwork(snipworkpcount, 5) = By
  1581.             doubletsnipwork(snipworkpcount, 6) = Bz
  1582.             doubletsnipwork(snipworkpcount, 7) = doubletsnip(i, 7)
  1583.         ELSE
  1584.             snipworkpcount = snipworkpcount + 1
  1585.             doubletsnipwork(snipworkpcount, 1) = Ax
  1586.             doubletsnipwork(snipworkpcount, 2) = Ay
  1587.             doubletsnipwork(snipworkpcount, 3) = Az
  1588.             doubletsnipwork(snipworkpcount, 4) = Ax * (1 - doubletintinfo(1, 2)) + doubletintinfo(1, 2) * Bx
  1589.             doubletsnipwork(snipworkpcount, 5) = Ay * (1 - doubletintinfo(1, 2)) + doubletintinfo(1, 2) * By
  1590.             doubletsnipwork(snipworkpcount, 6) = Az * (1 - doubletintinfo(1, 2)) + doubletintinfo(1, 2) * Bz
  1591.             doubletsnipwork(snipworkpcount, 7) = doubletsnip(i, 7)
  1592.             snipworkpcount = snipworkpcount + 1
  1593.             doubletsnipwork(snipworkpcount, 1) = Ax * (1 - doubletintinfo(numintersections, 2)) + doubletintinfo(numintersections, 2) * Bx
  1594.             doubletsnipwork(snipworkpcount, 2) = Ay * (1 - doubletintinfo(numintersections, 2)) + doubletintinfo(numintersections, 2) * By
  1595.             doubletsnipwork(snipworkpcount, 3) = Az * (1 - doubletintinfo(numintersections, 2)) + doubletintinfo(numintersections, 2) * Bz
  1596.             doubletsnipwork(snipworkpcount, 4) = Bx
  1597.             doubletsnipwork(snipworkpcount, 5) = By
  1598.             doubletsnipwork(snipworkpcount, 6) = Bz
  1599.             doubletsnipwork(snipworkpcount, 7) = doubletsnip(i, 7)
  1600.             FOR k = 1 TO numintersections - 1
  1601.                 snipworkpcount = snipworkpcount + 1
  1602.                 doubletsnipwork(snipworkpcount, 1) = Ax * (1 - doubletintinfo(k, 2)) + doubletintinfo(k, 2) * Bx
  1603.                 doubletsnipwork(snipworkpcount, 2) = Ay * (1 - doubletintinfo(k, 2)) + doubletintinfo(k, 2) * By
  1604.                 doubletsnipwork(snipworkpcount, 3) = Az * (1 - doubletintinfo(k, 2)) + doubletintinfo(k, 2) * Bz
  1605.                 doubletsnipwork(snipworkpcount, 4) = Ax * (1 - doubletintinfo(k + 1, 2)) + doubletintinfo(k + 1, 2) * Bx
  1606.                 doubletsnipwork(snipworkpcount, 5) = Ay * (1 - doubletintinfo(k + 1, 2)) + doubletintinfo(k + 1, 2) * By
  1607.                 doubletsnipwork(snipworkpcount, 6) = Az * (1 - doubletintinfo(k + 1, 2)) + doubletintinfo(k + 1, 2) * Bz
  1608.                 doubletsnipwork(snipworkpcount, 7) = doubletsnip(i, 7)
  1609.             NEXT
  1610.         END IF
  1611.     END IF
  1612.  
  1613. ' *** Define functions for triplet manipulations. ***
  1614.  
  1615. project.triplets:
  1616. FOR i = 1 TO numtripletfinal
  1617.     tripletfinaldotnhat(i, 1) = tripletfinal(i, 1) * nhat(1) + tripletfinal(i, 2) * nhat(2) + tripletfinal(i, 3) * nhat(3)
  1618.     tripletfinaldotnhat(i, 2) = tripletfinal(i, 4) * nhat(1) + tripletfinal(i, 5) * nhat(2) + tripletfinal(i, 6) * nhat(3)
  1619.     tripletfinaldotnhat(i, 3) = tripletfinal(i, 7) * nhat(1) + tripletfinal(i, 8) * nhat(2) + tripletfinal(i, 9) * nhat(3)
  1620.     tripletfinalpuv(i, 1) = tripletfinal(i, 1) * uhat(1) + tripletfinal(i, 2) * uhat(2) + tripletfinal(i, 3) * uhat(3)
  1621.     tripletfinalpuv(i, 2) = tripletfinal(i, 1) * vhat(1) + tripletfinal(i, 2) * vhat(2) + tripletfinal(i, 3) * vhat(3)
  1622.     tripletfinalpuv(i, 3) = tripletfinal(i, 4) * uhat(1) + tripletfinal(i, 5) * uhat(2) + tripletfinal(i, 6) * uhat(3)
  1623.     tripletfinalpuv(i, 4) = tripletfinal(i, 4) * vhat(1) + tripletfinal(i, 5) * vhat(2) + tripletfinal(i, 6) * vhat(3)
  1624.     tripletfinalpuv(i, 5) = tripletfinal(i, 7) * uhat(1) + tripletfinal(i, 8) * uhat(2) + tripletfinal(i, 9) * uhat(3)
  1625.     tripletfinalpuv(i, 6) = tripletfinal(i, 7) * vhat(1) + tripletfinal(i, 8) * vhat(2) + tripletfinal(i, 9) * vhat(3)
  1626.  
  1627. depth.adjust.triplets:
  1628. FOR i = 1 TO numtripletfinal
  1629.     tripletfinalpuvs(i, 1) = tripletfinalpuv(i, 1) * fovd / tripletfinaldotnhat(i, 1)
  1630.     tripletfinalpuvs(i, 2) = tripletfinalpuv(i, 2) * fovd / tripletfinaldotnhat(i, 1)
  1631.     tripletfinalpuvs(i, 3) = tripletfinalpuv(i, 3) * fovd / tripletfinaldotnhat(i, 2)
  1632.     tripletfinalpuvs(i, 4) = tripletfinalpuv(i, 4) * fovd / tripletfinaldotnhat(i, 2)
  1633.     tripletfinalpuvs(i, 5) = tripletfinalpuv(i, 5) * fovd / tripletfinaldotnhat(i, 3)
  1634.     tripletfinalpuvs(i, 6) = tripletfinalpuv(i, 6) * fovd / tripletfinaldotnhat(i, 3)
  1635.  
  1636. ' *** Define functions for triplet backface culling. ***
  1637.  
  1638. triplet.filter.faceon:
  1639. pcounttripletfaceon = 0
  1640. FOR i = 1 TO numtripletorig
  1641.     Ax = tripletorig(i, 4) - tripletorig(i, 1)
  1642.     Ay = tripletorig(i, 5) - tripletorig(i, 2)
  1643.     Az = tripletorig(i, 6) - tripletorig(i, 3)
  1644.     Bx = tripletorig(i, 7) - tripletorig(i, 1)
  1645.     By = tripletorig(i, 8) - tripletorig(i, 2)
  1646.     Bz = tripletorig(i, 9) - tripletorig(i, 3)
  1647.     centroiDx = (1 / 3) * (tripletorig(i, 1) + tripletorig(i, 4) + tripletorig(i, 7))
  1648.     centroiDy = (1 / 3) * (tripletorig(i, 2) + tripletorig(i, 5) + tripletorig(i, 8))
  1649.     centroidz = (1 / 3) * (tripletorig(i, 3) + tripletorig(i, 6) + tripletorig(i, 9))
  1650.     PanelNormx = Ay * Bz - Az * By
  1651.     PanelNormy = Az * Bx - Ax * Bz
  1652.     PanelNormz = Ax * By - Ay * Bx
  1653.     mag = SQR(PanelNormx ^ 2 + PanelNormy ^ 2 + PanelNormz ^ 2)
  1654.     PanelNormx = PanelNormx / mag
  1655.     PanelNormy = PanelNormy / mag
  1656.     PanelNormz = PanelNormz / mag
  1657.     panelnormdotnhat = PanelNormx * nhat(1) + PanelNormy * nhat(2) + PanelNormz * nhat(3)
  1658.     cullpoint = PanelNormx * centroiDx + PanelNormy * centroiDy + PanelNormz * centroidz
  1659.     IF panelnormdotnhat >= cullpoint THEN
  1660.         pcounttripletfaceon = pcounttripletfaceon + 1
  1661.         tripletfaceon(pcounttripletfaceon, 1) = tripletorig(i, 1)
  1662.         tripletfaceon(pcounttripletfaceon, 2) = tripletorig(i, 2)
  1663.         tripletfaceon(pcounttripletfaceon, 3) = tripletorig(i, 3)
  1664.         tripletfaceon(pcounttripletfaceon, 4) = tripletorig(i, 4)
  1665.         tripletfaceon(pcounttripletfaceon, 5) = tripletorig(i, 5)
  1666.         tripletfaceon(pcounttripletfaceon, 6) = tripletorig(i, 6)
  1667.         tripletfaceon(pcounttripletfaceon, 7) = tripletorig(i, 7)
  1668.         tripletfaceon(pcounttripletfaceon, 8) = tripletorig(i, 8)
  1669.         tripletfaceon(pcounttripletfaceon, 9) = tripletorig(i, 9)
  1670.         tripletfaceon(pcounttripletfaceon, 10) = tripletorig(i, 10)
  1671.     ELSE
  1672.         'pcounttripletfaceon = pcounttripletfaceon + 1
  1673.         'tripletfaceon(pcounttripletfaceon, 1) = tripletorig(i, 1)
  1674.         'tripletfaceon(pcounttripletfaceon, 2) = tripletorig(i, 2)
  1675.         'tripletfaceon(pcounttripletfaceon, 3) = tripletorig(i, 3)
  1676.         'tripletfaceon(pcounttripletfaceon, 4) = tripletorig(i, 4)
  1677.         'tripletfaceon(pcounttripletfaceon, 5) = tripletorig(i, 5)
  1678.         'tripletfaceon(pcounttripletfaceon, 6) = tripletorig(i, 6)
  1679.         'tripletfaceon(pcounttripletfaceon, 7) = tripletorig(i, 7)
  1680.         'tripletfaceon(pcounttripletfaceon, 8) = tripletorig(i, 8)
  1681.         'tripletfaceon(pcounttripletfaceon, 9) = tripletorig(i, 9)
  1682.         'tripletfaceon(pcounttripletfaceon, 10) = 8
  1683.     END IF
  1684. numtripletfaceon = pcounttripletfaceon
  1685.  
  1686. ' *** Define functions for triplet viewplane clipping. ***
  1687.  
  1688.  
  1689. copy.triplets.faceon.clip:
  1690. FOR i = 1 TO numtripletfaceon
  1691.     tripletclip(i, 1) = tripletfaceon(i, 1)
  1692.     tripletclip(i, 2) = tripletfaceon(i, 2)
  1693.     tripletclip(i, 3) = tripletfaceon(i, 3)
  1694.     tripletclip(i, 4) = tripletfaceon(i, 4)
  1695.     tripletclip(i, 5) = tripletfaceon(i, 5)
  1696.     tripletclip(i, 6) = tripletfaceon(i, 6)
  1697.     tripletclip(i, 7) = tripletfaceon(i, 7)
  1698.     tripletclip(i, 8) = tripletfaceon(i, 8)
  1699.     tripletclip(i, 9) = tripletfaceon(i, 9)
  1700.     tripletclip(i, 10) = tripletfaceon(i, 10)
  1701. numtripletclip = numtripletfaceon
  1702.  
  1703. copy.triplets.clipwork.clip:
  1704. FOR i = 1 TO pcounttripletclipwork
  1705.     tripletclip(i, 1) = tripletclipwork(i, 1)
  1706.     tripletclip(i, 2) = tripletclipwork(i, 2)
  1707.     tripletclip(i, 3) = tripletclipwork(i, 3)
  1708.     tripletclip(i, 4) = tripletclipwork(i, 4)
  1709.     tripletclip(i, 5) = tripletclipwork(i, 5)
  1710.     tripletclip(i, 6) = tripletclipwork(i, 6)
  1711.     tripletclip(i, 7) = tripletclipwork(i, 7)
  1712.     tripletclip(i, 8) = tripletclipwork(i, 8)
  1713.     tripletclip(i, 9) = tripletclipwork(i, 9)
  1714.     tripletclip(i, 10) = tripletclipwork(i, 10)
  1715. numtripletclip = pcounttripletclipwork
  1716.  
  1717. clip.triplets.viewplanes:
  1718. givenplanex = nearplane(1)
  1719. givenplaney = nearplane(2)
  1720. givenplanez = nearplane(3)
  1721. givenplaned = nearplane(4)
  1722. GOSUB clip.triplets.givenplane
  1723. GOSUB copy.triplets.clipwork.clip
  1724. givenplanex = rightplane(1)
  1725. givenplaney = rightplane(2)
  1726. givenplanez = rightplane(3)
  1727. givenplaned = rightplane(4)
  1728. GOSUB clip.triplets.givenplane
  1729. GOSUB copy.triplets.clipwork.clip
  1730. givenplanex = leftplane(1)
  1731. givenplaney = leftplane(2)
  1732. givenplanez = leftplane(3)
  1733. givenplaned = leftplane(4)
  1734. GOSUB clip.triplets.givenplane
  1735. GOSUB copy.triplets.clipwork.clip
  1736. givenplanex = topplane(1)
  1737. givenplaney = topplane(2)
  1738. givenplanez = topplane(3)
  1739. givenplaned = topplane(4)
  1740. GOSUB clip.triplets.givenplane
  1741. GOSUB copy.triplets.clipwork.clip
  1742. givenplanex = bottomplane(1)
  1743. givenplaney = bottomplane(2)
  1744. givenplanez = bottomplane(3)
  1745. givenplaned = bottomplane(4)
  1746. GOSUB clip.triplets.givenplane
  1747. GOSUB copy.triplets.clipwork.clip
  1748.  
  1749. clip.triplets.givenplane:
  1750. pcounttripletclipwork = 0
  1751. FOR i = 1 TO numtripletclip
  1752.     tripletclip1dotgivenplane = tripletclip(i, 1) * givenplanex + tripletclip(i, 2) * givenplaney + tripletclip(i, 3) * givenplanez - givenplaned
  1753.     tripletclip2dotgivenplane = tripletclip(i, 4) * givenplanex + tripletclip(i, 5) * givenplaney + tripletclip(i, 6) * givenplanez - givenplaned
  1754.     tripletclip3dotgivenplane = tripletclip(i, 7) * givenplanex + tripletclip(i, 8) * givenplaney + tripletclip(i, 9) * givenplanez - givenplaned
  1755.     gamma12 = tripletclip2dotgivenplane / tripletclip1dotgivenplane
  1756.     gamma23 = tripletclip3dotgivenplane / tripletclip2dotgivenplane
  1757.     gamma31 = tripletclip1dotgivenplane / tripletclip3dotgivenplane
  1758.     A12x = (tripletclip(i, 1) - tripletclip(i, 4)) / (1 - gamma12)
  1759.     A12y = (tripletclip(i, 2) - tripletclip(i, 5)) / (1 - gamma12)
  1760.     A12z = (tripletclip(i, 3) - tripletclip(i, 6)) / (1 - gamma12)
  1761.     B12x = gamma12 * A12x
  1762.     B12y = gamma12 * A12y
  1763.     B12z = gamma12 * A12z
  1764.     A23x = (tripletclip(i, 4) - tripletclip(i, 7)) / (1 - gamma23)
  1765.     A23y = (tripletclip(i, 5) - tripletclip(i, 8)) / (1 - gamma23)
  1766.     A23z = (tripletclip(i, 6) - tripletclip(i, 9)) / (1 - gamma23)
  1767.     B23x = gamma23 * A23x
  1768.     B23y = gamma23 * A23y
  1769.     B23z = gamma23 * A23z
  1770.     A31x = (tripletclip(i, 7) - tripletclip(i, 1)) / (1 - gamma31)
  1771.     A31y = (tripletclip(i, 8) - tripletclip(i, 2)) / (1 - gamma31)
  1772.     A31z = (tripletclip(i, 9) - tripletclip(i, 3)) / (1 - gamma31)
  1773.     B31x = gamma31 * A31x
  1774.     B31y = gamma31 * A31y
  1775.     B31z = gamma31 * A31z
  1776.     A12dotgivenplane = A12x * givenplanex + A12y * givenplaney + A12z * givenplanez
  1777.     B12dotgivenplane = B12x * givenplanex + B12y * givenplaney + B12z * givenplanez
  1778.     A23dotgivenplane = A23x * givenplanex + A23y * givenplaney + A23z * givenplanez
  1779.     B23dotgivenplane = B23x * givenplanex + B23y * givenplaney + B23z * givenplanez
  1780.     A31dotgivenplane = A31x * givenplanex + A31y * givenplaney + A31z * givenplanez
  1781.     B31dotgivenplane = B31x * givenplanex + B31y * givenplaney + B31z * givenplanez
  1782.     IF A12dotgivenplane > 0 AND B12dotgivenplane > 0 AND A23dotgivenplane > 0 AND B23dotgivenplane > 0 AND A31dotgivenplane > 0 AND B31dotgivenplane > 0 THEN
  1783.         pcounttripletclipwork = pcounttripletclipwork + 1
  1784.         tripletclipwork(pcounttripletclipwork, 1) = tripletclip(i, 1)
  1785.         tripletclipwork(pcounttripletclipwork, 2) = tripletclip(i, 2)
  1786.         tripletclipwork(pcounttripletclipwork, 3) = tripletclip(i, 3)
  1787.         tripletclipwork(pcounttripletclipwork, 4) = tripletclip(i, 4)
  1788.         tripletclipwork(pcounttripletclipwork, 5) = tripletclip(i, 5)
  1789.         tripletclipwork(pcounttripletclipwork, 6) = tripletclip(i, 6)
  1790.         tripletclipwork(pcounttripletclipwork, 7) = tripletclip(i, 7)
  1791.         tripletclipwork(pcounttripletclipwork, 8) = tripletclip(i, 8)
  1792.         tripletclipwork(pcounttripletclipwork, 9) = tripletclip(i, 9)
  1793.         tripletclipwork(pcounttripletclipwork, 10) = tripletclip(i, 10)
  1794.         panelinview = 1
  1795.     END IF
  1796.     IF A12dotgivenplane > 0 AND B12dotgivenplane > 0 AND A23dotgivenplane > 0 AND B23dotgivenplane < 0 AND A31dotgivenplane < 0 AND B31dotgivenplane > 0 THEN
  1797.         pcounttripletclipwork = pcounttripletclipwork + 1
  1798.         tripletclipwork(pcounttripletclipwork, 1) = tripletclip(i, 1)
  1799.         tripletclipwork(pcounttripletclipwork, 2) = tripletclip(i, 2)
  1800.         tripletclipwork(pcounttripletclipwork, 3) = tripletclip(i, 3)
  1801.         tripletclipwork(pcounttripletclipwork, 4) = tripletclip(i, 1) - B31x + givenplaned * givenplanex
  1802.         tripletclipwork(pcounttripletclipwork, 5) = tripletclip(i, 2) - B31y + givenplaned * givenplaney
  1803.         tripletclipwork(pcounttripletclipwork, 6) = tripletclip(i, 3) - B31z + givenplaned * givenplanez
  1804.         tripletclipwork(pcounttripletclipwork, 7) = tripletclip(i, 7) - B23x + givenplaned * givenplanex
  1805.         tripletclipwork(pcounttripletclipwork, 8) = tripletclip(i, 8) - B23y + givenplaned * givenplaney
  1806.         tripletclipwork(pcounttripletclipwork, 9) = tripletclip(i, 9) - B23z + givenplaned * givenplanez
  1807.         tripletclipwork(pcounttripletclipwork, 10) = tripletclip(i, 10)
  1808.         pcounttripletclipwork = pcounttripletclipwork + 1
  1809.         tripletclipwork(pcounttripletclipwork, 1) = tripletclip(i, 1)
  1810.         tripletclipwork(pcounttripletclipwork, 2) = tripletclip(i, 2)
  1811.         tripletclipwork(pcounttripletclipwork, 3) = tripletclip(i, 3)
  1812.         tripletclipwork(pcounttripletclipwork, 4) = tripletclip(i, 4)
  1813.         tripletclipwork(pcounttripletclipwork, 5) = tripletclip(i, 5)
  1814.         tripletclipwork(pcounttripletclipwork, 6) = tripletclip(i, 6)
  1815.         tripletclipwork(pcounttripletclipwork, 7) = tripletclip(i, 7) - B23x + givenplaned * givenplanex
  1816.         tripletclipwork(pcounttripletclipwork, 8) = tripletclip(i, 8) - B23y + givenplaned * givenplaney
  1817.         tripletclipwork(pcounttripletclipwork, 9) = tripletclip(i, 9) - B23z + givenplaned * givenplanez
  1818.         tripletclipwork(pcounttripletclipwork, 10) = tripletclip(i, 10)
  1819.     END IF
  1820.     IF A12dotgivenplane < 0 AND B12dotgivenplane > 0 AND A23dotgivenplane > 0 AND B23dotgivenplane > 0 AND A31dotgivenplane > 0 AND B31dotgivenplane < 0 THEN
  1821.         pcounttripletclipwork = pcounttripletclipwork + 1
  1822.         tripletclipwork(pcounttripletclipwork, 1) = tripletclip(i, 7)
  1823.         tripletclipwork(pcounttripletclipwork, 2) = tripletclip(i, 8)
  1824.         tripletclipwork(pcounttripletclipwork, 3) = tripletclip(i, 9)
  1825.         tripletclipwork(pcounttripletclipwork, 4) = tripletclip(i, 1) - B31x + givenplaned * givenplanex
  1826.         tripletclipwork(pcounttripletclipwork, 5) = tripletclip(i, 2) - B31y + givenplaned * givenplaney
  1827.         tripletclipwork(pcounttripletclipwork, 6) = tripletclip(i, 3) - B31z + givenplaned * givenplanez
  1828.         tripletclipwork(pcounttripletclipwork, 7) = tripletclip(i, 4)
  1829.         tripletclipwork(pcounttripletclipwork, 8) = tripletclip(i, 5)
  1830.         tripletclipwork(pcounttripletclipwork, 9) = tripletclip(i, 6)
  1831.         tripletclipwork(pcounttripletclipwork, 10) = tripletclip(i, 10)
  1832.         pcounttripletclipwork = pcounttripletclipwork + 1
  1833.         tripletclipwork(pcounttripletclipwork, 1) = tripletclip(i, 4)
  1834.         tripletclipwork(pcounttripletclipwork, 2) = tripletclip(i, 5)
  1835.         tripletclipwork(pcounttripletclipwork, 3) = tripletclip(i, 6)
  1836.         tripletclipwork(pcounttripletclipwork, 4) = tripletclip(i, 1) - B31x + givenplaned * givenplanex
  1837.         tripletclipwork(pcounttripletclipwork, 5) = tripletclip(i, 2) - B31y + givenplaned * givenplaney
  1838.         tripletclipwork(pcounttripletclipwork, 6) = tripletclip(i, 3) - B31z + givenplaned * givenplanez
  1839.         tripletclipwork(pcounttripletclipwork, 7) = tripletclip(i, 4) - B12x + givenplaned * givenplanex
  1840.         tripletclipwork(pcounttripletclipwork, 8) = tripletclip(i, 5) - B12y + givenplaned * givenplaney
  1841.         tripletclipwork(pcounttripletclipwork, 9) = tripletclip(i, 6) - B12z + givenplaned * givenplanez
  1842.         tripletclipwork(pcounttripletclipwork, 10) = tripletclip(i, 10)
  1843.     END IF
  1844.     IF A12dotgivenplane > 0 AND B12dotgivenplane < 0 AND A23dotgivenplane < 0 AND B23dotgivenplane > 0 AND A31dotgivenplane > 0 AND B31dotgivenplane > 0 THEN
  1845.         pcounttripletclipwork = pcounttripletclipwork + 1
  1846.         tripletclipwork(pcounttripletclipwork, 1) = tripletclip(i, 1)
  1847.         tripletclipwork(pcounttripletclipwork, 2) = tripletclip(i, 2)
  1848.         tripletclipwork(pcounttripletclipwork, 3) = tripletclip(i, 3)
  1849.         tripletclipwork(pcounttripletclipwork, 4) = tripletclip(i, 4) - B12x + givenplaned * givenplanex
  1850.         tripletclipwork(pcounttripletclipwork, 5) = tripletclip(i, 5) - B12y + givenplaned * givenplaney
  1851.         tripletclipwork(pcounttripletclipwork, 6) = tripletclip(i, 6) - B12z + givenplaned * givenplanez
  1852.         tripletclipwork(pcounttripletclipwork, 7) = tripletclip(i, 7)
  1853.         tripletclipwork(pcounttripletclipwork, 8) = tripletclip(i, 8)
  1854.         tripletclipwork(pcounttripletclipwork, 9) = tripletclip(i, 9)
  1855.         tripletclipwork(pcounttripletclipwork, 10) = tripletclip(i, 10)
  1856.         pcounttripletclipwork = pcounttripletclipwork + 1
  1857.         tripletclipwork(pcounttripletclipwork, 1) = tripletclip(i, 7)
  1858.         tripletclipwork(pcounttripletclipwork, 2) = tripletclip(i, 8)
  1859.         tripletclipwork(pcounttripletclipwork, 3) = tripletclip(i, 9)
  1860.         tripletclipwork(pcounttripletclipwork, 4) = tripletclip(i, 4) - B12x + givenplaned * givenplanex
  1861.         tripletclipwork(pcounttripletclipwork, 5) = tripletclip(i, 5) - B12y + givenplaned * givenplaney
  1862.         tripletclipwork(pcounttripletclipwork, 6) = tripletclip(i, 6) - B12z + givenplaned * givenplanez
  1863.         tripletclipwork(pcounttripletclipwork, 7) = tripletclip(i, 7) - B23x + givenplaned * givenplanex
  1864.         tripletclipwork(pcounttripletclipwork, 8) = tripletclip(i, 8) - B23y + givenplaned * givenplaney
  1865.         tripletclipwork(pcounttripletclipwork, 9) = tripletclip(i, 9) - B23z + givenplaned * givenplanez
  1866.         tripletclipwork(pcounttripletclipwork, 10) = tripletclip(i, 10)
  1867.     END IF
  1868.     IF A12dotgivenplane > 0 AND B12dotgivenplane < 0 AND A23dotgivenplane < 0 AND B23dotgivenplane < 0 AND A31dotgivenplane < 0 AND B31dotgivenplane > 0 THEN
  1869.         pcounttripletclipwork = pcounttripletclipwork + 1
  1870.         tripletclipwork(pcounttripletclipwork, 1) = tripletclip(i, 1)
  1871.         tripletclipwork(pcounttripletclipwork, 2) = tripletclip(i, 2)
  1872.         tripletclipwork(pcounttripletclipwork, 3) = tripletclip(i, 3)
  1873.         tripletclipwork(pcounttripletclipwork, 4) = tripletclip(i, 4) - B12x + givenplaned * givenplanex
  1874.         tripletclipwork(pcounttripletclipwork, 5) = tripletclip(i, 5) - B12y + givenplaned * givenplaney
  1875.         tripletclipwork(pcounttripletclipwork, 6) = tripletclip(i, 6) - B12z + givenplaned * givenplanez
  1876.         tripletclipwork(pcounttripletclipwork, 7) = tripletclip(i, 1) - B31x + givenplaned * givenplanex
  1877.         tripletclipwork(pcounttripletclipwork, 8) = tripletclip(i, 2) - B31y + givenplaned * givenplaney
  1878.         tripletclipwork(pcounttripletclipwork, 9) = tripletclip(i, 3) - B31z + givenplaned * givenplanez
  1879.         tripletclipwork(pcounttripletclipwork, 10) = tripletclip(i, 10)
  1880.     END IF
  1881.     IF A12dotgivenplane < 0 AND B12dotgivenplane > 0 AND A23dotgivenplane > 0 AND B23dotgivenplane < 0 AND A31dotgivenplane < 0 AND B31dotgivenplane < 0 THEN
  1882.         pcounttripletclipwork = pcounttripletclipwork + 1
  1883.         tripletclipwork(pcounttripletclipwork, 1) = tripletclip(i, 4)
  1884.         tripletclipwork(pcounttripletclipwork, 2) = tripletclip(i, 5)
  1885.         tripletclipwork(pcounttripletclipwork, 3) = tripletclip(i, 6)
  1886.         tripletclipwork(pcounttripletclipwork, 4) = tripletclip(i, 7) - B23x + givenplaned * givenplanex
  1887.         tripletclipwork(pcounttripletclipwork, 5) = tripletclip(i, 8) - B23y + givenplaned * givenplaney
  1888.         tripletclipwork(pcounttripletclipwork, 6) = tripletclip(i, 9) - B23z + givenplaned * givenplanez
  1889.         tripletclipwork(pcounttripletclipwork, 7) = tripletclip(i, 4) - B12x + givenplaned * givenplanex
  1890.         tripletclipwork(pcounttripletclipwork, 8) = tripletclip(i, 5) - B12y + givenplaned * givenplaney
  1891.         tripletclipwork(pcounttripletclipwork, 9) = tripletclip(i, 6) - B12z + givenplaned * givenplanez
  1892.         tripletclipwork(pcounttripletclipwork, 10) = tripletclip(i, 10)
  1893.     END IF
  1894.     IF A12dotgivenplane < 0 AND B12dotgivenplane < 0 AND A23dotgivenplane < 0 AND B23dotgivenplane > 0 AND A31dotgivenplane > 0 AND B31dotgivenplane < 0 THEN
  1895.         pcounttripletclipwork = pcounttripletclipwork + 1
  1896.         tripletclipwork(pcounttripletclipwork, 1) = tripletclip(i, 7)
  1897.         tripletclipwork(pcounttripletclipwork, 2) = tripletclip(i, 8)
  1898.         tripletclipwork(pcounttripletclipwork, 3) = tripletclip(i, 9)
  1899.         tripletclipwork(pcounttripletclipwork, 4) = tripletclip(i, 7) - B23x + givenplaned * givenplanex
  1900.         tripletclipwork(pcounttripletclipwork, 5) = tripletclip(i, 8) - B23y + givenplaned * givenplaney
  1901.         tripletclipwork(pcounttripletclipwork, 6) = tripletclip(i, 9) - B23z + givenplaned * givenplanez
  1902.         tripletclipwork(pcounttripletclipwork, 7) = tripletclip(i, 1) - B31x + givenplaned * givenplanex
  1903.         tripletclipwork(pcounttripletclipwork, 8) = tripletclip(i, 2) - B31y + givenplaned * givenplaney
  1904.         tripletclipwork(pcounttripletclipwork, 9) = tripletclip(i, 3) - B31z + givenplaned * givenplanez
  1905.         tripletclipwork(pcounttripletclipwork, 10) = tripletclip(i, 10)
  1906.     END IF
  1907.  
  1908. ' *** Define functions for triplet snipping. ***
  1909.  
  1910. copy.triplets.clip.snip:
  1911. FOR i = 1 TO numtripletclip
  1912.     tripletsnip(i, 1) = tripletclip(i, 1)
  1913.     tripletsnip(i, 2) = tripletclip(i, 2)
  1914.     tripletsnip(i, 3) = tripletclip(i, 3)
  1915.     tripletsnip(i, 4) = tripletclip(i, 4)
  1916.     tripletsnip(i, 5) = tripletclip(i, 5)
  1917.     tripletsnip(i, 6) = tripletclip(i, 6)
  1918.     tripletsnip(i, 7) = tripletclip(i, 7)
  1919.     tripletsnip(i, 8) = tripletclip(i, 8)
  1920.     tripletsnip(i, 9) = tripletclip(i, 9)
  1921.     tripletsnip(i, 10) = tripletclip(i, 10)
  1922. numtripletsnip = numtripletclip
  1923.  
  1924. snip.triplets:
  1925. snipworkpcount = 0
  1926. FOR i = 1 TO numtripletsnip
  1927.     pcounttripletsnipimage = 1
  1928.     tripletsnipimage(1, 1) = tripletsnip(i, 1)
  1929.     tripletsnipimage(1, 2) = tripletsnip(i, 2)
  1930.     tripletsnipimage(1, 3) = tripletsnip(i, 3)
  1931.     tripletsnipimage(1, 4) = tripletsnip(i, 4)
  1932.     tripletsnipimage(1, 5) = tripletsnip(i, 5)
  1933.     tripletsnipimage(1, 6) = tripletsnip(i, 6)
  1934.     tripletsnipimage(1, 7) = tripletsnip(i, 7)
  1935.     tripletsnipimage(1, 8) = tripletsnip(i, 8)
  1936.     tripletsnipimage(1, 9) = tripletsnip(i, 9)
  1937.     tripletsnipimage(1, 10) = tripletsnip(i, 10)
  1938.     begintripletsnipsubloop:
  1939.     FOR k = 1 TO pcounttripletsnipimage
  1940.         FOR j = 1 TO numtripletsnip
  1941.             IF j <> i THEN
  1942.                 IF pcounttripletsnipimage > numtripletsnip + 5 THEN
  1943.                     ' Error case. The 5 is completely arbitrary.
  1944.                     GOTO bypasssniploop
  1945.                 END IF
  1946.                 Ax = tripletsnipimage(k, 1)
  1947.                 Ay = tripletsnipimage(k, 2)
  1948.                 Az = tripletsnipimage(k, 3)
  1949.                 Bx = tripletsnipimage(k, 4)
  1950.                 By = tripletsnipimage(k, 5)
  1951.                 Bz = tripletsnipimage(k, 6)
  1952.                 Cx = tripletsnipimage(k, 7)
  1953.                 Cy = tripletsnipimage(k, 8)
  1954.                 Cz = tripletsnipimage(k, 9)
  1955.                 Au = Ax * uhat(1) + Ay * uhat(2) + Az * uhat(3)
  1956.                 Av = Ax * vhat(1) + Ay * vhat(2) + Az * vhat(3)
  1957.                 Bu = Bx * uhat(1) + By * uhat(2) + Bz * uhat(3)
  1958.                 Bv = Bx * vhat(1) + By * vhat(2) + Bz * vhat(3)
  1959.                 Cu = Cx * uhat(1) + Cy * uhat(2) + Cz * uhat(3)
  1960.                 Cv = Cx * vhat(1) + Cy * vhat(2) + Cz * vhat(3)
  1961.                 An = Ax * nhat(1) + Ay * nhat(2) + Az * nhat(3)
  1962.                 Bn = Bx * nhat(1) + By * nhat(2) + Bz * nhat(3)
  1963.                 Cn = Cx * nhat(1) + Cy * nhat(2) + Cz * nhat(3)
  1964.                 Asu = Au * fovd / An
  1965.                 Asv = Av * fovd / An
  1966.                 Bsu = Bu * fovd / Bn
  1967.                 Bsv = Bv * fovd / Bn
  1968.                 Csu = Cu * fovd / Cn
  1969.                 Csv = Cv * fovd / Cn
  1970.                 Dx = tripletsnip(j, 1)
  1971.                 Dy = tripletsnip(j, 2)
  1972.                 Dz = tripletsnip(j, 3)
  1973.                 Ex = tripletsnip(j, 4)
  1974.                 Ey = tripletsnip(j, 5)
  1975.                 Ez = tripletsnip(j, 6)
  1976.                 Fx = tripletsnip(j, 7)
  1977.                 Fy = tripletsnip(j, 8)
  1978.                 Fz = tripletsnip(j, 9)
  1979.                 Du = Dx * uhat(1) + Dy * uhat(2) + Dz * uhat(3)
  1980.                 Dv = Dx * vhat(1) + Dy * vhat(2) + Dz * vhat(3)
  1981.                 Eu = Ex * uhat(1) + Ey * uhat(2) + Ez * uhat(3)
  1982.                 Ev = Ex * vhat(1) + Ey * vhat(2) + Ez * vhat(3)
  1983.                 Fu = Fx * uhat(1) + Fy * uhat(2) + Fz * uhat(3)
  1984.                 Fv = Fx * vhat(1) + Fy * vhat(2) + Fz * vhat(3)
  1985.                 Dn = Dx * nhat(1) + Dy * nhat(2) + Dz * nhat(3)
  1986.                 En = Ex * nhat(1) + Ey * nhat(2) + Ez * nhat(3)
  1987.                 Fn = Fx * nhat(1) + Fy * nhat(2) + Fz * nhat(3)
  1988.                 Dsu = Du * fovd / Dn
  1989.                 Dsv = Dv * fovd / Dn
  1990.                 Esu = Eu * fovd / En
  1991.                 Esv = Ev * fovd / En
  1992.                 Fsu = Fu * fovd / Fn
  1993.                 Fsv = Fv * fovd / Fn
  1994.                 GOSUB compute.triplet.sig.components
  1995.                 ' Classify the scheme of triangle overlap and assign a 3-digit code.
  1996.                 signature1 = pointDinside + pointEinside + pointFinside
  1997.                 signature2 = pointAinside + pointBinside + pointCinside
  1998.                 signature3 = intABDE + intBCDE + intCADE + intABEF + intBCEF + intCAEF + intABFD + intBCFD + intCAFD
  1999.                 signature1text$ = STR$(signature1)
  2000.                 signature2text$ = STR$(signature2)
  2001.                 signature3text$ = STR$(signature3)
  2002.                 signaturefull$ = signature1text$ + signature2text$ + signature3text$
  2003.                 GOSUB triplet.image.generate
  2004.             END IF
  2005.         NEXT
  2006.     NEXT
  2007.     bypasssniploop:
  2008.     FOR m = 1 TO pcounttripletsnipimage
  2009.         snipworkpcount = snipworkpcount + 1
  2010.         tripletsnipwork(snipworkpcount, 1) = tripletsnipimage(m, 1)
  2011.         tripletsnipwork(snipworkpcount, 2) = tripletsnipimage(m, 2)
  2012.         tripletsnipwork(snipworkpcount, 3) = tripletsnipimage(m, 3)
  2013.         tripletsnipwork(snipworkpcount, 4) = tripletsnipimage(m, 4)
  2014.         tripletsnipwork(snipworkpcount, 5) = tripletsnipimage(m, 5)
  2015.         tripletsnipwork(snipworkpcount, 6) = tripletsnipimage(m, 6)
  2016.         tripletsnipwork(snipworkpcount, 7) = tripletsnipimage(m, 7)
  2017.         tripletsnipwork(snipworkpcount, 8) = tripletsnipimage(m, 8)
  2018.         tripletsnipwork(snipworkpcount, 9) = tripletsnipimage(m, 9)
  2019.         tripletsnipwork(snipworkpcount, 10) = tripletsnipimage(m, 10)
  2020.     NEXT
  2021. FOR i = 1 TO snipworkpcount
  2022.     tripletsnip(i, 1) = tripletsnipwork(i, 1)
  2023.     tripletsnip(i, 2) = tripletsnipwork(i, 2)
  2024.     tripletsnip(i, 3) = tripletsnipwork(i, 3)
  2025.     tripletsnip(i, 4) = tripletsnipwork(i, 4)
  2026.     tripletsnip(i, 5) = tripletsnipwork(i, 5)
  2027.     tripletsnip(i, 6) = tripletsnipwork(i, 6)
  2028.     tripletsnip(i, 7) = tripletsnipwork(i, 7)
  2029.     tripletsnip(i, 8) = tripletsnipwork(i, 8)
  2030.     tripletsnip(i, 9) = tripletsnipwork(i, 9)
  2031.     tripletsnip(i, 10) = tripletsnipwork(i, 10)
  2032.     ' Code for troubleshooting.
  2033.     'centsnipx = (1 / 3) * (tripletsnipwork(i, 1) + tripletsnipwork(i, 4) + tripletsnipwork(i, 7))
  2034.     'centsnipy = (1 / 3) * (tripletsnipwork(i, 2) + tripletsnipwork(i, 5) + tripletsnipwork(i, 8))
  2035.     'centsnipz = (1 / 3) * (tripletsnipwork(i, 3) + tripletsnipwork(i, 6) + tripletsnipwork(i, 9))
  2036.     'centmag = SQR((centsnipx) ^ 2 + (centsnipy) ^ 2 + (centsnipz) ^ 2)
  2037. numtripletsnip = snipworkpcount
  2038.  
  2039. compute.triplet.sig.components:
  2040. ' Begin calculations for enclosed points: DEF inside ABC.
  2041.  
  2042. pointDinside = -1
  2043. pointEinside = -1
  2044. pointFinside = -1
  2045. pcounttripletencpoint = 0
  2046.  
  2047. tan12uv = (Asv - Bsv) / (Asu - Bsu)
  2048. norm12u = -(Asv - Bsv)
  2049. norm12v = (Asu - Bsu)
  2050. mag = SQR(norm12u ^ 2 + norm12v ^ 2)
  2051. norm12u = norm12u / mag
  2052. norm12v = norm12v / mag
  2053. Asdotnorm12 = Asu * norm12u + Asv * norm12v
  2054. Bsdotnorm12 = Bsu * norm12u + Bsv * norm12v
  2055. Dsdotnorm12 = Dsu * norm12u + Dsv * norm12v
  2056. Esdotnorm12 = Esu * norm12u + Esv * norm12v
  2057. Fsdotnorm12 = Fsu * norm12u + Fsv * norm12v
  2058.  
  2059. tan23uv = (Bsv - Csv) / (Bsu - Csu)
  2060. norm23u = -(Bsv - Csv)
  2061. norm23v = (Bsu - Csu)
  2062. mag = SQR(norm23u ^ 2 + norm23v ^ 2)
  2063. norm23u = norm23u / mag
  2064. norm23v = norm23v / mag
  2065. Bsdotnorm23 = Bsu * norm23u + Bsv * norm23v
  2066. Csdotnorm23 = Csu * norm23u + Csv * norm23v
  2067. Dsdotnorm23 = Dsu * norm23u + Dsv * norm23v
  2068. Esdotnorm23 = Esu * norm23u + Esv * norm23v
  2069. Fsdotnorm23 = Fsu * norm23u + Fsv * norm23v
  2070.  
  2071. tan31uv = (Csv - Asv) / (Csu - Asu)
  2072. norm31u = -(Csv - Asv)
  2073. norm31v = (Csu - Asu)
  2074. mag = SQR(norm31u ^ 2 + norm31v ^ 2)
  2075. norm31u = norm31u / mag
  2076. norm31v = norm31v / mag
  2077. Csdotnorm31 = Csu * norm31u + Csv * norm31v
  2078. Asdotnorm31 = Asu * norm31u + Asv * norm31v
  2079. Dsdotnorm31 = Dsu * norm31u + Dsv * norm31v
  2080. Esdotnorm31 = Esu * norm31u + Esv * norm31v
  2081. Fsdotnorm31 = Fsu * norm31u + Fsv * norm31v
  2082.  
  2083. pointDdist12 = Dsdotnorm12 - (1 / 2) * (Asdotnorm12 + Bsdotnorm12)
  2084. pointDdist23 = Dsdotnorm23 - (1 / 2) * (Bsdotnorm23 + Csdotnorm23)
  2085. pointDdist31 = Dsdotnorm31 - (1 / 2) * (Csdotnorm31 + Asdotnorm31)
  2086.  
  2087. pointEdist12 = Esdotnorm12 - (1 / 2) * (Asdotnorm12 + Bsdotnorm12)
  2088. pointEdist23 = Esdotnorm23 - (1 / 2) * (Bsdotnorm23 + Csdotnorm23)
  2089. pointEdist31 = Esdotnorm31 - (1 / 2) * (Csdotnorm31 + Asdotnorm31)
  2090.  
  2091. pointFdist12 = Fsdotnorm12 - (1 / 2) * (Asdotnorm12 + Bsdotnorm12)
  2092. pointFdist23 = Fsdotnorm23 - (1 / 2) * (Bsdotnorm23 + Csdotnorm23)
  2093. pointFdist31 = Fsdotnorm31 - (1 / 2) * (Csdotnorm31 + Asdotnorm31)
  2094.  
  2095. IF pointDdist12 > 0 AND pointDdist23 > 0 AND pointDdist31 > 0 THEN
  2096.     pointDinside = 1
  2097.     Q = Dsu / fovd
  2098.     R = Q * (Bn - An) - (Bu - Au)
  2099.     S = Q * (Cn - An) - (Cu - Au)
  2100.     T = Au - Q * An
  2101.     Z = Dsv / fovd
  2102.     U = Z * (Bn - An) - (Bv - Av)
  2103.     V = Z * (Cn - An) - (Cv - Av)
  2104.     W = Av - Z * An
  2105.     factor1 = (T / S - W / V) / (R / S - U / V)
  2106.     factor2 = (T / R - W / U) / (S / R - V / U)
  2107.     pcounttripletencpoint = pcounttripletencpoint + 1
  2108.     tripletencpoint(pcounttripletencpoint, 1) = Dx
  2109.     tripletencpoint(pcounttripletencpoint, 2) = Dy
  2110.     tripletencpoint(pcounttripletencpoint, 3) = Dz
  2111.     tripletencpoint(pcounttripletencpoint, 4) = Ax + factor1 * (Bx - Ax) + factor2 * (Cx - Ax)
  2112.     tripletencpoint(pcounttripletencpoint, 5) = Ay + factor1 * (By - Ay) + factor2 * (Cy - Ay)
  2113.     tripletencpoint(pcounttripletencpoint, 6) = Az + factor1 * (Bz - Az) + factor2 * (Cz - Az)
  2114.     tripletencpoint(pcounttripletencpoint, 7) = Dsu
  2115.     tripletencpoint(pcounttripletencpoint, 8) = Dsv
  2116.     pointDinside = 0
  2117.  
  2118. IF pointEdist12 > 0 AND pointEdist23 > 0 AND pointEdist31 > 0 THEN
  2119.     pointEinside = 1
  2120.     Q = Esu / fovd
  2121.     R = Q * (Bn - An) - (Bu - Au)
  2122.     S = Q * (Cn - An) - (Cu - Au)
  2123.     T = Au - Q * An
  2124.     Z = Esv / fovd
  2125.     U = Z * (Bn - An) - (Bv - Av)
  2126.     V = Z * (Cn - An) - (Cv - Av)
  2127.     W = Av - Z * An
  2128.     factor1 = (T / S - W / V) / (R / S - U / V)
  2129.     factor2 = (T / R - W / U) / (S / R - V / U)
  2130.     pcounttripletencpoint = pcounttripletencpoint + 1
  2131.     tripletencpoint(pcounttripletencpoint, 1) = Ex
  2132.     tripletencpoint(pcounttripletencpoint, 2) = Ey
  2133.     tripletencpoint(pcounttripletencpoint, 3) = Ez
  2134.     tripletencpoint(pcounttripletencpoint, 4) = Ax + factor1 * (Bx - Ax) + factor2 * (Cx - Ax)
  2135.     tripletencpoint(pcounttripletencpoint, 5) = Ay + factor1 * (By - Ay) + factor2 * (Cy - Ay)
  2136.     tripletencpoint(pcounttripletencpoint, 6) = Az + factor1 * (Bz - Az) + factor2 * (Cz - Az)
  2137.     tripletencpoint(pcounttripletencpoint, 7) = Esu
  2138.     tripletencpoint(pcounttripletencpoint, 8) = Esv
  2139.     pointEinside = 0
  2140.  
  2141. IF pointFdist12 > 0 AND pointFdist23 > 0 AND pointFdist31 > 0 THEN
  2142.     pointFinside = 1
  2143.     Q = Fsu / fovd
  2144.     R = Q * (Bn - An) - (Bu - Au)
  2145.     S = Q * (Cn - An) - (Cu - Au)
  2146.     T = Au - Q * An
  2147.     Z = Fsv / fovd
  2148.     U = Z * (Bn - An) - (Bv - Av)
  2149.     V = Z * (Cn - An) - (Cv - Av)
  2150.     W = Av - Z * An
  2151.     factor1 = (T / S - W / V) / (R / S - U / V)
  2152.     factor2 = (T / R - W / U) / (S / R - V / U)
  2153.     pcounttripletencpoint = pcounttripletencpoint + 1
  2154.     tripletencpoint(pcounttripletencpoint, 1) = Fx
  2155.     tripletencpoint(pcounttripletencpoint, 2) = Fy
  2156.     tripletencpoint(pcounttripletencpoint, 3) = Fz
  2157.     tripletencpoint(pcounttripletencpoint, 4) = Ax + factor1 * (Bx - Ax) + factor2 * (Cx - Ax)
  2158.     tripletencpoint(pcounttripletencpoint, 5) = Ay + factor1 * (By - Ay) + factor2 * (Cy - Ay)
  2159.     tripletencpoint(pcounttripletencpoint, 6) = Az + factor1 * (Bz - Az) + factor2 * (Cz - Az)
  2160.     tripletencpoint(pcounttripletencpoint, 7) = Fsu
  2161.     tripletencpoint(pcounttripletencpoint, 8) = Fsv
  2162.     pointFinside = 0
  2163.  
  2164. ' Begin calculations for enclosed points: ABC inside DEF.
  2165.  
  2166. pointAinside = -1
  2167. pointBinside = -1
  2168. pointCinside = -1
  2169.  
  2170. tan12uv = (Dsv - Esv) / (Dsu - Esu)
  2171. norm12u = -(Dsv - Esv)
  2172. norm12v = (Dsu - Esu)
  2173. mag = SQR(norm12u ^ 2 + norm12v ^ 2)
  2174. norm12u = norm12u / mag
  2175. norm12v = norm12v / mag
  2176. Dsdotnorm12 = Dsu * norm12u + Dsv * norm12v
  2177. Esdotnorm12 = Esu * norm12u + Esv * norm12v
  2178. Asdotnorm12 = Asu * norm12u + Asv * norm12v
  2179. Bsdotnorm12 = Bsu * norm12u + Bsv * norm12v
  2180. Csdotnorm12 = Csu * norm12u + Csv * norm12v
  2181.  
  2182. tan23uv = (Esv - Fsv) / (Esu - Fsu)
  2183. norm23u = -(Esv - Fsv)
  2184. norm23v = (Esu - Fsu)
  2185. mag = SQR(norm23u ^ 2 + norm23v ^ 2)
  2186. norm23u = norm23u / mag
  2187. norm23v = norm23v / mag
  2188. Esdotnorm23 = Esu * norm23u + Esv * norm23v
  2189. Fsdotnorm23 = Fsu * norm23u + Fsv * norm23v
  2190. Asdotnorm23 = Asu * norm23u + Asv * norm23v
  2191. Bsdotnorm23 = Bsu * norm23u + Bsv * norm23v
  2192. Csdotnorm23 = Csu * norm23u + Csv * norm23v
  2193.  
  2194. tan31uv = (Fsv - Dsv) / (Fsu - Dsu)
  2195. norm31u = -(Fsv - Dsv)
  2196. norm31v = (Fsu - Dsu)
  2197. mag = SQR(norm31u ^ 2 + norm31v ^ 2)
  2198. norm31u = norm31u / mag
  2199. norm31v = norm31v / mag
  2200. Fsdotnorm31 = Fsu * norm31u + Fsv * norm31v
  2201. Dsdotnorm31 = Dsu * norm31u + Dsv * norm31v
  2202. Asdotnorm31 = Asu * norm31u + Asv * norm31v
  2203. Bsdotnorm31 = Bsu * norm31u + Bsv * norm31v
  2204. Csdotnorm31 = Csu * norm31u + Csv * norm31v
  2205.  
  2206. pointAdist12 = Asdotnorm12 - (1 / 2) * (Dsdotnorm12 + Esdotnorm12)
  2207. pointAdist23 = Asdotnorm23 - (1 / 2) * (Esdotnorm23 + Fsdotnorm23)
  2208. pointAdist31 = Asdotnorm31 - (1 / 2) * (Fsdotnorm31 + Dsdotnorm31)
  2209.  
  2210. pointBdist12 = Bsdotnorm12 - (1 / 2) * (Dsdotnorm12 + Esdotnorm12)
  2211. pointBdist23 = Bsdotnorm23 - (1 / 2) * (Esdotnorm23 + Fsdotnorm23)
  2212. pointBdist31 = Bsdotnorm31 - (1 / 2) * (Fsdotnorm31 + Dsdotnorm31)
  2213.  
  2214. pointCdist12 = Csdotnorm12 - (1 / 2) * (Dsdotnorm12 + Esdotnorm12)
  2215. pointCdist23 = Csdotnorm23 - (1 / 2) * (Esdotnorm23 + Fsdotnorm23)
  2216. pointCdist31 = Csdotnorm31 - (1 / 2) * (Fsdotnorm31 + Dsdotnorm31)
  2217.  
  2218. IF pointAdist12 > 0 AND pointAdist23 > 0 AND pointAdist31 > 0 THEN
  2219.     pointAinside = 1
  2220.     Q = Asu / fovd
  2221.     R = Q * (En - Dn) - (Eu - Du)
  2222.     S = Q * (Fn - Dn) - (Fu - Du)
  2223.     T = Du - Q * Dn
  2224.     Z = Asv / fovd
  2225.     U = Z * (En - Dn) - (Ev - Dv)
  2226.     V = Z * (Fn - Dn) - (Fv - Dv)
  2227.     W = Dv - Z * Dn
  2228.     factor1 = (T / S - W / V) / (R / S - U / V)
  2229.     factor2 = (T / R - W / U) / (S / R - V / U)
  2230.     pcounttripletencpoint = pcounttripletencpoint + 1
  2231.     tripletencpoint(pcounttripletencpoint, 1) = Ax
  2232.     tripletencpoint(pcounttripletencpoint, 2) = Ay
  2233.     tripletencpoint(pcounttripletencpoint, 3) = Az
  2234.     tripletencpoint(pcounttripletencpoint, 4) = Dx + factor1 * (Ex - Dx) + factor2 * (Fx - Dx)
  2235.     tripletencpoint(pcounttripletencpoint, 5) = Dy + factor1 * (Ey - Dy) + factor2 * (Fy - Dy)
  2236.     tripletencpoint(pcounttripletencpoint, 6) = Dz + factor1 * (Ez - Dz) + factor2 * (Fz - Dz)
  2237.     tripletencpoint(pcounttripletencpoint, 7) = Asu
  2238.     tripletencpoint(pcounttripletencpoint, 8) = Asv
  2239.     pointAinside = 0
  2240.  
  2241. IF pointBdist12 > 0 AND pointBdist23 > 0 AND pointBdist31 > 0 THEN
  2242.     pointBinside = 1
  2243.     Q = Bsu / fovd
  2244.     R = Q * (En - Dn) - (Eu - Du)
  2245.     S = Q * (Fn - Dn) - (Fu - Du)
  2246.     T = Du - Q * Dn
  2247.     Z = Bsv / fovd
  2248.     U = Z * (En - Dn) - (Ev - Dv)
  2249.     V = Z * (Fn - Dn) - (Fv - Dv)
  2250.     W = Dv - Z * Dn
  2251.     factor1 = (T / S - W / V) / (R / S - U / V)
  2252.     factor2 = (T / R - W / U) / (S / R - V / U)
  2253.     pcounttripletencpoint = pcounttripletencpoint + 1
  2254.     tripletencpoint(pcounttripletencpoint, 1) = Bx
  2255.     tripletencpoint(pcounttripletencpoint, 2) = By
  2256.     tripletencpoint(pcounttripletencpoint, 3) = Bz
  2257.     tripletencpoint(pcounttripletencpoint, 4) = Dx + factor1 * (Ex - Dx) + factor2 * (Fx - Dx)
  2258.     tripletencpoint(pcounttripletencpoint, 5) = Dy + factor1 * (Ey - Dy) + factor2 * (Fy - Dy)
  2259.     tripletencpoint(pcounttripletencpoint, 6) = Dz + factor1 * (Ez - Dz) + factor2 * (Fz - Dz)
  2260.     tripletencpoint(pcounttripletencpoint, 7) = Bsu
  2261.     tripletencpoint(pcounttripletencpoint, 8) = Bsv
  2262.     pointBinside = 0
  2263.  
  2264. IF pointCdist12 > 0 AND pointCdist23 > 0 AND pointCdist31 > 0 THEN
  2265.     pointCinside = 1
  2266.     Q = Csu / fovd
  2267.     R = Q * (En - Dn) - (Eu - Du)
  2268.     S = Q * (Fn - Dn) - (Fu - Du)
  2269.     T = Du - Q * Dn
  2270.     Z = Csv / fovd
  2271.     U = Z * (En - Dn) - (Ev - Dv)
  2272.     V = Z * (Fn - Dn) - (Fv - Dv)
  2273.     W = Dv - Z * Dn
  2274.     factor1 = (T / S - W / V) / (R / S - U / V)
  2275.     factor2 = (T / R - W / U) / (S / R - V / U)
  2276.     pcounttripletencpoint = pcounttripletencpoint + 1
  2277.     tripletencpoint(pcounttripletencpoint, 1) = Cx
  2278.     tripletencpoint(pcounttripletencpoint, 2) = Cy
  2279.     tripletencpoint(pcounttripletencpoint, 3) = Cz
  2280.     tripletencpoint(pcounttripletencpoint, 4) = Dx + factor1 * (Ex - Dx) + factor2 * (Fx - Dx)
  2281.     tripletencpoint(pcounttripletencpoint, 5) = Dy + factor1 * (Ey - Dy) + factor2 * (Fy - Dy)
  2282.     tripletencpoint(pcounttripletencpoint, 6) = Dz + factor1 * (Ez - Dz) + factor2 * (Fz - Dz)
  2283.     tripletencpoint(pcounttripletencpoint, 7) = Csu
  2284.     tripletencpoint(pcounttripletencpoint, 8) = Csv
  2285.     pointCinside = 0
  2286.  
  2287. ' Begin calculations for triplet line intersections.
  2288.  
  2289. magtripletABps = SQR((Asu - Bsu) ^ 2 + (Asv - Bsv) ^ 2)
  2290. magtripletBCps = SQR((Bsu - Csu) ^ 2 + (Bsv - Csv) ^ 2)
  2291. magtripletCAps = SQR((Csu - Asu) ^ 2 + (Csv - Asv) ^ 2)
  2292.  
  2293. magtripletDEps = SQR((Dsu - Esu) ^ 2 + (Dsv - Esv) ^ 2)
  2294. magtripletEFps = SQR((Esu - Fsu) ^ 2 + (Esv - Fsv) ^ 2)
  2295. magtripletFDps = SQR((Fsu - Dsu) ^ 2 + (Fsv - Dsv) ^ 2)
  2296.  
  2297. slopeAB = (Bsv - Asv) / (Bsu - Asu)
  2298. intAB = Asv - slopeAB * Asu
  2299. slopeBC = (Csv - Bsv) / (Csu - Bsu)
  2300. intBC = Bsv - slopeBC * Bsu
  2301. slopeCA = (Asv - Csv) / (Asu - Csu)
  2302. intCA = Csv - slopeCA * Csu
  2303.  
  2304. slopeDE = (Esv - Dsv) / (Esu - Dsu)
  2305. intDE = Dsv - slopeDE * Dsu
  2306. slopeEF = (Fsv - Esv) / (Fsu - Esu)
  2307. intEF = Esv - slopeEF * Esu
  2308. slopeFD = (Dsv - Fsv) / (Dsu - Fsu)
  2309. intFD = Fsv - slopeFD * Fsu
  2310.  
  2311. xstarABDE = -(intAB - intDE) / (slopeAB - slopeDE)
  2312. ystarABDE = slopeAB * xstarABDE + intAB
  2313. xstarABEF = -(intAB - intEF) / (slopeAB - slopeEF)
  2314. ystarABEF = slopeAB * xstarABEF + intAB
  2315. xstarABFD = -(intAB - intFD) / (slopeAB - slopeFD)
  2316. ystarABFD = slopeAB * xstarABFD + intAB
  2317.  
  2318. xstarBCDE = -(intBC - intDE) / (slopeBC - slopeDE)
  2319. ystarBCDE = slopeBC * xstarBCDE + intBC
  2320. xstarBCEF = -(intBC - intEF) / (slopeBC - slopeEF)
  2321. ystarBCEF = slopeBC * xstarBCEF + intBC
  2322. xstarBCFD = -(intBC - intFD) / (slopeBC - slopeFD)
  2323. ystarBCFD = slopeBC * xstarBCFD + intBC
  2324.  
  2325. xstarCADE = -(intCA - intDE) / (slopeCA - slopeDE)
  2326. ystarCADE = slopeCA * xstarCADE + intCA
  2327. xstarCAEF = -(intCA - intEF) / (slopeCA - slopeEF)
  2328. ystarCAEF = slopeCA * xstarCAEF + intCA
  2329. xstarCAFD = -(intCA - intFD) / (slopeCA - slopeFD)
  2330. ystarCAFD = slopeCA * xstarCAFD + intCA
  2331.  
  2332. alphaABDE1u = -xstarABDE + Asu
  2333. alphaABDE1v = -ystarABDE + Asv
  2334. alphaABDE2u = -xstarABDE + Bsu
  2335. alphaABDE2v = -ystarABDE + Bsv
  2336. alphaABEF1u = -xstarABEF + Asu
  2337. alphaABEF1v = -ystarABEF + Asv
  2338. alphaABEF2u = -xstarABEF + Bsu
  2339. alphaABEF2v = -ystarABEF + Bsv
  2340. alphaABFD1u = -xstarABFD + Asu
  2341. alphaABFD1v = -ystarABFD + Asv
  2342. alphaABFD2u = -xstarABFD + Bsu
  2343. alphaABFD2v = -ystarABFD + Bsv
  2344.  
  2345. alphaBCDE1u = -xstarBCDE + Bsu
  2346. alphaBCDE1v = -ystarBCDE + Bsv
  2347. alphaBCDE2u = -xstarBCDE + Csu
  2348. alphaBCDE2v = -ystarBCDE + Csv
  2349. alphaBCEF1u = -xstarBCEF + Bsu
  2350. alphaBCEF1v = -ystarBCEF + Bsv
  2351. alphaBCEF2u = -xstarBCEF + Csu
  2352. alphaBCEF2v = -ystarBCEF + Csv
  2353. alphaBCFD1u = -xstarBCFD + Bsu
  2354. alphaBCFD1v = -ystarBCFD + Bsv
  2355. alphaBCFD2u = -xstarBCFD + Csu
  2356. alphaBCFD2v = -ystarBCFD + Csv
  2357.  
  2358. alphaCADE1u = -xstarCADE + Csu
  2359. alphaCADE1v = -ystarCADE + Csv
  2360. alphaCADE2u = -xstarCADE + Asu
  2361. alphaCADE2v = -ystarCADE + Asv
  2362. alphaCAEF1u = -xstarCAEF + Csu
  2363. alphaCAEF1v = -ystarCAEF + Csv
  2364. alphaCAEF2u = -xstarCAEF + Asu
  2365. alphaCAEF2v = -ystarCAEF + Asv
  2366. alphaCAFD1u = -xstarCAFD + Csu
  2367. alphaCAFD1v = -ystarCAFD + Csv
  2368. alphaCAFD2u = -xstarCAFD + Asu
  2369. alphaCAFD2v = -ystarCAFD + Asv
  2370.  
  2371. alphaDEAB1u = -xstarABDE + Dsu
  2372. alphaDEAB1v = -ystarABDE + Dsv
  2373. alphaDEAB2u = -xstarABDE + Esu
  2374. alphaDEAB2v = -ystarABDE + Esv
  2375. alphaDEBC1u = -xstarBCDE + Dsu
  2376. alphaDEBC1v = -ystarBCDE + Dsv
  2377. alphaDEBC2u = -xstarBCDE + Esu
  2378. alphaDEBC2v = -ystarBCDE + Esv
  2379. alphaDECA1u = -xstarCADE + Dsu
  2380. alphaDECA1v = -ystarCADE + Dsv
  2381. alphaDECA2u = -xstarCADE + Esu
  2382. alphaDECA2v = -ystarCADE + Esv
  2383.  
  2384. alphaEFAB1u = -xstarABEF + Esu
  2385. alphaEFAB1v = -ystarABEF + Esv
  2386. alphaEFAB2u = -xstarABEF + Fsu
  2387. alphaEFAB2v = -ystarABEF + Fsv
  2388. alphaEFBC1u = -xstarBCEF + Esu
  2389. alphaEFBC1v = -ystarBCEF + Esv
  2390. alphaEFBC2u = -xstarBCEF + Fsu
  2391. alphaEFBC2v = -ystarBCEF + Fsv
  2392. alphaEFCA1u = -xstarCAEF + Esu
  2393. alphaEFCA1v = -ystarCAEF + Esv
  2394. alphaEFCA2u = -xstarCAEF + Fsu
  2395. alphaEFCA2v = -ystarCAEF + Fsv
  2396.  
  2397. alphaFDAB1u = -xstarABFD + Fsu
  2398. alphaFDAB1v = -ystarABFD + Fsv
  2399. alphaFDAB2u = -xstarABFD + Dsu
  2400. alphaFDAB2v = -ystarABFD + Dsv
  2401. alphaFDBC1u = -xstarBCFD + Fsu
  2402. alphaFDBC1v = -ystarBCFD + Fsv
  2403. alphaFDBC2u = -xstarBCFD + Dsu
  2404. alphaFDBC2v = -ystarBCFD + Dsv
  2405. alphaFDCA1u = -xstarCAFD + Fsu
  2406. alphaFDCA1v = -ystarCAFD + Fsv
  2407. alphaFDCA2u = -xstarCAFD + Dsu
  2408. alphaFDCA2v = -ystarCAFD + Dsv
  2409.  
  2410. magalphaABDE1 = SQR(alphaABDE1u ^ 2 + alphaABDE1v ^ 2)
  2411. magalphaABDE2 = SQR(alphaABDE2u ^ 2 + alphaABDE2v ^ 2)
  2412. magalphaABEF1 = SQR(alphaABEF1u ^ 2 + alphaABEF1v ^ 2)
  2413. magalphaABEF2 = SQR(alphaABEF2u ^ 2 + alphaABEF2v ^ 2)
  2414. magalphaABFD1 = SQR(alphaABFD1u ^ 2 + alphaABFD1v ^ 2)
  2415. magalphaABFD2 = SQR(alphaABFD2u ^ 2 + alphaABFD2v ^ 2)
  2416.  
  2417. magalphaBCDE1 = SQR(alphaBCDE1u ^ 2 + alphaBCDE1v ^ 2)
  2418. magalphaBCDE2 = SQR(alphaBCDE2u ^ 2 + alphaBCDE2v ^ 2)
  2419. magalphaBCEF1 = SQR(alphaBCEF1u ^ 2 + alphaBCEF1v ^ 2)
  2420. magalphaBCEF2 = SQR(alphaBCEF2u ^ 2 + alphaBCEF2v ^ 2)
  2421. magalphaBCFD1 = SQR(alphaBCFD1u ^ 2 + alphaBCFD1v ^ 2)
  2422. magalphaBCFD2 = SQR(alphaBCFD2u ^ 2 + alphaBCFD2v ^ 2)
  2423.  
  2424. magalphaCADE1 = SQR(alphaCADE1u ^ 2 + alphaCADE1v ^ 2)
  2425. magalphaCADE2 = SQR(alphaCADE2u ^ 2 + alphaCADE2v ^ 2)
  2426. magalphaCAEF1 = SQR(alphaCAEF1u ^ 2 + alphaCAEF1v ^ 2)
  2427. magalphaCAEF2 = SQR(alphaCAEF2u ^ 2 + alphaCAEF2v ^ 2)
  2428. magalphaCAFD1 = SQR(alphaCAFD1u ^ 2 + alphaCAFD1v ^ 2)
  2429. magalphaCAFD2 = SQR(alphaCAFD2u ^ 2 + alphaCAFD2v ^ 2)
  2430.  
  2431. magalphaDEAB1 = SQR(alphaDEAB1u ^ 2 + alphaDEAB1v ^ 2)
  2432. magalphaDEAB2 = SQR(alphaDEAB2u ^ 2 + alphaDEAB2v ^ 2)
  2433. magalphaDEBC1 = SQR(alphaDEBC1u ^ 2 + alphaDEBC1v ^ 2)
  2434. magalphaDEBC2 = SQR(alphaDEBC2u ^ 2 + alphaDEBC2v ^ 2)
  2435. magalphaDECA1 = SQR(alphaDECA1u ^ 2 + alphaDECA1v ^ 2)
  2436. magalphaDECA2 = SQR(alphaDECA2u ^ 2 + alphaDECA2v ^ 2)
  2437.  
  2438. magalphaEFAB1 = SQR(alphaEFAB1u ^ 2 + alphaEFAB1v ^ 2)
  2439. magalphaEFAB2 = SQR(alphaEFAB2u ^ 2 + alphaEFAB2v ^ 2)
  2440. magalphaEFBC1 = SQR(alphaEFBC1u ^ 2 + alphaEFBC1v ^ 2)
  2441. magalphaEFBC2 = SQR(alphaEFBC2u ^ 2 + alphaEFBC2v ^ 2)
  2442. magalphaEFCA1 = SQR(alphaEFCA1u ^ 2 + alphaEFCA1v ^ 2)
  2443. magalphaEFCA2 = SQR(alphaEFCA2u ^ 2 + alphaEFCA2v ^ 2)
  2444.  
  2445. magalphaFDAB1 = SQR(alphaFDAB1u ^ 2 + alphaFDAB1v ^ 2)
  2446. magalphaFDAB2 = SQR(alphaFDAB2u ^ 2 + alphaFDAB2v ^ 2)
  2447. magalphaFDBC1 = SQR(alphaFDBC1u ^ 2 + alphaFDBC1v ^ 2)
  2448. magalphaFDBC2 = SQR(alphaFDBC2u ^ 2 + alphaFDBC2v ^ 2)
  2449. magalphaFDCA1 = SQR(alphaFDCA1u ^ 2 + alphaFDCA1v ^ 2)
  2450. magalphaFDCA2 = SQR(alphaFDCA2u ^ 2 + alphaFDCA2v ^ 2)
  2451.  
  2452. ' Determine and store the mutual intersection points of triplets ABD and DEF.
  2453.  
  2454. intABDE = -1
  2455. intBCDE = -1
  2456. intCADE = -1
  2457. intABEF = -1
  2458. intBCEF = -1
  2459. intCAEF = -1
  2460. intABFD = -1
  2461. intBCFD = -1
  2462. intCAFD = -1
  2463. pcounttripletintpointpair = 0
  2464.  
  2465. IF magalphaABDE1 - magtripletABps < 0 AND magalphaABDE2 - magtripletABps < 0 AND magalphaDEAB1 - magtripletDEps < 0 AND magalphaDEAB2 - magtripletDEps < 0 THEN
  2466.     qAB1u = (Asu - alphaABDE1u) / fovd
  2467.     numerator = qAB1u * An - Au
  2468.     denominator = Bu - Au + qAB1u * (An - Bn)
  2469.     betaABDE = numerator / denominator
  2470.     qDE1u = (Dsu - alphaDEAB1u) / fovd
  2471.     numerator = qDE1u * Dn - Du
  2472.     denominator = Eu - Du + qDE1u * (Dn - En)
  2473.     betaDEAB = numerator / denominator
  2474.     intABDE = 1
  2475.     pcounttripletintpointpair = pcounttripletintpointpair + 1
  2476.     tripletintpointpair(pcounttripletintpointpair, 1) = Ax * (1 - betaABDE) + betaABDE * Bx
  2477.     tripletintpointpair(pcounttripletintpointpair, 2) = Ay * (1 - betaABDE) + betaABDE * By
  2478.     tripletintpointpair(pcounttripletintpointpair, 3) = Az * (1 - betaABDE) + betaABDE * Bz
  2479.     tripletintpointpair(pcounttripletintpointpair, 4) = Dx * (1 - betaDEAB) + betaDEAB * Ex
  2480.     tripletintpointpair(pcounttripletintpointpair, 5) = Dy * (1 - betaDEAB) + betaDEAB * Ey
  2481.     tripletintpointpair(pcounttripletintpointpair, 6) = Dz * (1 - betaDEAB) + betaDEAB * Ez
  2482.     tripletintpointpair(pcounttripletintpointpair, 7) = Cx
  2483.     tripletintpointpair(pcounttripletintpointpair, 8) = Cy
  2484.     tripletintpointpair(pcounttripletintpointpair, 9) = Cz
  2485.     tripletintpointpair(pcounttripletintpointpair, 10) = Ax
  2486.     tripletintpointpair(pcounttripletintpointpair, 11) = Ay
  2487.     tripletintpointpair(pcounttripletintpointpair, 12) = Az
  2488.     tripletintpointpair(pcounttripletintpointpair, 13) = Bx
  2489.     tripletintpointpair(pcounttripletintpointpair, 14) = By
  2490.     tripletintpointpair(pcounttripletintpointpair, 15) = Bz
  2491.     tripletintpointpair(pcounttripletintpointpair, 16) = Dx
  2492.     tripletintpointpair(pcounttripletintpointpair, 17) = Dy
  2493.     tripletintpointpair(pcounttripletintpointpair, 18) = Dz
  2494.     tripletintpointpair(pcounttripletintpointpair, 19) = Ex
  2495.     tripletintpointpair(pcounttripletintpointpair, 20) = Ey
  2496.     tripletintpointpair(pcounttripletintpointpair, 21) = Ez
  2497.     intABDE = 0
  2498.  
  2499. IF magalphaBCDE1 - magtripletBCps < 0 AND magalphaBCDE2 - magtripletBCps < 0 AND magalphaDEBC1 - magtripletDEps < 0 AND magalphaDEBC2 - magtripletDEps < 0 THEN
  2500.     qBC1u = (Bsu - alphaBCDE1u) / fovd
  2501.     numerator = qBC1u * Bn - Bu
  2502.     denominator = Cu - Bu + qBC1u * (Bn - Cn)
  2503.     betaBCDE = numerator / denominator
  2504.     qDE1u = (Dsu - alphaDEBC1u) / fovd
  2505.     numerator = qDE1u * Dn - Du
  2506.     denominator = Eu - Du + qDE1u * (Dn - En)
  2507.     betaDEBC = numerator / denominator
  2508.     intBCDE = 1
  2509.     pcounttripletintpointpair = pcounttripletintpointpair + 1
  2510.     tripletintpointpair(pcounttripletintpointpair, 1) = Bx * (1 - betaBCDE) + betaBCDE * Cx
  2511.     tripletintpointpair(pcounttripletintpointpair, 2) = By * (1 - betaBCDE) + betaBCDE * Cy
  2512.     tripletintpointpair(pcounttripletintpointpair, 3) = Bz * (1 - betaBCDE) + betaBCDE * Cz
  2513.     tripletintpointpair(pcounttripletintpointpair, 4) = Dx * (1 - betaDEBC) + betaDEBC * Ex
  2514.     tripletintpointpair(pcounttripletintpointpair, 5) = Dy * (1 - betaDEBC) + betaDEBC * Ey
  2515.     tripletintpointpair(pcounttripletintpointpair, 6) = Dz * (1 - betaDEBC) + betaDEBC * Ez
  2516.     tripletintpointpair(pcounttripletintpointpair, 7) = Ax
  2517.     tripletintpointpair(pcounttripletintpointpair, 8) = Ay
  2518.     tripletintpointpair(pcounttripletintpointpair, 9) = Az
  2519.     tripletintpointpair(pcounttripletintpointpair, 10) = Bx
  2520.     tripletintpointpair(pcounttripletintpointpair, 11) = By
  2521.     tripletintpointpair(pcounttripletintpointpair, 12) = Bz
  2522.     tripletintpointpair(pcounttripletintpointpair, 13) = Cx
  2523.     tripletintpointpair(pcounttripletintpointpair, 14) = Cy
  2524.     tripletintpointpair(pcounttripletintpointpair, 15) = Cz
  2525.     tripletintpointpair(pcounttripletintpointpair, 16) = Dx
  2526.     tripletintpointpair(pcounttripletintpointpair, 17) = Dy
  2527.     tripletintpointpair(pcounttripletintpointpair, 18) = Dz
  2528.     tripletintpointpair(pcounttripletintpointpair, 19) = Ex
  2529.     tripletintpointpair(pcounttripletintpointpair, 20) = Ey
  2530.     tripletintpointpair(pcounttripletintpointpair, 21) = Ez
  2531.     intBCDE = 0
  2532.  
  2533. IF magalphaCADE1 - magtripletCAps < 0 AND magalphaCADE2 - magtripletCAps < 0 AND magalphaDECA1 - magtripletDEps < 0 AND magalphaDECA2 - magtripletDEps < 0 THEN
  2534.     qCA1u = (Csu - alphaCADE1u) / fovd
  2535.     numerator = qCA1u * Cn - Cu
  2536.     denominator = Au - Cu + qCA1u * (Cn - An)
  2537.     betaCADE = numerator / denominator
  2538.     qDE1u = (Dsu - alphaDECA1u) / fovd
  2539.     numerator = qDE1u * Dn - Du
  2540.     denominator = Eu - Du + qDE1u * (Dn - En)
  2541.     betaDECA = numerator / denominator
  2542.     intCADE = 1
  2543.     pcounttripletintpointpair = pcounttripletintpointpair + 1
  2544.     tripletintpointpair(pcounttripletintpointpair, 1) = Cx * (1 - betaCADE) + betaCADE * Ax
  2545.     tripletintpointpair(pcounttripletintpointpair, 2) = Cy * (1 - betaCADE) + betaCADE * Ay
  2546.     tripletintpointpair(pcounttripletintpointpair, 3) = Cz * (1 - betaCADE) + betaCADE * Az
  2547.     tripletintpointpair(pcounttripletintpointpair, 4) = Dx * (1 - betaDECA) + betaDECA * Ex
  2548.     tripletintpointpair(pcounttripletintpointpair, 5) = Dy * (1 - betaDECA) + betaDECA * Ey
  2549.     tripletintpointpair(pcounttripletintpointpair, 6) = Dz * (1 - betaDECA) + betaDECA * Ez
  2550.     tripletintpointpair(pcounttripletintpointpair, 7) = Bx
  2551.     tripletintpointpair(pcounttripletintpointpair, 8) = By
  2552.     tripletintpointpair(pcounttripletintpointpair, 9) = Bz
  2553.     tripletintpointpair(pcounttripletintpointpair, 10) = Cx
  2554.     tripletintpointpair(pcounttripletintpointpair, 11) = Cy
  2555.     tripletintpointpair(pcounttripletintpointpair, 12) = Cz
  2556.     tripletintpointpair(pcounttripletintpointpair, 13) = Ax
  2557.     tripletintpointpair(pcounttripletintpointpair, 14) = Ay
  2558.     tripletintpointpair(pcounttripletintpointpair, 15) = Az
  2559.     tripletintpointpair(pcounttripletintpointpair, 16) = Dx
  2560.     tripletintpointpair(pcounttripletintpointpair, 17) = Dy
  2561.     tripletintpointpair(pcounttripletintpointpair, 18) = Dz
  2562.     tripletintpointpair(pcounttripletintpointpair, 19) = Ex
  2563.     tripletintpointpair(pcounttripletintpointpair, 20) = Ey
  2564.     tripletintpointpair(pcounttripletintpointpair, 21) = Ez
  2565.     intCADE = 0
  2566.  
  2567. IF magalphaABEF1 - magtripletABps < 0 AND magalphaABEF2 - magtripletABps < 0 AND magalphaEFAB1 - magtripletEFps < 0 AND magalphaEFAB2 - magtripletEFps < 0 THEN
  2568.     qAB1u = (Asu - alphaABEF1u) / fovd
  2569.     numerator = qAB1u * An - Au
  2570.     denominator = Bu - Au + qAB1u * (An - Bn)
  2571.     betaABEF = numerator / denominator
  2572.     qEF1u = (Esu - alphaEFAB1u) / fovd
  2573.     numerator = qEF1u * En - Eu
  2574.     denominator = Fu - Eu + qEF1u * (En - Fn)
  2575.     betaEFAB = numerator / denominator
  2576.     intABEF = 1
  2577.     pcounttripletintpointpair = pcounttripletintpointpair + 1
  2578.     tripletintpointpair(pcounttripletintpointpair, 1) = Ax * (1 - betaABEF) + betaABEF * Bx
  2579.     tripletintpointpair(pcounttripletintpointpair, 2) = Ay * (1 - betaABEF) + betaABEF * By
  2580.     tripletintpointpair(pcounttripletintpointpair, 3) = Az * (1 - betaABEF) + betaABEF * Bz
  2581.     tripletintpointpair(pcounttripletintpointpair, 4) = Ex * (1 - betaEFAB) + betaEFAB * Fx
  2582.     tripletintpointpair(pcounttripletintpointpair, 5) = Ey * (1 - betaEFAB) + betaEFAB * Fy
  2583.     tripletintpointpair(pcounttripletintpointpair, 6) = Ez * (1 - betaEFAB) + betaEFAB * Fz
  2584.     tripletintpointpair(pcounttripletintpointpair, 7) = Cx
  2585.     tripletintpointpair(pcounttripletintpointpair, 8) = Cy
  2586.     tripletintpointpair(pcounttripletintpointpair, 9) = Cz
  2587.     tripletintpointpair(pcounttripletintpointpair, 10) = Ax
  2588.     tripletintpointpair(pcounttripletintpointpair, 11) = Ay
  2589.     tripletintpointpair(pcounttripletintpointpair, 12) = Az
  2590.     tripletintpointpair(pcounttripletintpointpair, 13) = Bx
  2591.     tripletintpointpair(pcounttripletintpointpair, 14) = By
  2592.     tripletintpointpair(pcounttripletintpointpair, 15) = Bz
  2593.     tripletintpointpair(pcounttripletintpointpair, 16) = Ex
  2594.     tripletintpointpair(pcounttripletintpointpair, 17) = Ey
  2595.     tripletintpointpair(pcounttripletintpointpair, 18) = Ez
  2596.     tripletintpointpair(pcounttripletintpointpair, 19) = Fx
  2597.     tripletintpointpair(pcounttripletintpointpair, 20) = Fy
  2598.     tripletintpointpair(pcounttripletintpointpair, 21) = Fz
  2599.     intABEF = 0
  2600.  
  2601. IF magalphaBCEF1 - magtripletBCps < 0 AND magalphaBCEF2 - magtripletBCps < 0 AND magalphaEFBC1 - magtripletEFps < 0 AND magalphaEFBC2 - magtripletEFps < 0 THEN
  2602.     qBC1u = (Bsu - alphaBCEF1u) / fovd
  2603.     numerator = qBC1u * Bn - Bu
  2604.     denominator = Cu - Bu + qBC1u * (Bn - Cn)
  2605.     betaBCEF = numerator / denominator
  2606.     qEF1u = (Esu - alphaEFBC1u) / fovd
  2607.     numerator = qEF1u * En - Eu
  2608.     denominator = Fu - Eu + qEF1u * (En - Fn)
  2609.     betaEFBC = numerator / denominator
  2610.     intBCEF = 1
  2611.     pcounttripletintpointpair = pcounttripletintpointpair + 1
  2612.     tripletintpointpair(pcounttripletintpointpair, 1) = Bx * (1 - betaBCEF) + betaBCEF * Cx
  2613.     tripletintpointpair(pcounttripletintpointpair, 2) = By * (1 - betaBCEF) + betaBCEF * Cy
  2614.     tripletintpointpair(pcounttripletintpointpair, 3) = Bz * (1 - betaBCEF) + betaBCEF * Cz
  2615.     tripletintpointpair(pcounttripletintpointpair, 4) = Ex * (1 - betaEFBC) + betaEFBC * Fx
  2616.     tripletintpointpair(pcounttripletintpointpair, 5) = Ey * (1 - betaEFBC) + betaEFBC * Fy
  2617.     tripletintpointpair(pcounttripletintpointpair, 6) = Ez * (1 - betaEFBC) + betaEFBC * Fz
  2618.     tripletintpointpair(pcounttripletintpointpair, 7) = Ax
  2619.     tripletintpointpair(pcounttripletintpointpair, 8) = Ay
  2620.     tripletintpointpair(pcounttripletintpointpair, 9) = Az
  2621.     tripletintpointpair(pcounttripletintpointpair, 10) = Bx
  2622.     tripletintpointpair(pcounttripletintpointpair, 11) = By
  2623.     tripletintpointpair(pcounttripletintpointpair, 12) = Bz
  2624.     tripletintpointpair(pcounttripletintpointpair, 13) = Cx
  2625.     tripletintpointpair(pcounttripletintpointpair, 14) = Cy
  2626.     tripletintpointpair(pcounttripletintpointpair, 15) = Cz
  2627.     tripletintpointpair(pcounttripletintpointpair, 16) = Ex
  2628.     tripletintpointpair(pcounttripletintpointpair, 17) = Ey
  2629.     tripletintpointpair(pcounttripletintpointpair, 18) = Ez
  2630.     tripletintpointpair(pcounttripletintpointpair, 19) = Fx
  2631.     tripletintpointpair(pcounttripletintpointpair, 20) = Fy
  2632.     tripletintpointpair(pcounttripletintpointpair, 21) = Fz
  2633.     intBCEF = 0
  2634.  
  2635. IF magalphaCAEF1 - magtripletCAps < 0 AND magalphaCAEF2 - magtripletCAps < 0 AND magalphaEFCA1 - magtripletEFps < 0 AND magalphaEFCA2 - magtripletEFps < 0 THEN
  2636.     qCA1u = (Csu - alphaCAEF1u) / fovd
  2637.     numerator = qCA1u * Cn - Cu
  2638.     denominator = Au - Cu + qCA1u * (Cn - An)
  2639.     betaCAEF = numerator / denominator
  2640.     qEF1u = (Esu - alphaEFCA1u) / fovd
  2641.     numerator = qEF1u * En - Eu
  2642.     denominator = Fu - Eu + qEF1u * (En - Fn)
  2643.     betaEFCA = numerator / denominator
  2644.     intCAEF = 1
  2645.     pcounttripletintpointpair = pcounttripletintpointpair + 1
  2646.     tripletintpointpair(pcounttripletintpointpair, 1) = Cx * (1 - betaCAEF) + betaCAEF * Ax
  2647.     tripletintpointpair(pcounttripletintpointpair, 2) = Cy * (1 - betaCAEF) + betaCAEF * Ay
  2648.     tripletintpointpair(pcounttripletintpointpair, 3) = Cz * (1 - betaCAEF) + betaCAEF * Az
  2649.     tripletintpointpair(pcounttripletintpointpair, 4) = Ex * (1 - betaEFCA) + betaEFCA * Fx
  2650.     tripletintpointpair(pcounttripletintpointpair, 5) = Ey * (1 - betaEFCA) + betaEFCA * Fy
  2651.     tripletintpointpair(pcounttripletintpointpair, 6) = Ez * (1 - betaEFCA) + betaEFCA * Fz
  2652.     tripletintpointpair(pcounttripletintpointpair, 7) = Bx
  2653.     tripletintpointpair(pcounttripletintpointpair, 8) = By
  2654.     tripletintpointpair(pcounttripletintpointpair, 9) = Bz
  2655.     tripletintpointpair(pcounttripletintpointpair, 10) = Cx
  2656.     tripletintpointpair(pcounttripletintpointpair, 11) = Cy
  2657.     tripletintpointpair(pcounttripletintpointpair, 12) = Cz
  2658.     tripletintpointpair(pcounttripletintpointpair, 13) = Ax
  2659.     tripletintpointpair(pcounttripletintpointpair, 14) = Ay
  2660.     tripletintpointpair(pcounttripletintpointpair, 15) = Az
  2661.     tripletintpointpair(pcounttripletintpointpair, 16) = Ex
  2662.     tripletintpointpair(pcounttripletintpointpair, 17) = Ey
  2663.     tripletintpointpair(pcounttripletintpointpair, 18) = Ez
  2664.     tripletintpointpair(pcounttripletintpointpair, 19) = Fx
  2665.     tripletintpointpair(pcounttripletintpointpair, 20) = Fy
  2666.     tripletintpointpair(pcounttripletintpointpair, 21) = Fz
  2667.     intCAEF = 0
  2668.  
  2669. IF magalphaABFD1 - magtripletABps < 0 AND magalphaABFD2 - magtripletABps < 0 AND magalphaFDAB1 - magtripletFDps < 0 AND magalphaFDAB2 - magtripletFDps < 0 THEN
  2670.     qAB1u = (Asu - alphaABFD1u) / fovd
  2671.     numerator = qAB1u * An - Au
  2672.     denominator = Bu - Au + qAB1u * (An - Bn)
  2673.     betaABFD = numerator / denominator
  2674.     qFD1u = (Fsu - alphaFDAB1u) / fovd
  2675.     numerator = qFD1u * Fn - Fu
  2676.     denominator = Du - Fu + qFD1u * (Fn - Dn)
  2677.     betaFDAB = numerator / denominator
  2678.     intABFD = 1
  2679.     pcounttripletintpointpair = pcounttripletintpointpair + 1
  2680.     tripletintpointpair(pcounttripletintpointpair, 1) = Ax * (1 - betaABFD) + betaABFD * Bx
  2681.     tripletintpointpair(pcounttripletintpointpair, 2) = Ay * (1 - betaABFD) + betaABFD * By
  2682.     tripletintpointpair(pcounttripletintpointpair, 3) = Az * (1 - betaABFD) + betaABFD * Bz
  2683.     tripletintpointpair(pcounttripletintpointpair, 4) = Fx * (1 - betaFDAB) + betaFDAB * Dx
  2684.     tripletintpointpair(pcounttripletintpointpair, 5) = Fy * (1 - betaFDAB) + betaFDAB * Dy
  2685.     tripletintpointpair(pcounttripletintpointpair, 6) = Fz * (1 - betaFDAB) + betaFDAB * Dz
  2686.     tripletintpointpair(pcounttripletintpointpair, 7) = Cx
  2687.     tripletintpointpair(pcounttripletintpointpair, 8) = Cy
  2688.     tripletintpointpair(pcounttripletintpointpair, 9) = Cz
  2689.     tripletintpointpair(pcounttripletintpointpair, 10) = Ax
  2690.     tripletintpointpair(pcounttripletintpointpair, 11) = Ay
  2691.     tripletintpointpair(pcounttripletintpointpair, 12) = Az
  2692.     tripletintpointpair(pcounttripletintpointpair, 13) = Bx
  2693.     tripletintpointpair(pcounttripletintpointpair, 14) = By
  2694.     tripletintpointpair(pcounttripletintpointpair, 15) = Bz
  2695.     tripletintpointpair(pcounttripletintpointpair, 16) = Fx
  2696.     tripletintpointpair(pcounttripletintpointpair, 17) = Fy
  2697.     tripletintpointpair(pcounttripletintpointpair, 18) = Fz
  2698.     tripletintpointpair(pcounttripletintpointpair, 19) = Dx
  2699.     tripletintpointpair(pcounttripletintpointpair, 20) = Dy
  2700.     tripletintpointpair(pcounttripletintpointpair, 21) = Dz
  2701.     intABFD = 0
  2702.  
  2703. IF magalphaBCFD1 - magtripletBCps < 0 AND magalphaBCFD2 - magtripletBCps < 0 AND magalphaFDBC1 - magtripletFDps < 0 AND magalphaFDBC2 - magtripletFDps < 0 THEN
  2704.     qBC1u = (Bsu - alphaBCFD1u) / fovd
  2705.     numerator = qBC1u * Bn - Bu
  2706.     denominator = Cu - Bu + qBC1u * (Bn - Cn)
  2707.     betaBCFD = numerator / denominator
  2708.     qFD1u = (Fsu - alphaFDBC1u) / fovd
  2709.     numerator = qFD1u * Fn - Fu
  2710.     denominator = Du - Fu + qFD1u * (Fn - Dn)
  2711.     betaFDBC = numerator / denominator
  2712.     intBCFD = 1
  2713.     pcounttripletintpointpair = pcounttripletintpointpair + 1
  2714.     tripletintpointpair(pcounttripletintpointpair, 1) = Bx * (1 - betaBCFD) + betaBCFD * Cx
  2715.     tripletintpointpair(pcounttripletintpointpair, 2) = By * (1 - betaBCFD) + betaBCFD * Cy
  2716.     tripletintpointpair(pcounttripletintpointpair, 3) = Bz * (1 - betaBCFD) + betaBCFD * Cz
  2717.     tripletintpointpair(pcounttripletintpointpair, 4) = Fx * (1 - betaFDBC) + betaFDBC * Dx
  2718.     tripletintpointpair(pcounttripletintpointpair, 5) = Fy * (1 - betaFDBC) + betaFDBC * Dy
  2719.     tripletintpointpair(pcounttripletintpointpair, 6) = Fz * (1 - betaFDBC) + betaFDBC * Dz
  2720.     tripletintpointpair(pcounttripletintpointpair, 7) = Ax
  2721.     tripletintpointpair(pcounttripletintpointpair, 8) = Ay
  2722.     tripletintpointpair(pcounttripletintpointpair, 9) = Az
  2723.     tripletintpointpair(pcounttripletintpointpair, 10) = Bx
  2724.     tripletintpointpair(pcounttripletintpointpair, 11) = By
  2725.     tripletintpointpair(pcounttripletintpointpair, 12) = Bz
  2726.     tripletintpointpair(pcounttripletintpointpair, 13) = Cx
  2727.     tripletintpointpair(pcounttripletintpointpair, 14) = Cy
  2728.     tripletintpointpair(pcounttripletintpointpair, 15) = Cz
  2729.     tripletintpointpair(pcounttripletintpointpair, 16) = Fx
  2730.     tripletintpointpair(pcounttripletintpointpair, 17) = Fy
  2731.     tripletintpointpair(pcounttripletintpointpair, 18) = Fz
  2732.     tripletintpointpair(pcounttripletintpointpair, 19) = Dx
  2733.     tripletintpointpair(pcounttripletintpointpair, 20) = Dy
  2734.     tripletintpointpair(pcounttripletintpointpair, 21) = Dz
  2735.     intBCFD = 0
  2736.  
  2737. IF magalphaCAFD1 - magtripletCAps < 0 AND magalphaCAFD2 - magtripletCAps < 0 AND magalphaFDCA1 - magtripletFDps < 0 AND magalphaFDCA2 - magtripletFDps < 0 THEN
  2738.     qCA1u = (Csu - alphaCAFD1u) / fovd
  2739.     numerator = qCA1u * Cn - Cu
  2740.     denominator = Au - Cu + qCA1u * (Cn - An)
  2741.     betaCAFD = numerator / denominator
  2742.     qFD1u = (Fsu - alphaFDCA1u) / fovd
  2743.     numerator = qFD1u * Fn - Fu
  2744.     denominator = Du - Fu + qFD1u * (Fn - Dn)
  2745.     betaFDCA = numerator / denominator
  2746.     intCAFD = 1
  2747.     pcounttripletintpointpair = pcounttripletintpointpair + 1
  2748.     tripletintpointpair(pcounttripletintpointpair, 1) = Cx * (1 - betaCAFD) + betaCAFD * Ax
  2749.     tripletintpointpair(pcounttripletintpointpair, 2) = Cy * (1 - betaCAFD) + betaCAFD * Ay
  2750.     tripletintpointpair(pcounttripletintpointpair, 3) = Cz * (1 - betaCAFD) + betaCAFD * Az
  2751.     tripletintpointpair(pcounttripletintpointpair, 4) = Fx * (1 - betaFDCA) + betaFDCA * Dx
  2752.     tripletintpointpair(pcounttripletintpointpair, 5) = Fy * (1 - betaFDCA) + betaFDCA * Dy
  2753.     tripletintpointpair(pcounttripletintpointpair, 6) = Fz * (1 - betaFDCA) + betaFDCA * Dz
  2754.     tripletintpointpair(pcounttripletintpointpair, 7) = Bx
  2755.     tripletintpointpair(pcounttripletintpointpair, 8) = By
  2756.     tripletintpointpair(pcounttripletintpointpair, 9) = Bz
  2757.     tripletintpointpair(pcounttripletintpointpair, 10) = Cx
  2758.     tripletintpointpair(pcounttripletintpointpair, 11) = Cy
  2759.     tripletintpointpair(pcounttripletintpointpair, 12) = Cz
  2760.     tripletintpointpair(pcounttripletintpointpair, 13) = Ax
  2761.     tripletintpointpair(pcounttripletintpointpair, 14) = Ay
  2762.     tripletintpointpair(pcounttripletintpointpair, 15) = Az
  2763.     tripletintpointpair(pcounttripletintpointpair, 16) = Fx
  2764.     tripletintpointpair(pcounttripletintpointpair, 17) = Fy
  2765.     tripletintpointpair(pcounttripletintpointpair, 18) = Fz
  2766.     tripletintpointpair(pcounttripletintpointpair, 19) = Dx
  2767.     tripletintpointpair(pcounttripletintpointpair, 20) = Dy
  2768.     tripletintpointpair(pcounttripletintpointpair, 21) = Dz
  2769.     intCAFD = 0
  2770.  
  2771. triplet.image.generate:
  2772. flagimagechange = 0
  2773.  
  2774. SELECT CASE signaturefull$
  2775.  
  2776.     CASE " 0 0 0" '*' 1 of 15
  2777.         'LOCATE 1, 1: PRINT signaturefull$
  2778.  
  2779.     CASE " 0 0 4" '*' 2 of 15
  2780.         ' Load information on overlap triangle.
  2781.         int1ABCx = tripletintpointpair(1, 1)
  2782.         int1ABCy = tripletintpointpair(1, 2)
  2783.         int1ABCz = tripletintpointpair(1, 3)
  2784.         int1DEFx = tripletintpointpair(1, 4)
  2785.         int1DEFy = tripletintpointpair(1, 5)
  2786.         int1DEFz = tripletintpointpair(1, 6)
  2787.         int2ABCx = tripletintpointpair(2, 1)
  2788.         int2ABCy = tripletintpointpair(2, 2)
  2789.         int2ABCz = tripletintpointpair(2, 3)
  2790.         int2DEFx = tripletintpointpair(2, 4)
  2791.         int2DEFy = tripletintpointpair(2, 5)
  2792.         int2DEFz = tripletintpointpair(2, 6)
  2793.         int3ABCx = tripletintpointpair(3, 1)
  2794.         int3ABCy = tripletintpointpair(3, 2)
  2795.         int3ABCz = tripletintpointpair(3, 3)
  2796.         int3DEFx = tripletintpointpair(3, 4)
  2797.         int3DEFy = tripletintpointpair(3, 5)
  2798.         int3DEFz = tripletintpointpair(3, 6)
  2799.         GOSUB perform.overlap.calculations
  2800.         ' Compare the apparent overlap tringles using centroid.
  2801.         IF magcentABC > magcentDEF AND magdiff > 0 AND areaABC > 0.005 AND areaDEF > 0.005 AND snip004enabled = 1 THEN
  2802.             'LOCATE 2, 1: PRINT signaturefull$
  2803.             flagimagechange = 1
  2804.             ' Classify the two outer points of ABC.
  2805.             outerpoint1x = tripletintpointpair(1, 7)
  2806.             outerpoint1y = tripletintpointpair(1, 8)
  2807.             outerpoint1z = tripletintpointpair(1, 9)
  2808.             possibleoutpoint2x = tripletintpointpair(2, 7)
  2809.             possibleoutpoint2y = tripletintpointpair(2, 8)
  2810.             possibleoutpoint2z = tripletintpointpair(2, 9)
  2811.             possibleoutpoint3x = tripletintpointpair(3, 7)
  2812.             possibleoutpoint3y = tripletintpointpair(3, 8)
  2813.             possibleoutpoint3z = tripletintpointpair(3, 9)
  2814.             '*'possibleoutpoint4x = tripletintpointpair(4, 7)
  2815.             '*'possibleoutpoint4y = tripletintpointpair(4, 8)
  2816.             '*'possibleoutpoint4z = tripletintpointpair(4, 9)
  2817.             IF SQR((outerpoint1x - possibleoutpoint2x) ^ 2 + (outerpoint1y - possibleoutpoint2y) ^ 2 + (outerpoint1z - possibleoutpoint2z) ^ 2) < 0.0001 THEN
  2818.                 outerpoint2x = possibleoutpoint3x
  2819.                 outerpoint2y = possibleoutpoint3y
  2820.                 outerpoint2z = possibleoutpoint3z
  2821.             ELSE
  2822.                 outerpoint2x = possibleoutpoint2x
  2823.                 outerpoint2y = possibleoutpoint2y
  2824.                 outerpoint2z = possibleoutpoint2z
  2825.             END IF
  2826.             ' Classify the lonely point of ABC.
  2827.             possibleinpoint1x = tripletintpointpair(1, 10)
  2828.             possibleinpoint1y = tripletintpointpair(1, 11)
  2829.             possibleinpoint1z = tripletintpointpair(1, 12)
  2830.             possibleinpoint2x = tripletintpointpair(1, 13)
  2831.             possibleinpoint2y = tripletintpointpair(1, 14)
  2832.             possibleinpoint2z = tripletintpointpair(1, 15)
  2833.             IF SQR((possibleinpoint1x - outerpoint1x) ^ 2 + (possibleinpoint1y - outerpoint1y) ^ 2 + (possibleinpoint1z - outerpoint1z) ^ 2) > 0.1 AND SQR((possibleinpoint1x - outerpoint2x) ^ 2 + (possibleinpoint1y - outerpoint2y) ^ 2 + (possibleinpoint1z - outerpoint2z) ^ 2) > 0.1 THEN
  2834.                 innerpointx = possibleinpoint1x
  2835.                 innerpointy = possibleinpoint1y
  2836.                 innerpointz = possibleinpoint1z
  2837.             ELSE
  2838.                 innerpointx = possibleinpoint2x
  2839.                 innerpointy = possibleinpoint2y
  2840.                 innerpointz = possibleinpoint2z
  2841.             END IF
  2842.             ' Determine the closest and furthest int points on each int line for lonely point.
  2843.             test1pointx = tripletintpointpair(1, 1)
  2844.             test1pointy = tripletintpointpair(1, 2)
  2845.             test1pointz = tripletintpointpair(1, 3)
  2846.             test1pointuninvolvedx = tripletintpointpair(1, 7)
  2847.             test1pointuninvolvedy = tripletintpointpair(1, 8)
  2848.             test1pointuninvolvedz = tripletintpointpair(1, 9)
  2849.             disttotest1point = SQR((innerpointx - test1pointx) ^ 2 + (innerpointy - test1pointy) ^ 2 + (innerpointz - test1pointz) ^ 2)
  2850.             disttotest1pointuninvolved = SQR((innerpointx - test1pointuninvolvedx) ^ 2 + (innerpointy - test1pointuninvolvedy) ^ 2 + (innerpointz - test1pointuninvolvedz) ^ 2)
  2851.             test2pointx = tripletintpointpair(2, 1)
  2852.             test2pointy = tripletintpointpair(2, 2)
  2853.             test2pointz = tripletintpointpair(2, 3)
  2854.             test2pointuninvolvedx = tripletintpointpair(2, 7)
  2855.             test2pointuninvolvedy = tripletintpointpair(2, 8)
  2856.             test2pointuninvolvedz = tripletintpointpair(2, 9)
  2857.             disttotest2point = SQR((innerpointx - test2pointx) ^ 2 + (innerpointy - test2pointy) ^ 2 + (innerpointz - test2pointz) ^ 2)
  2858.             disttotest2pointuninvolved = SQR((innerpointx - test2pointuninvolvedx) ^ 2 + (innerpointy - test2pointuninvolvedy) ^ 2 + (innerpointz - test2pointuninvolvedz) ^ 2)
  2859.             test3pointx = tripletintpointpair(3, 1)
  2860.             test3pointy = tripletintpointpair(3, 2)
  2861.             test3pointz = tripletintpointpair(3, 3)
  2862.             test3pointuninvolvedx = tripletintpointpair(3, 7)
  2863.             test3pointuninvolvedy = tripletintpointpair(3, 8)
  2864.             test3pointuninvolvedz = tripletintpointpair(3, 9)
  2865.             disttotest3point = SQR((innerpointx - test3pointx) ^ 2 + (innerpointy - test3pointy) ^ 2 + (innerpointz - test3pointz) ^ 2)
  2866.             disttotest3pointuninvolved = SQR((innerpointx - test3pointuninvolvedx) ^ 2 + (innerpointy - test3pointuninvolvedy) ^ 2 + (innerpointz - test3pointuninvolvedz) ^ 2)
  2867.             test4pointx = tripletintpointpair(4, 1)
  2868.             test4pointy = tripletintpointpair(4, 2)
  2869.             test4pointz = tripletintpointpair(4, 3)
  2870.             test4pointuninvolvedx = tripletintpointpair(4, 7)
  2871.             test4pointuninvolvedy = tripletintpointpair(4, 8)
  2872.             test4pointuninvolvedz = tripletintpointpair(4, 9)
  2873.             disttotest4point = SQR((innerpointx - test4pointx) ^ 2 + (innerpointy - test4pointy) ^ 2 + (innerpointz - test4pointz) ^ 2)
  2874.             disttotest4pointuninvolved = SQR((innerpointx - test4pointuninvolvedx) ^ 2 + (innerpointy - test4pointuninvolvedy) ^ 2 + (innerpointz - test4pointuninvolvedz) ^ 2)
  2875.             testpoint1used = 0
  2876.             testpoint2used = 0
  2877.             testpoint3used = 0
  2878.             testpoint4used = 0
  2879.             IF SQR((disttotest1pointuninvolved - disttotest2pointuninvolved) ^ 2) < 0.0001 THEN
  2880.                 testpoint1used = 1
  2881.                 testpoint2used = 1
  2882.                 IF disttotest1point < disttotest2point THEN
  2883.                     firsttriangleleftx = test1pointx
  2884.                     firsttrianglelefty = test1pointy
  2885.                     firsttriangleleftz = test1pointz
  2886.                     firstfurtherpointx = test2pointx
  2887.                     firstfurtherpointy = test2pointy
  2888.                     firstfurtherpointz = test2pointz
  2889.                 ELSE
  2890.                     firsttriangleleftx = test2pointx
  2891.                     firsttrianglelefty = test2pointy
  2892.                     firsttriangleleftz = test2pointz
  2893.                     firstfurtherpointx = test1pointx
  2894.                     firstfurtherpointy = test1pointy
  2895.                     firstfurtherpointz = test1pointz
  2896.                 END IF
  2897.             END IF
  2898.             IF SQR((disttotest1pointuninvolved - disttotest3pointuninvolved) ^ 2) < 0.0001 THEN
  2899.                 testpoint1used = 1
  2900.                 testpoint3used = 1
  2901.                 IF disttotest1point < disttotest3point THEN
  2902.                     firsttriangleleftx = test1pointx
  2903.                     firsttrianglelefty = test1pointy
  2904.                     firsttriangleleftz = test1pointz
  2905.                     firstfurtherpointx = test3pointx
  2906.                     firstfurtherpointy = test3pointy
  2907.                     firstfurtherpointz = test3pointz
  2908.                 ELSE
  2909.                     firsttriangleleftx = test3pointx
  2910.                     firsttrianglelefty = test3pointy
  2911.                     firsttriangleleftz = test3pointz
  2912.                     firstfurtherpointx = test1pointx
  2913.                     firstfurtherpointy = test1pointy
  2914.                     firstfurtherpointz = test1pointz
  2915.                 END IF
  2916.             END IF
  2917.             IF SQR((disttotest1pointuninvolved - disttotest4pointuninvolved) ^ 2) < 0.0001 THEN
  2918.                 testpoint1used = 1
  2919.                 testpoint4used = 1
  2920.                 IF disttotest1point < disttotest4point THEN
  2921.                     firsttriangleleftx = test1pointx
  2922.                     firsttrianglelefty = test1pointy
  2923.                     firsttriangleleftz = test1pointz
  2924.                     firstfurtherpointx = test4pointx
  2925.                     firstfurtherpointy = test4pointy
  2926.                     firstfurtherpointz = test4pointz
  2927.                 ELSE
  2928.                     firsttriangleleftx = test4pointx
  2929.                     firsttrianglelefty = test4pointy
  2930.                     firsttriangleleftz = test4pointz
  2931.                     firstfurtherpointx = test1pointx
  2932.                     firstfurtherpointy = test1pointy
  2933.                     firstfurtherpointz = test1pointz
  2934.                 END IF
  2935.             END IF
  2936.             IF testpoint2used = 0 AND testpoint3used = 0 THEN
  2937.                 IF disttotest2point < disttotest3point THEN
  2938.                     firsttrianglerightx = test2pointx
  2939.                     firsttrianglerighty = test2pointy
  2940.                     firsttrianglerightz = test2pointz
  2941.                     secondfurtherpointx = test3pointx
  2942.                     secondfurtherpointy = test3pointy
  2943.                     secondfurtherpointz = test3pointz
  2944.                 ELSE
  2945.                     firsttrianglerightx = test3pointx
  2946.                     firsttrianglerighty = test3pointy
  2947.                     firsttrianglerightz = test3pointz
  2948.                     secondfurtherpointx = test2pointx
  2949.                     secondfurtherpointy = test2pointy
  2950.                     secondfurtherpointz = test2pointz
  2951.                 END IF
  2952.             END IF
  2953.             IF testpoint3used = 0 AND testpoint4used = 0 THEN
  2954.                 IF disttotest3point < disttotest4point THEN
  2955.                     firsttrianglerightx = test3pointx
  2956.                     firsttrianglerighty = test3pointy
  2957.                     firsttrianglerightz = test3pointz
  2958.                     secondfurtherpointx = test4pointx
  2959.                     secondfurtherpointy = test4pointy
  2960.                     secondfurtherpointz = test4pointz
  2961.                 ELSE
  2962.                     firsttrianglerightx = test4pointx
  2963.                     firsttrianglerighty = test4pointy
  2964.                     firsttrianglerightz = test4pointz
  2965.                     secondfurtherpointx = test3pointx
  2966.                     secondfurtherpointy = test3pointy
  2967.                     secondfurtherpointz = test3pointz
  2968.                 END IF
  2969.             END IF
  2970.             IF testpoint4used = 0 AND testpoint2used = 0 THEN
  2971.                 IF disttotest4point < disttotest2point THEN
  2972.                     firsttrianglerightx = test4pointx
  2973.                     firsttrianglerighty = test4pointy
  2974.                     firsttrianglerightz = test4pointz
  2975.                     secondfurtherpointx = test2pointx
  2976.                     secondfurtherpointy = test2pointy
  2977.                     secondfurtherpointz = test2pointz
  2978.                 ELSE
  2979.                     firsttrianglerightx = test2pointx
  2980.                     firsttrianglerighty = test2pointy
  2981.                     firsttrianglerightz = test2pointz
  2982.                     secondfurtherpointx = test4pointx
  2983.                     secondfurtherpointy = test4pointy
  2984.                     secondfurtherpointz = test4pointz
  2985.                 END IF
  2986.             END IF
  2987.             flagindexkused = 0
  2988.             ' First new triangle overwrites old one.
  2989.             basepointx = innerpointx
  2990.             basepointy = innerpointy
  2991.             basepointz = innerpointz
  2992.             rightpointx = firsttrianglerightx
  2993.             rightpointy = firsttrianglerighty
  2994.             rightpointz = firsttrianglerightz
  2995.             leftpointx = firsttriangleleftx
  2996.             leftpointy = firsttrianglelefty
  2997.             leftpointz = firsttriangleleftz
  2998.             GOSUB compute.triangle.areas.cents
  2999.             GOSUB create.image.triangle
  3000.             ' Second new triangle.
  3001.             basepointx = firstfurtherpointx
  3002.             basepointy = firstfurtherpointy
  3003.             basepointz = firstfurtherpointz
  3004.             rightpointx = secondfurtherpointx
  3005.             rightpointy = secondfurtherpointy
  3006.             rightpointz = secondfurtherpointz
  3007.             leftpointx = outerpoint1x
  3008.             leftpointy = outerpoint1y
  3009.             leftpointz = outerpoint1z
  3010.             GOSUB compute.triangle.areas.cents
  3011.             GOSUB create.image.triangle
  3012.             ' Third new triangle.
  3013.             basepointx = firstfurtherpointx
  3014.             basepointy = firstfurtherpointy
  3015.             basepointz = firstfurtherpointz
  3016.             rightpointx = outerpoint1x
  3017.             rightpointy = outerpoint1y
  3018.             rightpointz = outerpoint1z
  3019.             leftpointx = outerpoint2x
  3020.             leftpointy = outerpoint2y
  3021.             leftpointz = outerpoint2z
  3022.             GOSUB compute.triangle.areas.cents
  3023.             GOSUB create.image.triangle
  3024.         END IF
  3025.         IF flagimagechange = 1 THEN
  3026.             IF flagindexkused = 1 THEN
  3027.                 GOTO begintripletsnipsubloop
  3028.             ELSE
  3029.                 GOSUB triplet.image.repack
  3030.             END IF
  3031.         END IF
  3032.  
  3033.     CASE " 0 3 0" '*' 3 of 15
  3034.         ' Load information on overlap triangle.
  3035.         int3ABCx = tripletencpoint(1, 1)
  3036.         int3ABCy = tripletencpoint(1, 2)
  3037.         int3ABCz = tripletencpoint(1, 3)
  3038.         int3DEFx = tripletencpoint(1, 4)
  3039.         int3DEFy = tripletencpoint(1, 5)
  3040.         int3DEFz = tripletencpoint(1, 6)
  3041.         int1ABCx = tripletencpoint(2, 1)
  3042.         int1ABCy = tripletencpoint(2, 2)
  3043.         int1ABCz = tripletencpoint(2, 3)
  3044.         int1DEFx = tripletencpoint(2, 4)
  3045.         int1DEFy = tripletencpoint(2, 5)
  3046.         int1DEFz = tripletencpoint(3, 6)
  3047.         int2ABCx = tripletencpoint(3, 1)
  3048.         int2ABCy = tripletencpoint(3, 2)
  3049.         int2ABCz = tripletencpoint(3, 3)
  3050.         int2DEFx = tripletencpoint(3, 4)
  3051.         int2DEFy = tripletencpoint(3, 5)
  3052.         int2DEFz = tripletencpoint(3, 6)
  3053.         GOSUB perform.overlap.calculations
  3054.         ' Compare the apparent overlap tringles using centroid.
  3055.         IF magcentABC > magcentDEF AND snip030enabled = 1 THEN
  3056.             'IF magcentABC > magcentDEF AND magdiff > 0 AND areaABC > 0 AND areaDEF > 0 AND snip030enabled = 1 THEN
  3057.             'LOCATE 3, 1: PRINT signaturefull$
  3058.             flagimagechange = 1
  3059.             flagindexkused = 0
  3060.         END IF
  3061.         IF flagimagechange = 1 THEN
  3062.             IF flagindexkused = 1 THEN
  3063.  
  3064.             ELSE
  3065.                 GOSUB triplet.image.repack
  3066.             END IF
  3067.         END IF
  3068.  
  3069.     CASE " 3 0 0" '*' 4 of 15
  3070.         ' Load information on overlap triangle.
  3071.         int3ABCx = tripletencpoint(1, 4)
  3072.         int3ABCy = tripletencpoint(1, 5)
  3073.         int3ABCz = tripletencpoint(1, 6)
  3074.         int3DEFx = tripletencpoint(1, 1)
  3075.         int3DEFy = tripletencpoint(1, 2)
  3076.         int3DEFz = tripletencpoint(1, 3)
  3077.         int1ABCx = tripletencpoint(2, 4)
  3078.         int1ABCy = tripletencpoint(2, 5)
  3079.         int1ABCz = tripletencpoint(2, 6)
  3080.         int1DEFx = tripletencpoint(2, 1)
  3081.         int1DEFy = tripletencpoint(2, 2)
  3082.         int1DEFz = tripletencpoint(2, 3)
  3083.         int2ABCx = tripletencpoint(3, 4)
  3084.         int2ABCy = tripletencpoint(3, 5)
  3085.         int2ABCz = tripletencpoint(3, 6)
  3086.         int2DEFx = tripletencpoint(3, 1)
  3087.         int2DEFy = tripletencpoint(3, 2)
  3088.         int2DEFz = tripletencpoint(3, 3)
  3089.         GOSUB perform.overlap.calculations
  3090.         ' Compare the apparent overlap tringles using centroid.
  3091.         IF magcentABC > magcentDEF AND magdiff > 0 AND areaABC > 0.005 AND areaDEF > 0.005 AND snip300enabled = 1 THEN
  3092.             'LOCATE 4, 1: PRINT signaturefull$
  3093.             flagimagechange = 1
  3094.             centDEFx = (1 / 3) * (tripletencpoint(1, 4) + tripletencpoint(2, 4) + tripletencpoint(3, 4))
  3095.             centDEFy = (1 / 3) * (tripletencpoint(1, 5) + tripletencpoint(2, 5) + tripletencpoint(3, 5))
  3096.             centDEFz = (1 / 3) * (tripletencpoint(1, 6) + tripletencpoint(2, 6) + tripletencpoint(3, 6))
  3097.             flagindexkused = 0
  3098.             ' First new triangle overwrites old one.
  3099.             basepointx = centDEFx
  3100.             basepointy = centDEFy
  3101.             basepointz = centDEFz
  3102.             rightpointx = Ax
  3103.             rightpointy = Ay
  3104.             rightpointz = Az
  3105.             leftpointx = Bx
  3106.             leftpointy = By
  3107.             leftpointz = Bz
  3108.             GOSUB compute.triangle.areas.cents
  3109.             GOSUB create.image.triangle
  3110.             ' Second new triangle.
  3111.             basepointx = centDEFx
  3112.             basepointy = centDEFy
  3113.             basepointz = centDEFz
  3114.             rightpointx = Bx
  3115.             rightpointy = By
  3116.             rightpointz = Bz
  3117.             leftpointx = Cx
  3118.             leftpointy = Cy
  3119.             leftpointz = Cz
  3120.             GOSUB compute.triangle.areas.cents
  3121.             GOSUB create.image.triangle
  3122.             ' Third new triangle.
  3123.             basepointx = centDEFx
  3124.             basepointy = centDEFy
  3125.             basepointz = centDEFz
  3126.             rightpointx = Cx
  3127.             rightpointy = Cy
  3128.             rightpointz = Cz
  3129.             leftpointx = Ax
  3130.             leftpointy = Ay
  3131.             leftpointz = Az
  3132.             GOSUB compute.triangle.areas.cents
  3133.             GOSUB create.image.triangle
  3134.         END IF
  3135.         IF flagimagechange = 1 THEN
  3136.             IF flagindexkused = 1 THEN
  3137.                 GOTO begintripletsnipsubloop
  3138.             ELSE
  3139.                 GOSUB triplet.image.repack
  3140.             END IF
  3141.         END IF
  3142.  
  3143.     CASE " 0 0 6" '*' 5 of 15
  3144.         ' Load information on overlap triangle.
  3145.         int3ABCx = tripletintpointpair(3, 1)
  3146.         int3ABCy = tripletintpointpair(3, 2)
  3147.         int3ABCz = tripletintpointpair(3, 3)
  3148.         int3DEFx = tripletintpointpair(3, 4)
  3149.         int3DEFy = tripletintpointpair(3, 5)
  3150.         int3DEFz = tripletintpointpair(3, 6)
  3151.         int1ABCx = tripletintpointpair(1, 1)
  3152.         int1ABCy = tripletintpointpair(1, 2)
  3153.         int1ABCz = tripletintpointpair(1, 3)
  3154.         int1DEFx = tripletintpointpair(1, 4)
  3155.         int1DEFy = tripletintpointpair(1, 5)
  3156.         int1DEFz = tripletintpointpair(1, 6)
  3157.         int2ABCx = tripletintpointpair(2, 1)
  3158.         int2ABCy = tripletintpointpair(2, 2)
  3159.         int2ABCz = tripletintpointpair(2, 3)
  3160.         int2DEFx = tripletintpointpair(2, 4)
  3161.         int2DEFy = tripletintpointpair(2, 5)
  3162.         int2DEFz = tripletintpointpair(2, 6)
  3163.         GOSUB perform.overlap.calculations
  3164.         ' Compare the apparent overlap tringles using centroid.
  3165.         IF magcentABC > magcentDEF AND magdiff > 0 AND areaABC > 0.005 AND areaDEF > 0.005 AND snip006enabled = 1 THEN
  3166.             'LOCATE 5, 1: PRINT signaturefull$
  3167.             flagimagechange = 1
  3168.             centDEFx = (1 / 3) * (Dx + Ex + Fx) '(tripletencpoint(1, 4) + tripletencpoint(2, 4) + tripletencpoint(3, 4))
  3169.             centDEFy = (1 / 3) * (Dy + Ey + Fy) '(tripletencpoint(1, 5) + tripletencpoint(2, 5) + tripletencpoint(3, 5))
  3170.             centDEFz = (1 / 3) * (Dz + Ez + Fz) '(tripletencpoint(1, 6) + tripletencpoint(2, 6) + tripletencpoint(3, 6))
  3171.             flagindexkused = 0
  3172.             ' First new triangle overwrites old one.
  3173.             basepointx = centDEFx
  3174.             basepointy = centDEFy
  3175.             basepointz = centDEFz
  3176.             rightpointx = Ax
  3177.             rightpointy = Ay
  3178.             rightpointz = Az
  3179.             leftpointx = Bx
  3180.             leftpointy = By
  3181.             leftpointz = Bz
  3182.             GOSUB compute.triangle.areas.cents
  3183.             GOSUB create.image.triangle
  3184.             ' Second new triangle.
  3185.             basepointx = centDEFx
  3186.             basepointy = centDEFy
  3187.             basepointz = centDEFz
  3188.             rightpointx = Bx
  3189.             rightpointy = By
  3190.             rightpointz = Bz
  3191.             leftpointx = Cx
  3192.             leftpointy = Cy
  3193.             leftpointz = Cz
  3194.             GOSUB compute.triangle.areas.cents
  3195.             GOSUB create.image.triangle
  3196.             ' Third new triangle.
  3197.             basepointx = centDEFx
  3198.             basepointy = centDEFy
  3199.             basepointz = centDEFz
  3200.             rightpointx = Cx
  3201.             rightpointy = Cy
  3202.             rightpointz = Cz
  3203.             leftpointx = Ax
  3204.             leftpointy = Ay
  3205.             leftpointz = Az
  3206.             GOSUB compute.triangle.areas.cents
  3207.             GOSUB create.image.triangle
  3208.         END IF
  3209.         IF flagimagechange = 1 THEN
  3210.             IF flagindexkused = 1 THEN
  3211.                 GOTO begintripletsnipsubloop
  3212.             ELSE
  3213.                 GOSUB triplet.image.repack
  3214.             END IF
  3215.         END IF
  3216.  
  3217.     CASE " 0 1 2" '*' 6 of 15
  3218.         ' Load information on overlap triangle.
  3219.         int3ABCx = tripletencpoint(1, 1)
  3220.         int3ABCy = tripletencpoint(1, 2)
  3221.         int3ABCz = tripletencpoint(1, 3)
  3222.         int3DEFx = tripletencpoint(1, 4)
  3223.         int3DEFy = tripletencpoint(1, 5)
  3224.         int3DEFz = tripletencpoint(1, 6)
  3225.         int1ABCx = tripletintpointpair(1, 1)
  3226.         int1ABCy = tripletintpointpair(1, 2)
  3227.         int1ABCz = tripletintpointpair(1, 3)
  3228.         int1DEFx = tripletintpointpair(1, 4)
  3229.         int1DEFy = tripletintpointpair(1, 5)
  3230.         int1DEFz = tripletintpointpair(1, 6)
  3231.         int2ABCx = tripletintpointpair(2, 1)
  3232.         int2ABCy = tripletintpointpair(2, 2)
  3233.         int2ABCz = tripletintpointpair(2, 3)
  3234.         int2DEFx = tripletintpointpair(2, 4)
  3235.         int2DEFy = tripletintpointpair(2, 5)
  3236.         int2DEFz = tripletintpointpair(2, 6)
  3237.         GOSUB perform.overlap.calculations
  3238.         ' Compare the apparent overlap tringles using centroid.
  3239.         IF magcentABC > magcentDEF AND magdiff > 0 AND areaABC > 0.005 AND areaDEF > 0.005 AND snip012enabled = 1 THEN
  3240.             'LOCATE 6, 1: PRINT signaturefull$
  3241.             flagimagechange = 1
  3242.             flagindexkused = 0
  3243.             ' First new triangle overwrites old one.
  3244.             basepointx = tripletintpointpair(2, 7)
  3245.             basepointy = tripletintpointpair(2, 8)
  3246.             basepointz = tripletintpointpair(2, 9)
  3247.             rightpointx = int1ABCx
  3248.             rightpointy = int1ABCy
  3249.             rightpointz = int1ABCz
  3250.             leftpointx = tripletintpointpair(1, 7)
  3251.             leftpointy = tripletintpointpair(1, 8)
  3252.             leftpointz = tripletintpointpair(1, 9)
  3253.             GOSUB compute.triangle.areas.cents
  3254.             GOSUB create.image.triangle
  3255.             ' Second new triangle.
  3256.             basepointx = int2ABCx
  3257.             basepointy = int2ABCy
  3258.             basepointz = int2ABCz
  3259.             rightpointx = tripletintpointpair(1, 7)
  3260.             rightpointy = tripletintpointpair(1, 8)
  3261.             rightpointz = tripletintpointpair(1, 9)
  3262.             leftpointx = int1ABCx
  3263.             leftpointy = int1ABCy
  3264.             leftpointz = int1ABCz
  3265.             GOSUB compute.triangle.areas.cents
  3266.             GOSUB create.image.triangle
  3267.         END IF
  3268.         IF flagimagechange = 1 THEN
  3269.             IF flagindexkused = 1 THEN
  3270.                 GOTO begintripletsnipsubloop
  3271.             ELSE
  3272.                 GOSUB triplet.image.repack
  3273.             END IF
  3274.         END IF
  3275.  
  3276.     CASE " 1 0 2" '*' 7 of 15
  3277.         ' Load information on overlap triangle.
  3278.         int3ABCx = tripletencpoint(1, 4)
  3279.         int3ABCy = tripletencpoint(1, 5)
  3280.         int3ABCz = tripletencpoint(1, 6)
  3281.         int3DEFx = tripletencpoint(1, 1)
  3282.         int3DEFy = tripletencpoint(1, 2)
  3283.         int3DEFz = tripletencpoint(1, 3)
  3284.         int1ABCx = tripletintpointpair(1, 1)
  3285.         int1ABCy = tripletintpointpair(1, 2)
  3286.         int1ABCz = tripletintpointpair(1, 3)
  3287.         int1DEFx = tripletintpointpair(1, 4)
  3288.         int1DEFy = tripletintpointpair(1, 5)
  3289.         int1DEFz = tripletintpointpair(1, 6)
  3290.         int2ABCx = tripletintpointpair(2, 1)
  3291.         int2ABCy = tripletintpointpair(2, 2)
  3292.         int2ABCz = tripletintpointpair(2, 3)
  3293.         int2DEFx = tripletintpointpair(2, 4)
  3294.         int2DEFy = tripletintpointpair(2, 5)
  3295.         int2DEFz = tripletintpointpair(2, 6)
  3296.         GOSUB perform.overlap.calculations
  3297.         ' Compare the apparent overlap tringles using centroid.
  3298.         IF magcentABC > magcentDEF AND magdiff > 0 AND areaABC > 0.005 AND areaDEF > 0.005 AND snip102enabled = 1 THEN
  3299.             'LOCATE 7, 1: PRINT signaturefull$
  3300.             flagimagechange = 1
  3301.             outerpointx = tripletintpointpair(1, 7)
  3302.             outerpointy = tripletintpointpair(1, 8)
  3303.             outerpointz = tripletintpointpair(1, 9)
  3304.             leftvertpointx = tripletintpointpair(1, 10)
  3305.             leftvertpointy = tripletintpointpair(1, 11)
  3306.             leftvertpointz = tripletintpointpair(1, 12)
  3307.             rightvertpointx = tripletintpointpair(1, 13)
  3308.             rightvertpointy = tripletintpointpair(1, 14)
  3309.             rightvertpointz = tripletintpointpair(1, 15)
  3310.             int1ABCdistleftvertpoint = SQR((leftvertpointx - int1ABCx) ^ 2 + (leftvertpointy - int1ABCy) ^ 2 + (leftvertpointz - int1ABCz) ^ 2)
  3311.             '*'int1ABCdistrightvertpoint = SQR((rightvertpointx - int1ABCx) ^ 2 + (rightvertpointy - int1ABCy) ^ 2 + (rightvertpointz - int1ABCz) ^ 2)
  3312.             int2ABCdistleftvertpoint = SQR((leftvertpointx - int2ABCx) ^ 2 + (leftvertpointy - int2ABCy) ^ 2 + (leftvertpointz - int2ABCz) ^ 2)
  3313.             '*'int2ABCdistrightvertpoint = SQR((rightvertpointx - int2ABCx) ^ 2 + (rightvertpointy - int2ABCy) ^ 2 + (rightvertpointz - int2ABCz) ^ 2)
  3314.             IF int1ABCdistleftvertpoint < int2ABCdistleftvertpoint THEN
  3315.                 intleftclosestx = int1ABCx
  3316.                 intleftclosesty = int1ABCy
  3317.                 intleftclosestz = int1ABCz
  3318.                 intrightclosestx = int2ABCx
  3319.                 intrightclosesty = int2ABCy
  3320.                 intrightclosestz = int2ABCz
  3321.             ELSE
  3322.                 intleftclosestx = int2ABCx
  3323.                 intleftclosesty = int2ABCy
  3324.                 intleftclosestz = int2ABCz
  3325.                 intrightclosestx = int1ABCx
  3326.                 intrightclosesty = int1ABCy
  3327.                 intrightclosestz = int1ABCz
  3328.             END IF
  3329.             flagindexkused = 0
  3330.             ' First new triangle overwrites old one.
  3331.             basepointx = leftvertpointx
  3332.             basepointy = leftvertpointy
  3333.             basepointz = leftvertpointz
  3334.             rightpointx = intleftclosestx
  3335.             rightpointy = intleftclosesty
  3336.             rightpointz = intleftclosestz
  3337.             leftpointx = int3ABCx
  3338.             leftpointy = int3ABCy
  3339.             leftpointz = int3ABCz
  3340.             GOSUB compute.triangle.areas.cents
  3341.             GOSUB create.image.triangle
  3342.             ' Second new triangle.
  3343.             basepointx = outerpointx
  3344.             basepointy = outerpointy
  3345.             basepointz = outerpointz
  3346.             rightpointx = leftvertpointx
  3347.             rightpointy = leftvertpointy
  3348.             rightpointz = leftvertpointz
  3349.             leftpointx = int3ABCx
  3350.             leftpointy = int3ABCy
  3351.             leftpointz = int3ABCz
  3352.             GOSUB compute.triangle.areas.cents
  3353.             GOSUB create.image.triangle
  3354.             ' Third new triangle.
  3355.             basepointx = outerpointx
  3356.             basepointy = outerpointy
  3357.             basepointz = outerpointz
  3358.             rightpointx = int3ABCx
  3359.             rightpointy = int3ABCy
  3360.             rightpointz = int3ABCz
  3361.             leftpointx = rightvertpointx
  3362.             leftpointy = rightvertpointy
  3363.             leftpointz = rightvertpointz
  3364.             GOSUB compute.triangle.areas.cents
  3365.             GOSUB create.image.triangle
  3366.             ' Fourth new triangle.
  3367.             basepointx = rightvertpointx
  3368.             basepointy = rightvertpointy
  3369.             basepointz = rightvertpointz
  3370.             rightpointx = int3ABCx
  3371.             rightpointy = int3ABCy
  3372.             rightpointz = int3ABCz
  3373.             leftpointx = intrightclosestx
  3374.             leftpointy = intrightclosesty
  3375.             leftpointz = intrightclosestz
  3376.             GOSUB compute.triangle.areas.cents
  3377.             GOSUB create.image.triangle
  3378.         END IF
  3379.         IF flagimagechange = 1 THEN
  3380.             IF flagindexkused = 1 THEN
  3381.                 GOTO begintripletsnipsubloop
  3382.             ELSE
  3383.                 GOSUB triplet.image.repack
  3384.             END IF
  3385.         END IF
  3386.     CASE " 1 1 2" '*' 8 of 15
  3387.         ' Load information on overlap triangle.
  3388.         int3ABCx = tripletencpoint(1, 4) '
  3389.         int3ABCy = tripletencpoint(1, 5) '
  3390.         int3ABCz = tripletencpoint(1, 6) '
  3391.         int3DEFx = tripletencpoint(1, 1) '
  3392.         int3DEFy = tripletencpoint(1, 2) '
  3393.         int3DEFz = tripletencpoint(1, 3) '
  3394.         int1ABCx = tripletintpointpair(1, 1)
  3395.         int1ABCy = tripletintpointpair(1, 2)
  3396.         int1ABCz = tripletintpointpair(1, 3)
  3397.         int1DEFx = tripletintpointpair(1, 4)
  3398.         int1DEFy = tripletintpointpair(1, 5)
  3399.         int1DEFz = tripletintpointpair(1, 6)
  3400.         int2ABCx = tripletintpointpair(2, 1)
  3401.         int2ABCy = tripletintpointpair(2, 2)
  3402.         int2ABCz = tripletintpointpair(2, 3)
  3403.         int2DEFx = tripletintpointpair(2, 4)
  3404.         int2DEFy = tripletintpointpair(2, 5)
  3405.         int2DEFz = tripletintpointpair(2, 6)
  3406.         GOSUB perform.overlap.calculations
  3407.         ' Compare the apparent overlap tringles using centroid.
  3408.         IF magcentABC > magcentDEF AND magdiff > 0 AND areaABC > 0.005 AND areaDEF > 0.005 AND snip112enabled = 1 THEN
  3409.             'LOCATE 8, 1: PRINT signaturefull$
  3410.             flagimagechange = 1
  3411.             flagindexkused = 0
  3412.             ' First new triangle overwrites old one.
  3413.             basepointx = int3ABCx '
  3414.             basepointy = int3ABCy '
  3415.             basepointz = int3ABCz '
  3416.             rightpointx = int1ABCx
  3417.             rightpointy = int1ABCy
  3418.             rightpointz = int1ABCz
  3419.             leftpointx = tripletintpointpair(2, 7)
  3420.             leftpointy = tripletintpointpair(2, 8)
  3421.             leftpointz = tripletintpointpair(2, 9)
  3422.             GOSUB compute.triangle.areas.cents
  3423.             GOSUB create.image.triangle
  3424.             ' Second new triangle.
  3425.             basepointx = int3ABCx '
  3426.             basepointy = int3ABCy '
  3427.             basepointz = int3ABCz '
  3428.             rightpointx = tripletintpointpair(1, 7)
  3429.             rightpointy = tripletintpointpair(1, 8)
  3430.             rightpointz = tripletintpointpair(1, 9)
  3431.             leftpointx = tripletintpointpair(2, 7)
  3432.             leftpointy = tripletintpointpair(2, 8)
  3433.             leftpointz = tripletintpointpair(2, 9)
  3434.             GOSUB compute.triangle.areas.cents
  3435.             GOSUB create.image.triangle
  3436.             ' Third new triangle.
  3437.             basepointx = int3ABCx '
  3438.             basepointy = int3ABCy '
  3439.             basepointz = int3ABCz '
  3440.             rightpointx = int2ABCx
  3441.             rightpointy = int2ABCy
  3442.             rightpointz = int2ABCz
  3443.             leftpointx = tripletintpointpair(1, 7)
  3444.             leftpointy = tripletintpointpair(1, 8)
  3445.             leftpointz = tripletintpointpair(1, 9)
  3446.             GOSUB compute.triangle.areas.cents
  3447.             GOSUB create.image.triangle
  3448.         END IF
  3449.         IF flagimagechange = 1 THEN
  3450.             IF flagindexkused = 1 THEN
  3451.                 GOTO begintripletsnipsubloop
  3452.             ELSE
  3453.                 GOSUB triplet.image.repack
  3454.             END IF
  3455.         END IF
  3456.  
  3457.     CASE " 0 2 2" '*' 9 of 15
  3458.         ' Load information on overlap triangle.
  3459.         int3ABCx = tripletencpoint(1, 1)
  3460.         int3ABCy = tripletencpoint(1, 2)
  3461.         int3ABCz = tripletencpoint(1, 3)
  3462.         int3DEFx = tripletencpoint(1, 4)
  3463.         int3DEFy = tripletencpoint(1, 5)
  3464.         int3DEFz = tripletencpoint(1, 6)
  3465.         int1ABCx = tripletintpointpair(1, 1)
  3466.         int1ABCy = tripletintpointpair(1, 2)
  3467.         int1ABCz = tripletintpointpair(1, 3)
  3468.         int1DEFx = tripletintpointpair(1, 4)
  3469.         int1DEFy = tripletintpointpair(1, 5)
  3470.         int1DEFz = tripletintpointpair(1, 6)
  3471.         int2ABCx = tripletintpointpair(2, 1)
  3472.         int2ABCy = tripletintpointpair(2, 2)
  3473.         int2ABCz = tripletintpointpair(2, 3)
  3474.         int2DEFx = tripletintpointpair(2, 4)
  3475.         int2DEFy = tripletintpointpair(2, 5)
  3476.         int2DEFz = tripletintpointpair(2, 6)
  3477.         GOSUB perform.overlap.calculations
  3478.         ' Compare the apparent overlap tringles using centroid.
  3479.         IF magcentABC > magcentDEF AND magdiff > 0 AND areaABC > 0.005 AND areaDEF > 0.005 AND snip022enabled = 1 THEN
  3480.             'LOCATE 9, 1: PRINT signaturefull$
  3481.             flagimagechange = 1
  3482.             ' Classify the outer point of ABC.
  3483.             possibleoutpoint1x = tripletintpointpair(1, 10)
  3484.             possibleoutpoint1y = tripletintpointpair(1, 11)
  3485.             possibleoutpoint1z = tripletintpointpair(1, 12)
  3486.             possibleoutpoint2x = tripletintpointpair(1, 13)
  3487.             possibleoutpoint2y = tripletintpointpair(1, 14)
  3488.             possibleoutpoint2z = tripletintpointpair(1, 15)
  3489.             IF SQR((possibleoutpoint1x - tripletencpoint(1, 1)) ^ 2 + (possibleoutpoint1y - tripletencpoint(1, 2)) ^ 2 + (possibleoutpoint1z - tripletencpoint(1, 3)) ^ 2) > 0.1 AND SQR((possibleoutpoint1x - tripletencpoint(2, 1)) ^ 2 + (possibleoutpoint1y - tripletencpoint(2, 2)) ^ 2 + (possibleoutpoint1z - tripletencpoint(2, 3)) ^ 2) > 0.1 THEN
  3490.                 outerpointx = possibleoutpoint1x
  3491.                 outerpointy = possibleoutpoint1y
  3492.                 outerpointz = possibleoutpoint1z
  3493.             ELSE
  3494.                 outerpointx = possibleoutpoint2x
  3495.                 outerpointy = possibleoutpoint2y
  3496.                 outerpointz = possibleoutpoint2z
  3497.             END IF
  3498.             flagindexkused = 0
  3499.             ' First new triangle overwrites old one.
  3500.             basepointx = int1ABCx
  3501.             basepointy = int1ABCy
  3502.             basepointz = int1ABCz
  3503.             rightpointx = outerpointx
  3504.             rightpointy = outerpointy
  3505.             rightpointz = outerpointz
  3506.             leftpointx = int2ABCx
  3507.             leftpointy = int2ABCy
  3508.             leftpointz = int2ABCz
  3509.             GOSUB compute.triangle.areas.cents
  3510.             GOSUB create.image.triangle
  3511.         END IF
  3512.         IF flagimagechange = 1 THEN
  3513.             IF flagindexkused = 1 THEN
  3514.                 GOTO begintripletsnipsubloop
  3515.             ELSE
  3516.                 GOSUB triplet.image.repack
  3517.             END IF
  3518.         END IF
  3519.  
  3520.     CASE " 2 0 2" '*' 10 of 15
  3521.         ' Load information on overlap triangle.
  3522.         int3ABCx = tripletencpoint(1, 4)
  3523.         int3ABCy = tripletencpoint(1, 5)
  3524.         int3ABCz = tripletencpoint(1, 6)
  3525.         int3DEFx = tripletencpoint(1, 1)
  3526.         int3DEFy = tripletencpoint(1, 2)
  3527.         int3DEFz = tripletencpoint(1, 3)
  3528.         int1ABCx = tripletintpointpair(1, 1)
  3529.         int1ABCy = tripletintpointpair(1, 2)
  3530.         int1ABCz = tripletintpointpair(1, 3)
  3531.         int1DEFx = tripletintpointpair(1, 4)
  3532.         int1DEFy = tripletintpointpair(1, 5)
  3533.         int1DEFz = tripletintpointpair(1, 6)
  3534.         int2ABCx = tripletintpointpair(2, 1)
  3535.         int2ABCy = tripletintpointpair(2, 2)
  3536.         int2ABCz = tripletintpointpair(2, 3)
  3537.         int2DEFx = tripletintpointpair(2, 4)
  3538.         int2DEFy = tripletintpointpair(2, 5)
  3539.         int2DEFz = tripletintpointpair(2, 6)
  3540.         GOSUB perform.overlap.calculations
  3541.         ' Compare the apparent overlap tringles using centroid.
  3542.         IF magcentABC > magcentDEF AND magdiff > 0 AND areaABC > 0.005 AND areaDEF > 0.005 AND snip202enabled = 1 THEN
  3543.             'LOCATE 10, 1: PRINT signaturefull$
  3544.             flagimagechange = 1
  3545.             verttopx = tripletintpointpair(1, 7)
  3546.             verttopy = tripletintpointpair(1, 8)
  3547.             verttopz = tripletintpointpair(1, 9)
  3548.             vertleftx = tripletintpointpair(1, 10)
  3549.             vertlefty = tripletintpointpair(1, 11)
  3550.             vertleftz = tripletintpointpair(1, 12)
  3551.             vertrightx = tripletintpointpair(1, 13)
  3552.             vertrighty = tripletintpointpair(1, 14)
  3553.             vertrightz = tripletintpointpair(1, 15)
  3554.             disttointpoint1 = SQR((vertleftx - tripletintpointpair(1, 1)) ^ 2 + (vertlefty - tripletintpointpair(1, 2)) ^ 2 + (vertleftz - tripletintpointpair(1, 3)) ^ 2)
  3555.             disttointpoint2 = SQR((vertleftx - tripletintpointpair(2, 1)) ^ 2 + (vertlefty - tripletintpointpair(2, 2)) ^ 2 + (vertleftz - tripletintpointpair(2, 3)) ^ 2)
  3556.             IF disttointpoint1 < disttointpoint2 THEN
  3557.                 intleftx = tripletintpointpair(1, 1)
  3558.                 intlefty = tripletintpointpair(1, 2)
  3559.                 intleftz = tripletintpointpair(1, 3)
  3560.                 intrightx = tripletintpointpair(2, 1)
  3561.                 intrighty = tripletintpointpair(2, 2)
  3562.                 intrightz = tripletintpointpair(2, 3)
  3563.                 candencleft1x = tripletintpointpair(1, 16)
  3564.                 candencleft1y = tripletintpointpair(1, 17)
  3565.                 candencleft1z = tripletintpointpair(1, 18)
  3566.                 candencleft2x = tripletintpointpair(1, 19)
  3567.                 candencleft2y = tripletintpointpair(1, 20)
  3568.                 candencleft2z = tripletintpointpair(1, 21)
  3569.             ELSE
  3570.                 intleftx = tripletintpointpair(2, 1)
  3571.                 intlefty = tripletintpointpair(2, 2)
  3572.                 intleftz = tripletintpointpair(2, 3)
  3573.                 intrightx = tripletintpointpair(1, 1)
  3574.                 intrighty = tripletintpointpair(1, 2)
  3575.                 intrightz = tripletintpointpair(1, 3)
  3576.                 candencleft1x = tripletintpointpair(2, 16)
  3577.                 candencleft1y = tripletintpointpair(2, 17)
  3578.                 candencleft1z = tripletintpointpair(2, 18)
  3579.                 candencleft2x = tripletintpointpair(2, 19)
  3580.                 candencleft2y = tripletintpointpair(2, 20)
  3581.                 candencleft2z = tripletintpointpair(2, 21)
  3582.             END IF
  3583.             IF SQR((candencleft1x - tripletencpoint(1, 1)) ^ 2 + (candencleft1y - tripletencpoint(1, 2)) ^ 2 + (candencleft1z - tripletencpoint(1, 3)) ^ 2) < 0.0001 OR SQR((candencleft2x - tripletencpoint(1, 1)) ^ 2 + (candencleft2y - tripletencpoint(1, 2)) ^ 2 + (candencleft2z - tripletencpoint(1, 3)) ^ 2) < 0.0001 THEN
  3584.                 encpointleftx = tripletencpoint(1, 4)
  3585.                 encpointlefty = tripletencpoint(1, 5)
  3586.                 encpointleftz = tripletencpoint(1, 6)
  3587.                 encpointrightx = tripletencpoint(2, 4)
  3588.                 encpointrighty = tripletencpoint(2, 5)
  3589.                 encpointrightz = tripletencpoint(2, 6)
  3590.             ELSE
  3591.                 encpointleftx = tripletencpoint(2, 4)
  3592.                 encpointlefty = tripletencpoint(2, 5)
  3593.                 encpointleftz = tripletencpoint(2, 6)
  3594.                 encpointrightx = tripletencpoint(1, 4)
  3595.                 encpointrighty = tripletencpoint(1, 5)
  3596.                 encpointrightz = tripletencpoint(1, 6)
  3597.             END IF
  3598.             flagindexkused = 0
  3599.             ' First new triangle overwrites old one.
  3600.             basepointx = intleftx
  3601.             basepointy = intlefty
  3602.             basepointz = intleftz
  3603.             rightpointx = encpointleftx
  3604.             rightpointy = encpointlefty
  3605.             rightpointz = encpointleftz
  3606.             leftpointx = vertleftx
  3607.             leftpointy = vertlefty
  3608.             leftpointz = vertleftz
  3609.             GOSUB compute.triangle.areas.cents
  3610.             GOSUB create.image.triangle
  3611.             ' Second new triangle.
  3612.             basepointx = encpointleftx
  3613.             basepointy = encpointlefty
  3614.             basepointz = encpointleftz
  3615.             rightpointx = verttopx
  3616.             rightpointy = verttopy
  3617.             rightpointz = verttopz
  3618.             leftpointx = vertleftx
  3619.             leftpointy = vertlefty
  3620.             leftpointz = vertleftz
  3621.             GOSUB compute.triangle.areas.cents
  3622.             GOSUB create.image.triangle
  3623.             ' Third new triangle.
  3624.             basepointx = encpointrightx
  3625.             basepointy = encpointrighty
  3626.             basepointz = encpointrightz
  3627.             rightpointx = verttopx
  3628.             rightpointy = verttopy
  3629.             rightpointz = verttopz
  3630.             leftpointx = encpointleftx
  3631.             leftpointy = encpointlefty
  3632.             leftpointz = encpointleftz
  3633.             GOSUB compute.triangle.areas.cents
  3634.             GOSUB create.image.triangle
  3635.             ' Fourth new triangle.
  3636.             basepointx = vertrightx
  3637.             basepointy = vertrighty
  3638.             basepointz = vertrightz
  3639.             rightpointx = verttopx
  3640.             rightpointy = verttopy
  3641.             rightpointz = verttopz
  3642.             leftpointx = encpointrightx
  3643.             leftpointy = encpointrighty
  3644.             leftpointz = encpointrightz
  3645.             GOSUB compute.triangle.areas.cents
  3646.             GOSUB create.image.triangle
  3647.             ' Fifth new triangle.
  3648.             basepointx = vertrightx
  3649.             basepointy = vertrighty
  3650.             basepointz = vertrightz
  3651.             rightpointx = encpointrightx
  3652.             rightpointy = encpointrighty
  3653.             rightpointz = encpointrightz
  3654.             leftpointx = intrightx
  3655.             leftpointy = intrighty
  3656.             leftpointz = intrightz
  3657.             GOSUB compute.triangle.areas.cents
  3658.             GOSUB create.image.triangle
  3659.         END IF
  3660.         IF flagimagechange = 1 THEN
  3661.             IF flagindexkused = 1 THEN
  3662.                 GOTO begintripletsnipsubloop
  3663.             ELSE
  3664.                 GOSUB triplet.image.repack
  3665.             END IF
  3666.         END IF
  3667.  
  3668.     CASE " 1 2 2" '*' 11 of 15
  3669.         ' Load information on overlap triangle.
  3670.         int3ABCx = tripletencpoint(1, 1)
  3671.         int3ABCy = tripletencpoint(1, 2)
  3672.         int3ABCz = tripletencpoint(1, 3)
  3673.         int3DEFx = tripletencpoint(1, 4)
  3674.         int3DEFy = tripletencpoint(1, 5)
  3675.         int3DEFz = tripletencpoint(1, 6)
  3676.         int1ABCx = tripletintpointpair(1, 1)
  3677.         int1ABCy = tripletintpointpair(1, 2)
  3678.         int1ABCz = tripletintpointpair(1, 3)
  3679.         int1DEFx = tripletintpointpair(1, 4)
  3680.         int1DEFy = tripletintpointpair(1, 5)
  3681.         int1DEFz = tripletintpointpair(1, 6)
  3682.         int2ABCx = tripletintpointpair(2, 1)
  3683.         int2ABCy = tripletintpointpair(2, 2)
  3684.         int2ABCz = tripletintpointpair(2, 3)
  3685.         int2DEFx = tripletintpointpair(2, 4)
  3686.         int2DEFy = tripletintpointpair(2, 5)
  3687.         int2DEFz = tripletintpointpair(2, 6)
  3688.         GOSUB perform.overlap.calculations
  3689.         ' Compare the apparent overlap tringles using centroid.
  3690.         IF magcentABC > magcentDEF AND magdiff > 0 AND areaABC > 0.005 AND areaDEF > 0.005 AND snip122enabled = 1 THEN
  3691.             'LOCATE 11, 1: PRINT signaturefull$
  3692.             flagimagechange = 1
  3693.             candouterpoint1x = tripletintpointpair(1, 10)
  3694.             candouterpoint1y = tripletintpointpair(1, 11)
  3695.             candouterpoint1z = tripletintpointpair(1, 12)
  3696.             candouterpoint2x = tripletintpointpair(1, 13)
  3697.             candouterpoint2y = tripletintpointpair(1, 14)
  3698.             candouterpoint2z = tripletintpointpair(1, 15)
  3699.             IF SQR((candouterpoint1x - tripletencpoint(1, 1)) ^ 2 + (candouterpoint1y - tripletencpoint(1, 2)) ^ 2 + (candouterpoint1z - tripletencpoint(1, 3)) ^ 2) > 0.1 AND SQR((candouterpoint1x - tripletencpoint(2, 1)) ^ 2 + (candouterpoint1y - tripletencpoint(2, 2)) ^ 2 + (candouterpoint1z - tripletencpoint(2, 3)) ^ 2) > 0.1 THEN
  3700.                 outerpointx = candouterpoint1x
  3701.                 outerpointy = candouterpoint1y
  3702.                 outerpointz = candouterpoint1z
  3703.             ELSE
  3704.                 outerpointx = candouterpoint1x
  3705.                 outerpointy = candouterpoint1y
  3706.                 outerpointz = candouterpoint1z
  3707.             END IF
  3708.             flagindexkused = 0
  3709.             ' First new triangle overwrites old one.
  3710.             basepointx = int3DEFx
  3711.             basepointy = int3DEFy
  3712.             basepointz = int3DEFz
  3713.             rightpointx = outerpointx
  3714.             rightpointy = outerpointy
  3715.             rightpointz = outerpointz
  3716.             leftpointx = int1ABCx
  3717.             leftpointy = int1ABCy
  3718.             leftpointz = int1ABCz
  3719.             GOSUB compute.triangle.areas.cents
  3720.             GOSUB create.image.triangle
  3721.             ' Second new triangle.
  3722.             basepointx = int3DEFx
  3723.             basepointy = int3DEFy
  3724.             basepointz = int3DEFz
  3725.             rightpointx = outerpointx
  3726.             rightpointy = outerpointy
  3727.             rightpointz = outerpointz
  3728.             leftpointx = int2ABCx
  3729.             leftpointy = int2ABCy
  3730.             leftpointz = int2ABCz
  3731.             GOSUB compute.triangle.areas.cents
  3732.             GOSUB create.image.triangle
  3733.         END IF
  3734.         IF flagimagechange = 1 THEN
  3735.             IF flagindexkused = 1 THEN
  3736.                 GOTO begintripletsnipsubloop
  3737.             ELSE
  3738.                 GOSUB triplet.image.repack
  3739.             END IF
  3740.         END IF
  3741.     CASE " 2 1 2" '*' 12 of 15
  3742.         ' Load information on overlap triangle.
  3743.         int3ABCx = tripletencpoint(1, 4)
  3744.         int3ABCy = tripletencpoint(1, 5)
  3745.         int3ABCz = tripletencpoint(1, 6)
  3746.         int3DEFx = tripletencpoint(1, 1)
  3747.         int3DEFy = tripletencpoint(1, 2)
  3748.         int3DEFz = tripletencpoint(1, 3)
  3749.         int1ABCx = tripletintpointpair(1, 1)
  3750.         int1ABCy = tripletintpointpair(1, 2)
  3751.         int1ABCz = tripletintpointpair(1, 3)
  3752.         int1DEFx = tripletintpointpair(1, 4)
  3753.         int1DEFy = tripletintpointpair(1, 5)
  3754.         int1DEFz = tripletintpointpair(1, 6)
  3755.         int2ABCx = tripletintpointpair(2, 1)
  3756.         int2ABCy = tripletintpointpair(2, 2)
  3757.         int2ABCz = tripletintpointpair(2, 3)
  3758.         int2DEFx = tripletintpointpair(2, 4)
  3759.         int2DEFy = tripletintpointpair(2, 5)
  3760.         int2DEFz = tripletintpointpair(2, 6)
  3761.         GOSUB perform.overlap.calculations
  3762.         ' Compare the apparent overlap tringles using centroid.
  3763.         IF magcentABC > magcentDEF AND magdiff > 0 AND areaABC > 0.005 AND areaDEF > 0.005 AND snip212enabled = 1 THEN
  3764.             'LOCATE 12, 1: PRINT signaturefull$
  3765.             flagimagechange = 1
  3766.             outvert1x = tripletintpointpair(2, 7)
  3767.             outvert1y = tripletintpointpair(2, 8)
  3768.             outvert1z = tripletintpointpair(2, 9)
  3769.             outvert2x = tripletintpointpair(1, 7)
  3770.             outvert2y = tripletintpointpair(1, 8)
  3771.             outvert2z = tripletintpointpair(1, 9)
  3772.             IF SQR((tripletintpointpair(1, 16) - tripletencpoint(1, 1)) ^ 2 + (tripletintpointpair(1, 17) - tripletencpoint(1, 2)) ^ 2 + (tripletintpointpair(1, 18) - tripletencpoint(1, 3)) ^ 2) < 0.0001 OR SQR((tripletintpointpair(1, 19) - tripletencpoint(1, 1)) ^ 2 + (tripletintpointpair(1, 20) - tripletencpoint(1, 2)) ^ 2 + (tripletintpointpair(1, 21) - tripletencpoint(1, 3)) ^ 2) < 0.0001 THEN
  3773.                 encpoint1x = tripletencpoint(1, 4)
  3774.                 encpoint1y = tripletencpoint(1, 5)
  3775.                 encpoint1z = tripletencpoint(1, 6)
  3776.                 encpoint2x = tripletencpoint(2, 4)
  3777.                 encpoint2y = tripletencpoint(2, 5)
  3778.                 encpoint2z = tripletencpoint(2, 6)
  3779.             ELSE
  3780.                 encpoint1x = tripletencpoint(2, 4)
  3781.                 encpoint1y = tripletencpoint(2, 5)
  3782.                 encpoint1z = tripletencpoint(2, 6)
  3783.                 encpoint2x = tripletencpoint(1, 4)
  3784.                 encpoint2y = tripletencpoint(1, 5)
  3785.                 encpoint2z = tripletencpoint(1, 6)
  3786.             END IF
  3787.             flagindexkused = 0
  3788.             ' First new triangle overwrites old one.
  3789.             basepointx = outvert2x
  3790.             basepointy = outvert2y
  3791.             basepointz = outvert2z
  3792.             rightpointx = int2ABCx
  3793.             rightpointy = int2ABCy
  3794.             rightpointz = int2ABCz
  3795.             leftpointx = encpoint2x
  3796.             leftpointy = encpoint2y
  3797.             leftpointz = encpoint2z
  3798.             GOSUB compute.triangle.areas.cents
  3799.             GOSUB create.image.triangle
  3800.             ' Second new triangle.
  3801.             basepointx = outvert2x
  3802.             basepointy = outvert2y
  3803.             basepointz = outvert2z
  3804.             rightpointx = encpoint2x
  3805.             rightpointy = encpoint2y
  3806.             rightpointz = encpoint2z
  3807.             leftpointx = encpoint1x
  3808.             leftpointy = encpoint1y
  3809.             leftpointz = encpoint1z
  3810.             GOSUB compute.triangle.areas.cents
  3811.             GOSUB create.image.triangle
  3812.             ' Third new triangle.
  3813.             basepointx = outvert1x
  3814.             basepointy = outvert1y
  3815.             basepointz = outvert1z
  3816.             rightpointx = outvert2x
  3817.             rightpointy = outvert2y
  3818.             rightpointz = outvert2z
  3819.             leftpointx = encpoint1x
  3820.             leftpointy = encpoint1y
  3821.             leftpointz = encpoint1z
  3822.             GOSUB compute.triangle.areas.cents
  3823.             GOSUB create.image.triangle
  3824.             ' Fourth new triangle.
  3825.             basepointx = outvert1x
  3826.             basepointy = outvert1y
  3827.             basepointz = outvert1z
  3828.             rightpointx = encpoint1x
  3829.             rightpointy = encpoint1y
  3830.             rightpointz = encpoint1z
  3831.             leftpointx = int1ABCx
  3832.             leftpointy = int1ABCy
  3833.             leftpointz = int1ABCz
  3834.             GOSUB compute.triangle.areas.cents
  3835.             GOSUB create.image.triangle
  3836.         END IF
  3837.         IF flagimagechange = 1 THEN
  3838.             IF flagindexkused = 1 THEN
  3839.                 GOTO begintripletsnipsubloop
  3840.             ELSE
  3841.                 GOSUB triplet.image.repack
  3842.             END IF
  3843.         END IF
  3844.  
  3845.     CASE " 0 1 4" '*' 13 of 15
  3846.         ' Load information on overlap triangle.
  3847.         int3ABCx = tripletencpoint(1, 1)
  3848.         int3ABCy = tripletencpoint(1, 2)
  3849.         int3ABCz = tripletencpoint(1, 3)
  3850.         int3DEFx = tripletencpoint(1, 4)
  3851.         int3DEFy = tripletencpoint(1, 5)
  3852.         int3DEFz = tripletencpoint(1, 6)
  3853.         int1ABCx = tripletintpointpair(1, 1)
  3854.         int1ABCy = tripletintpointpair(1, 2)
  3855.         int1ABCz = tripletintpointpair(1, 3)
  3856.         int1DEFx = tripletintpointpair(1, 4)
  3857.         int1DEFy = tripletintpointpair(1, 5)
  3858.         int1DEFz = tripletintpointpair(1, 6)
  3859.         int2ABCx = tripletintpointpair(2, 1)
  3860.         int2ABCy = tripletintpointpair(2, 2)
  3861.         int2ABCz = tripletintpointpair(2, 3)
  3862.         int2DEFx = tripletintpointpair(2, 4)
  3863.         int2DEFy = tripletintpointpair(2, 5)
  3864.         int2DEFz = tripletintpointpair(2, 6)
  3865.         GOSUB perform.overlap.calculations
  3866.         ' Compare the apparent overlap tringles using centroid.
  3867.         IF magcentABC > magcentDEF AND magdiff > 0 AND areaABC > 0.005 AND areaDEF > 0.005 AND snip014enabled = 1 THEN
  3868.             'LOCATE 13, 1: PRINT signaturefull$
  3869.             flagimagechange = 1
  3870.             ' Identify the two triangles.
  3871.             leftedgefound = 0
  3872.             FOR f = 1 TO 4
  3873.                 IF SQR((tripletintpointpair(f, 7) - int3ABCx) ^ 2 + (tripletintpointpair(f, 8) - int3ABCy) ^ 2 + (tripletintpointpair(f, 9) - int3ABCz) ^ 2) > 0.1 THEN
  3874.                     possibleoutpoint1x = tripletintpointpair(f, 10)
  3875.                     possibleoutpoint1y = tripletintpointpair(f, 11)
  3876.                     possibleoutpoint1z = tripletintpointpair(f, 12)
  3877.                     possibleoutpoint2x = tripletintpointpair(f, 13)
  3878.                     possibleoutpoint2y = tripletintpointpair(f, 14)
  3879.                     possibleoutpoint2z = tripletintpointpair(f, 15)
  3880.                     intpointfwdx = tripletintpointpair(f, 1)
  3881.                     intpointfwdy = tripletintpointpair(f, 2)
  3882.                     intpointfwdz = tripletintpointpair(f, 3)
  3883.                     IF leftedgefound = 0 THEN
  3884.                         IF SQR((possibleoutpoint1x - int3ABCx) ^ 2 + (possibleoutpoint1y - int3ABCy) ^ 2 + (possibleoutpoint1z - int3ABCz) ^ 2) < 0.0001 THEN
  3885.                             outerpointleftx = possibleoutpoint2x
  3886.                             outerpointlefty = possibleoutpoint2y
  3887.                             outerpointleftz = possibleoutpoint2z
  3888.                             intpointfwdleftx = intpointfwdx
  3889.                             intpointfwdlefty = intpointfwdy
  3890.                             intpointfwdleftz = intpointfwdz
  3891.                         ELSE
  3892.                             outerpointleftx = possibleoutpoint1x
  3893.                             outerpointlefty = possibleoutpoint1y
  3894.                             outerpointleftz = possibleoutpoint1z
  3895.                             intpointfwdleftx = intpointfwdx
  3896.                             intpointfwdlefty = intpointfwdy
  3897.                             intpointfwdleftz = intpointfwdz
  3898.                         END IF
  3899.                         disttointpointmin = 10 ^ 5
  3900.                         FOR m = 1 TO 4
  3901.                             IF m <> W THEN
  3902.                                 IF SQR((tripletintpointpair(m, 7) - int3ABCx) ^ 2 + (tripletintpointpair(m, 8) - int3ABCy) ^ 2 + (tripletintpointpair(m, 9) - int3ABCz) ^ 2) < 0.0001 THEN
  3903.                                     disttointpoint = SQR((outerpointleftx - tripletintpointpair(m, 1)) ^ 2 + (outerpointlefty - tripletintpointpair(m, 2)) ^ 2 + (outerpointleftz - tripletintpointpair(m, 3)) ^ 2)
  3904.                                     IF disttointpoint < disttointpointmin THEN
  3905.                                         intpointbackleftx = tripletintpointpair(m, 1)
  3906.                                         intpointbacklefty = tripletintpointpair(m, 2)
  3907.                                         intpointbackleftz = tripletintpointpair(m, 3)
  3908.                                         disttointpointmin = disttointpoint
  3909.                                     END IF
  3910.  
  3911.                                 END IF
  3912.                             END IF
  3913.                         NEXT
  3914.                         leftedgefound = 1
  3915.                     ELSE
  3916.                         IF SQR((possibleoutpoint1x - int3ABCx) ^ 2 + (possibleoutpoint1y - int3ABCy) ^ 2 + (possibleoutpoint1z - int3ABCz) ^ 2) < 0.0001 THEN
  3917.                             outerpointrightx = possibleoutpoint2x
  3918.                             outerpointrighty = possibleoutpoint2y
  3919.                             outerpointrightz = possibleoutpoint2z
  3920.                             intpointfwdrightx = intpointfwdx
  3921.                             intpointfwdrighty = intpointfwdy
  3922.                             intpointfwdrightz = intpointfwdz
  3923.                         ELSE
  3924.                             outerpointrightx = possibleoutpoint1x
  3925.                             outerpointrighty = possibleoutpoint1y
  3926.                             outerpointrightz = possibleoutpoint1z
  3927.                             intpointfwdrightx = intpointfwdx
  3928.                             intpointfwdrighty = intpointfwdy
  3929.                             intpointfwdrightz = intpointfwdz
  3930.                         END IF
  3931.                         disttointpointmin = 10 ^ 5
  3932.                         FOR m = 1 TO 4
  3933.                             IF m <> W THEN
  3934.                                 IF SQR((tripletintpointpair(m, 7) - int3ABCx) ^ 2 + (tripletintpointpair(m, 8) - int3ABCy) ^ 2 + (tripletintpointpair(m, 9) - int3ABCz) ^ 2) < 0.0001 THEN
  3935.                                     disttointpoint = SQR((outerpointrightx - tripletintpointpair(m, 1)) ^ 2 + (outerpointrighty - tripletintpointpair(m, 2)) ^ 2 + (outerpointrightz - tripletintpointpair(m, 3)) ^ 2)
  3936.                                     IF disttointpoint < disttointpointmin THEN
  3937.                                         intpointbackrightx = tripletintpointpair(m, 1)
  3938.                                         intpointbackrighty = tripletintpointpair(m, 2)
  3939.                                         intpointbackrightz = tripletintpointpair(m, 3)
  3940.                                         disttointpointmin = disttointpoint
  3941.                                     END IF
  3942.                                 END IF
  3943.                             END IF
  3944.                         NEXT
  3945.                     END IF
  3946.                 END IF
  3947.             NEXT
  3948.             flagindexkused = 0
  3949.             ' First new triangle overwrites old one.
  3950.             basepointx = outerpointrightx
  3951.             basepointy = outerpointrighty
  3952.             basepointz = outerpointrightz
  3953.             rightpointx = intpointfwdrightx
  3954.             rightpointy = intpointfwdrighty
  3955.             rightpointz = intpointfwdrightz
  3956.             leftpointx = intpointbackrightx
  3957.             leftpointy = intpointbackrighty
  3958.             leftpointz = intpointbackrightz
  3959.             GOSUB compute.triangle.areas.cents
  3960.             GOSUB create.image.triangle
  3961.             ' Second new triangle.
  3962.             basepointx = outerpointleftx
  3963.             basepointy = outerpointlefty
  3964.             basepointz = outerpointleftz
  3965.             rightpointx = intpointbackleftx
  3966.             rightpointy = intpointbacklefty
  3967.             rightpointz = intpointbackleftz
  3968.             leftpointx = intpointfwdleftx
  3969.             leftpointy = intpointfwdlefty
  3970.             leftpointz = intpointfwdleftz
  3971.             GOSUB compute.triangle.areas.cents
  3972.             GOSUB create.image.triangle
  3973.         END IF
  3974.         IF flagimagechange = 1 THEN
  3975.             IF flagindexkused = 1 THEN
  3976.                 GOTO begintripletsnipsubloop
  3977.             ELSE
  3978.                 GOSUB triplet.image.repack
  3979.             END IF
  3980.         END IF
  3981.  
  3982.     CASE " 1 0 4" '*' 14 of 15
  3983.         int3ABCx = tripletintpointpair(3, 1)
  3984.         int3ABCy = tripletintpointpair(3, 2)
  3985.         int3ABCz = tripletintpointpair(3, 3)
  3986.         int3DEFx = tripletintpointpair(3, 4)
  3987.         int3DEFy = tripletintpointpair(3, 5)
  3988.         int3DEFz = tripletintpointpair(3, 6)
  3989.         int1ABCx = tripletintpointpair(1, 1)
  3990.         int1ABCy = tripletintpointpair(1, 2)
  3991.         int1ABCz = tripletintpointpair(1, 3)
  3992.         int1DEFx = tripletintpointpair(1, 4)
  3993.         int1DEFy = tripletintpointpair(1, 5)
  3994.         int1DEFz = tripletintpointpair(1, 6)
  3995.         int2ABCx = tripletintpointpair(2, 1)
  3996.         int2ABCy = tripletintpointpair(2, 2)
  3997.         int2ABCz = tripletintpointpair(2, 3)
  3998.         int2DEFx = tripletintpointpair(2, 4)
  3999.         int2DEFy = tripletintpointpair(2, 5)
  4000.         int2DEFz = tripletintpointpair(2, 6)
  4001.         GOSUB perform.overlap.calculations
  4002.         ' Compare the apparent overlap tringles using centroid.
  4003.         IF magcentABC > magcentDEF AND magdiff > 0 AND areaABC > 0.005 AND areaDEF > 0.005 AND snip104enabled = 1 THEN
  4004.             'LOCATE 14, 1: PRINT signaturefull$
  4005.             flagimagechange = 1
  4006.             ''intpointbackleftused = 0
  4007.             ''FOR m = 1 TO 4
  4008.             ''    IF SQR((tripletintpointpair(m, 16) - tripletencpoint(1, 1)) ^ 2 + (tripletintpointpair(m, 17) - tripletencpoint(1, 2)) ^ 2 + (tripletintpointpair(m, 18) - tripletencpoint(1, 3)) ^ 2) > 0.1 AND SQR((tripletintpointpair(m, 19) - tripletencpoint(1, 1)) ^ 2 + (tripletintpointpair(m, 20) - tripletencpoint(1, 2)) ^ 2 + (tripletintpointpair(m, 21) - tripletencpoint(1, 3)) ^ 2) > 0.1 THEN
  4009.             ''        IF intpointbackleftused = 0 THEN
  4010.             ''            intpointbackleftx = tripletintpointpair(m, 1)
  4011.             ''            intpointbacklefty = tripletintpointpair(m, 2)
  4012.             ''            intpointbackleftz = tripletintpointpair(m, 3)
  4013.             ''            backleftindex = m
  4014.             ''            intpointbackleftused = 1
  4015.             ''        ELSE
  4016.             ''            intpointbackrightx = tripletintpointpair(m, 1)
  4017.             ''            intpointbackrighty = tripletintpointpair(m, 2)
  4018.             ''            intpointbackrightz = tripletintpointpair(m, 3)
  4019.             ''            backrightindex = m
  4020.             ''        END IF
  4021.             ''    END IF
  4022.             ''NEXT
  4023.             ''cand1x = tripletintpointpair(backleftindex, 10)
  4024.             ''cand1y = tripletintpointpair(backleftindex, 11)
  4025.             ''cand1z = tripletintpointpair(backleftindex, 12)
  4026.             ''cand2x = tripletintpointpair(backleftindex, 13)
  4027.             ''cand2y = tripletintpointpair(backleftindex, 14)
  4028.             ''cand2z = tripletintpointpair(backleftindex, 15)
  4029.             ''cand3x = tripletintpointpair(backrightindex, 10)
  4030.             ''cand3y = tripletintpointpair(backrightindex, 11)
  4031.             ''cand3z = tripletintpointpair(backrightindex, 12)
  4032.             ''cand4x = tripletintpointpair(backrightindex, 13)
  4033.             ''cand4y = tripletintpointpair(backrightindex, 14)
  4034.             ''cand4z = tripletintpointpair(backrightindex, 15)
  4035.             ''diff13 = SQR((cand1x - cand3x) ^ 2 + (cand1y - cand3y) ^ 2 + (cand1z - cand3z) ^ 2)
  4036.             ''diff14 = SQR((cand1x - cand4x) ^ 2 + (cand1y - cand4y) ^ 2 + (cand1z - cand4z) ^ 2)
  4037.             ''diff23 = SQR((cand2x - cand3x) ^ 2 + (cand2y - cand3y) ^ 2 + (cand2z - cand3z) ^ 2)
  4038.             ''diff24 = SQR((cand2x - cand4x) ^ 2 + (cand2y - cand4y) ^ 2 + (cand2z - cand4z) ^ 2)
  4039.             ''IF diff13 < 0.0001 THEN
  4040.             ''    pointbackoutx = cand1x
  4041.             ''    pointbackouty = cand1y
  4042.             ''    pointbackoutz = cand1z
  4043.             ''    pointfwdoutleftx = cand2x
  4044.             ''    pointfwdoutlefty = cand2y
  4045.             ''    pointfwdoutleftz = cand2z
  4046.             ''    pointfwdoutrightx = cand4x
  4047.             ''    pointfwdoutrighty = cand4y
  4048.             ''    pointfwdoutrightz = cand4z
  4049.             ''END IF
  4050.             ''IF diff14 < 0.0001 THEN
  4051.             ''    pointbackoutx = cand1x
  4052.             ''    pointbackouty = cand1y
  4053.             ''    pointbackoutz = cand1z
  4054.             ''    pointfwdoutleftx = cand2x
  4055.             ''    pointfwdoutlefty = cand2y
  4056.             ''    pointfwdoutleftz = cand2z
  4057.             ''    pointfwdoutrightx = cand3x
  4058.             ''    pointfwdoutrighty = cand3y
  4059.             ''    pointfwdoutrightz = cand3z
  4060.             ''END IF
  4061.             ''IF diff23 < 0.0001 THEN
  4062.             ''    pointbackoutx = cand2x
  4063.             ''    pointbackouty = cand2y
  4064.             ''    pointbackoutz = cand2z
  4065.             ''    pointfwdoutleftx = cand1x
  4066.             ''    pointfwdoutlefty = cand1y
  4067.             ''    pointfwdoutleftz = cand1z
  4068.             ''    pointfwdoutrightx = cand4x
  4069.             ''    pointfwdoutrighty = cand4y
  4070.             ''    pointfwdoutrightz = cand4z
  4071.             ''END IF
  4072.             ''IF diff24 < 0.0001 THEN
  4073.             ''    pointbackoutx = cand2x
  4074.             ''    pointbackouty = cand2y
  4075.             ''    pointbackoutz = cand2z
  4076.             ''    pointfwdoutleftx = cand1x
  4077.             ''    pointfwdoutlefty = cand1y
  4078.             ''    pointfwdoutleftz = cand1z
  4079.             ''    pointfwdoutrightx = cand3x
  4080.             ''    pointfwdoutrighty = cand3y
  4081.             ''    pointfwdoutrightz = cand3z
  4082.             ''END IF
  4083.             ''FOR m = 1 TO 4
  4084.             ''    IF SQR((tripletintpointpair(m, 16) - tripletencpoint(1, 1)) ^ 2 + (tripletintpointpair(m, 17) - tripletencpoint(1, 2)) ^ 2 + (tripletintpointpair(m, 18) - tripletencpoint(1, 3)) ^ 2) < 0.0001 OR SQR((tripletintpointpair(m, 19) - tripletencpoint(1, 1)) ^ 2 + (tripletintpointpair(m, 20) - tripletencpoint(1, 2)) ^ 2 + (tripletintpointpair(m, 21) - tripletencpoint(1, 3)) ^ 2) < 0.0001 THEN
  4085.             ''        IF SQR((tripletintpointpair(m, 7) - tripletintpointpair(backleftindex, 7)) ^ 2 + (tripletintpointpair(m, 8) - tripletintpointpair(backleftindex, 8)) ^ 2 + (tripletintpointpair(m, 9) - tripletintpointpair(backleftindex, 9)) ^ 2) < 0.0001 THEN
  4086.             ''            intpointfwdleftx = tripletintpointpair(m, 1)
  4087.             ''            intpointfwdlefty = tripletintpointpair(m, 2)
  4088.             ''            intpointfwdleftz = tripletintpointpair(m, 3)
  4089.             ''        END IF
  4090.             ''        IF SQR((tripletintpointpair(m, 7) - tripletintpointpair(backrightindex, 7)) ^ 2 + (tripletintpointpair(m, 8) - tripletintpointpair(backrightindex, 8)) ^ 2 + (tripletintpointpair(m, 9) - tripletintpointpair(backrightindex, 9)) ^ 2) < 0.0001 THEN
  4091.             ''            intpointfwdrightx = tripletintpointpair(m, 1)
  4092.             ''            intpointfwdrighty = tripletintpointpair(m, 2)
  4093.             ''            intpointfwdrightz = tripletintpointpair(m, 3)
  4094.             ''        END IF
  4095.             ''    END IF
  4096.             ''NEXT
  4097.             ''flagindexkused = 0
  4098.             ''' First new triangle overwrites old one.
  4099.             ''basepointx = pointbackoutx
  4100.             ''basepointy = pointbackouty
  4101.             ''basepointz = pointbackoutz
  4102.             ''rightpointx = intpointbackrightx
  4103.             ''rightpointy = intpointbackrighty
  4104.             ''rightpointz = intpointbackrightz
  4105.             ''leftpointx = intpointbackleftx
  4106.             ''leftpointy = intpointbacklefty
  4107.             ''leftpointz = intpointbackleftz
  4108.             ''GOSUB compute.triangle.areas.cents
  4109.             ''GOSUB create.image.triangle
  4110.             ''' Second new triangle.
  4111.             ''basepointx = intpointfwdleftx
  4112.             ''basepointy = intpointfwdlefty
  4113.             ''basepointz = intpointfwdleftz
  4114.             ''rightpointx = tripletencpoint(1, 4)
  4115.             ''rightpointy = tripletencpoint(1, 5)
  4116.             ''rightpointz = tripletencpoint(1, 6)
  4117.             ''leftpointx = pointfwdoutleftx
  4118.             ''leftpointy = pointfwdoutlefty
  4119.             ''leftpointz = pointfwdoutleftz
  4120.             ''GOSUB compute.triangle.areas.cents
  4121.             ''GOSUB create.image.triangle
  4122.             ''' Third new triangle.
  4123.             ''basepointx = tripletencpoint(1, 4)
  4124.             ''basepointy = tripletencpoint(1, 5)
  4125.             ''basepointz = tripletencpoint(1, 6)
  4126.             ''rightpointx = pointfwdoutrightx
  4127.             ''rightpointy = pointfwdoutrighty
  4128.             ''rightpointz = pointfwdoutrightz
  4129.             ''leftpointx = pointfwdoutleftx
  4130.             ''leftpointy = pointfwdoutlefty
  4131.             ''leftpointz = pointfwdoutleftz
  4132.             ''GOSUB compute.triangle.areas.cents
  4133.             ''GOSUB create.image.triangle
  4134.             ''' Fourth new triangle.
  4135.             ''basepointx = tripletencpoint(1, 4)
  4136.             ''basepointy = tripletencpoint(1, 5)
  4137.             ''basepointz = tripletencpoint(1, 6)
  4138.             ''rightpointx = intpointfwdrightx
  4139.             ''rightpointy = intpointfwdrighty
  4140.             ''rightpointz = intpointfwdrightz
  4141.             ''leftpointx = pointfwdoutrightx
  4142.             ''leftpointy = pointfwdoutrighty
  4143.             ''leftpointz = pointfwdoutrightz
  4144.             ''GOSUB compute.triangle.areas.cents
  4145.             ''GOSUB create.image.triangle
  4146.             centsharedx = (1 / 3) * (int1ABCx + int2ABCx + int3ABCx)
  4147.             centsharedy = (1 / 3) * (int1ABCy + int2ABCy + int3ABCy)
  4148.             centsharedz = (1 / 3) * (int1ABCz + int2ABCz + int3ABCz)
  4149.             flagindexkused = 0
  4150.             ' First new triangle overwrites old one.
  4151.             basepointx = centsharedx
  4152.             basepointy = centsharedy
  4153.             basepointz = centsharedz
  4154.             rightpointx = Ax
  4155.             rightpointy = Ay
  4156.             rightpointz = Az
  4157.             leftpointx = Bx
  4158.             leftpointy = By
  4159.             leftpointz = Bz
  4160.             GOSUB compute.triangle.areas.cents
  4161.             GOSUB create.image.triangle
  4162.             ' Second new triangle.
  4163.             basepointx = centsharedx
  4164.             basepointy = centsharedy
  4165.             basepointz = centsharedz
  4166.             rightpointx = Bx
  4167.             rightpointy = By
  4168.             rightpointz = Bz
  4169.             leftpointx = Cx
  4170.             leftpointy = Cy
  4171.             leftpointz = Cz
  4172.             GOSUB compute.triangle.areas.cents
  4173.             GOSUB create.image.triangle
  4174.             ' Third new triangle.
  4175.             basepointx = centsharedx
  4176.             basepointy = centsharedy
  4177.             basepointz = centsharedz
  4178.             rightpointx = Cx
  4179.             rightpointy = Cy
  4180.             rightpointz = Cz
  4181.             leftpointx = Ax
  4182.             leftpointy = Ay
  4183.             leftpointz = Az
  4184.             GOSUB compute.triangle.areas.cents
  4185.             GOSUB create.image.triangle
  4186.         END IF
  4187.         IF flagimagechange = 1 THEN
  4188.             IF flagindexkused = 1 THEN
  4189.                 GOTO begintripletsnipsubloop
  4190.             ELSE
  4191.                 GOSUB triplet.image.repack
  4192.             END IF
  4193.         END IF
  4194.  
  4195.     CASE " 1 1 4" '*' 15 of 15
  4196.         ' Load information on overlap triangle.
  4197.         int3ABCx = tripletencpoint(1, 1)
  4198.         int3ABCy = tripletencpoint(1, 2)
  4199.         int3ABCz = tripletencpoint(1, 3)
  4200.         int3DEFx = tripletencpoint(1, 4)
  4201.         int3DEFy = tripletencpoint(1, 5)
  4202.         int3DEFz = tripletencpoint(1, 6)
  4203.         int1ABCx = tripletintpointpair(1, 1)
  4204.         int1ABCy = tripletintpointpair(1, 2)
  4205.         int1ABCz = tripletintpointpair(1, 3)
  4206.         int1DEFx = tripletintpointpair(1, 4)
  4207.         int1DEFy = tripletintpointpair(1, 5)
  4208.         int1DEFz = tripletintpointpair(1, 6)
  4209.         int2ABCx = tripletintpointpair(2, 1)
  4210.         int2ABCy = tripletintpointpair(2, 2)
  4211.         int2ABCz = tripletintpointpair(2, 3)
  4212.         int2DEFx = tripletintpointpair(2, 4)
  4213.         int2DEFy = tripletintpointpair(2, 5)
  4214.         int2DEFz = tripletintpointpair(2, 6)
  4215.         GOSUB perform.overlap.calculations
  4216.         ' Compare the apparent overlap tringles using centroid.
  4217.         IF magcentABC > magcentDEF AND magdiff > 0 AND areaABC > 0.005 AND areaDEF > 0.005 AND snip114enabled = 1 THEN
  4218.             'LOCATE 15, 1: PRINT signaturefull$
  4219.             flagimagechange = 1
  4220.             ' Identify the left int points.
  4221.             FOR m = 1 TO 4
  4222.                 IF SQR((tripletintpointpair(m, 7) - tripletencpoint(2, 1)) ^ 2 + (tripletintpointpair(m, 8) - tripletencpoint(2, 2)) ^ 2 + (tripletintpointpair(m, 9) - tripletencpoint(2, 3)) ^ 2) > 0.1 THEN
  4223.                     IF SQR((tripletintpointpair(m, 16) - tripletencpoint(1, 1)) ^ 2 + (tripletintpointpair(m, 17) - tripletencpoint(1, 2)) ^ 2 + (tripletintpointpair(m, 18) - tripletencpoint(1, 3)) ^ 2) < 0.0001 OR SQR((tripletintpointpair(m, 19) - tripletencpoint(1, 1)) ^ 2 + (tripletintpointpair(m, 20) - tripletencpoint(1, 2)) ^ 2 + (tripletintpointpair(m, 21) - tripletencpoint(1, 3)) ^ 2) < 0.0001 THEN
  4224.                         intpointfwdleftx = tripletintpointpair(m, 1)
  4225.                         intpointfwdlefty = tripletintpointpair(m, 2)
  4226.                         intpointfwdleftz = tripletintpointpair(m, 3)
  4227.                         IF SQR((tripletintpointpair(m, 10) - tripletencpoint(2, 1)) ^ 2 + (tripletintpointpair(m, 11) - tripletencpoint(2, 2)) ^ 2 + (tripletintpointpair(m, 12) - tripletencpoint(2, 3)) ^ 2) < 0.0001 THEN
  4228.                             intpointfwdoutx = tripletintpointpair(m, 13)
  4229.                             intpointfwdouty = tripletintpointpair(m, 14)
  4230.                             intpointfwdoutz = tripletintpointpair(m, 15)
  4231.                         ELSE
  4232.                             intpointfwdoutx = tripletintpointpair(m, 10)
  4233.                             intpointfwdouty = tripletintpointpair(m, 11)
  4234.                             intpointfwdoutz = tripletintpointpair(m, 12)
  4235.                         END IF
  4236.                     ELSE
  4237.                         intpointbackleftx = tripletintpointpair(m, 1)
  4238.                         intpointbacklefty = tripletintpointpair(m, 2)
  4239.                         intpointbackleftz = tripletintpointpair(m, 3)
  4240.                         IF SQR((tripletintpointpair(m, 10) - tripletencpoint(2, 1)) ^ 2 + (tripletintpointpair(m, 11) - tripletencpoint(2, 2)) ^ 2 + (tripletintpointpair(m, 12) - tripletencpoint(2, 3)) ^ 2) < 0.0001 THEN
  4241.                             intpointbackoutx = tripletintpointpair(m, 13)
  4242.                             intpointbackouty = tripletintpointpair(m, 14)
  4243.                             intpointbackoutz = tripletintpointpair(m, 15)
  4244.                         ELSE
  4245.                             intpointbackoutx = tripletintpointpair(m, 10)
  4246.                             intpointbackouty = tripletintpointpair(m, 11)
  4247.                             intpointbackoutz = tripletintpointpair(m, 12)
  4248.                         END IF
  4249.                     END IF
  4250.                 ELSE
  4251.                     IF SQR((tripletintpointpair(m, 16) - tripletencpoint(1, 1)) ^ 2 + (tripletintpointpair(m, 17) - tripletencpoint(1, 2)) ^ 2 + (tripletintpointpair(m, 18) - tripletencpoint(1, 3)) ^ 2) < 0.0001 OR SQR((tripletintpointpair(m, 19) - tripletencpoint(1, 1)) ^ 2 + (tripletintpointpair(m, 20) - tripletencpoint(1, 2)) ^ 2 + (tripletintpointpair(m, 21) - tripletencpoint(1, 3)) ^ 2) < 0.0001 THEN
  4252.                         intpointfwdrightx = tripletintpointpair(m, 1)
  4253.                         intpointfwdrighty = tripletintpointpair(m, 2)
  4254.                         intpointfwdrightz = tripletintpointpair(m, 3)
  4255.                     END IF
  4256.                     IF SQR((tripletintpointpair(m, 16) - tripletencpoint(1, 1)) ^ 2 + (tripletintpointpair(m, 17) - tripletencpoint(1, 2)) ^ 2 + (tripletintpointpair(m, 18) - tripletencpoint(1, 3)) ^ 2) > 0.1 AND SQR((tripletintpointpair(m, 19) - tripletencpoint(1, 1)) ^ 2 + (tripletintpointpair(m, 20) - tripletencpoint(1, 2)) ^ 2 + (tripletintpointpair(m, 21) - tripletencpoint(1, 3)) ^ 2) > 0.1 THEN
  4257.                         intpointbackrightx = tripletintpointpair(m, 1)
  4258.                         intpointbackrighty = tripletintpointpair(m, 2)
  4259.                         intpointbackrightz = tripletintpointpair(m, 3)
  4260.                     END IF
  4261.                 END IF
  4262.             NEXT
  4263.             flagindexkused = 0
  4264.             ' First new triangle overwrites old one.
  4265.             basepointx = tripletencpoint(1, 4)
  4266.             basepointy = tripletencpoint(1, 5)
  4267.             basepointz = tripletencpoint(1, 6)
  4268.             rightpointx = intpointfwdoutx
  4269.             rightpointy = intpointfwdouty
  4270.             rightpointz = intpointfwdoutz
  4271.             leftpointx = intpointfwdleftx
  4272.             leftpointy = intpointfwdlefty
  4273.             leftpointz = intpointfwdleftz
  4274.             GOSUB compute.triangle.areas.cents
  4275.             GOSUB create.image.triangle
  4276.             ' Second new triangle.
  4277.             basepointx = intpointfwdrightx
  4278.             basepointy = intpointfwdrighty
  4279.             basepointz = intpointfwdrightz
  4280.             rightpointx = intpointfwdoutx
  4281.             rightpointy = intpointfwdouty
  4282.             rightpointz = intpointfwdoutz
  4283.             leftpointx = tripletencpoint(1, 4)
  4284.             leftpointy = tripletencpoint(1, 5)
  4285.             leftpointz = tripletencpoint(1, 6)
  4286.             GOSUB compute.triangle.areas.cents
  4287.             GOSUB create.image.triangle
  4288.             ' Third new triangle.
  4289.             basepointx = intpointbackoutx
  4290.             basepointy = intpointbackouty
  4291.             basepointz = intpointbackoutz
  4292.             rightpointx = intpointbackrightx
  4293.             rightpointy = intpointbackrighty
  4294.             rightpointz = intpointbackrightz
  4295.             leftpointx = intpointbackleftx
  4296.             leftpointy = intpointbacklefty
  4297.             leftpointz = intpointbackleftz
  4298.             GOSUB compute.triangle.areas.cents
  4299.             GOSUB create.image.triangle
  4300.         END IF
  4301.         IF flagimagechange = 1 THEN
  4302.             IF flagindexkused = 1 THEN
  4303.                 GOTO begintripletsnipsubloop
  4304.             ELSE
  4305.                 GOSUB triplet.image.repack
  4306.             END IF
  4307.         END IF
  4308.  
  4309.     CASE ELSE
  4310.         ' Code for troubleshooting.
  4311.         'LOCATE 16, 1: PRINT "else"
  4312.         'rdy = INT(RND * 9)
  4313.         'IF i = 1 AND j = 3 THEN COLOR 4
  4314.         'LOCATE 17 + rdy, 1: PRINT signaturefull$
  4315.         'COLOR 15
  4316.  
  4317. compute.triangle.areas.cents:
  4318. rightarmx = rightpointx - basepointx
  4319. rightarmy = rightpointy - basepointy
  4320. rightarmz = rightpointz - basepointz
  4321. leftarmx = leftpointx - basepointx
  4322. leftarmy = leftpointy - basepointy
  4323. leftarmz = leftpointz - basepointz
  4324. trianglearea3Dvecx = rightarmy * leftarmz - rightarmz * leftarmy
  4325. trianglearea3Dvecy = rightarmz * leftarmx - rightarmx * leftarmz
  4326. trianglearea3Dvecz = rightarmx * leftarmy - rightarmy * leftarmx
  4327. trianglearea3D = (1 / 2) * (SQR(trianglearea3Dvecx ^ 2 + trianglearea3Dvecy ^ 2 + trianglearea3Dvecz ^ 2))
  4328. trianglecent3Dx = (1 / 3) * (basepointx + rightpointx + leftpointx)
  4329. trianglecent3Dy = (1 / 3) * (basepointy + rightpointy + leftpointy)
  4330. trianglecent3Dz = (1 / 3) * (basepointz + rightpointz + leftpointz)
  4331. trianglecent3Dmag = SQR(trianglecent3Dx ^ 2 + trianglecent3Dy ^ 2 + trianglecent3Dz ^ 2)
  4332. baseu = basepointx * uhat(1) + basepointy * uhat(2) + basepointz * uhat(3)
  4333. basev = basepointx * vhat(1) + basepointy * vhat(2) + basepointz * vhat(3)
  4334. rightu = rightpointx * uhat(1) + rightpointy * uhat(2) + rightpointz * uhat(3)
  4335. rightv = rightpointx * vhat(1) + rightpointy * vhat(2) + rightpointz * vhat(3)
  4336. leftu = leftpointx * uhat(1) + leftpointy * uhat(2) + leftpointz * uhat(3)
  4337. leftv = leftpointx * vhat(1) + leftpointy * vhat(2) + leftpointz * vhat(3)
  4338. basen = (basepointx * nhat(1) + basepointy * nhat(2) + basepointz * nhat(3))
  4339. rightn = (rightpointx * nhat(1) + rightpointy * nhat(2) + rightpointz * nhat(3))
  4340. leftn = (leftpointx * nhat(1) + leftpointy * nhat(2) + leftpointz * nhat(3))
  4341. basesu = baseu * fovd / basen
  4342. basesv = basev * fovd / basen
  4343. rightsu = rightu * fovd / rightn
  4344. rightsv = rightv * fovd / rightn
  4345. leftsu = leftu * fovd / leftn
  4346. leftsv = leftv * fovd / leftn
  4347. rightarmsu = rightsu - basesu
  4348. rightarmsv = rightsv - basesv
  4349. leftarmsu = leftsu - basesu
  4350. leftarmsv = leftsv - basesv
  4351. trianglearea2Dsvecncomp = rightarmsu * leftarmsv - rightarmsv * leftarmsu
  4352. trianglearea2Ds = (1 / 2) * (SQR(trianglearea2Dsvecncomp ^ 2))
  4353. trianglecent2Dsu = (1 / 3) * (basesu + rightsu + leftsu)
  4354. trianglecent2Dsv = (1 / 3) * (basesv + rightsv + leftsv)
  4355. trianglecent2Dmag = SQR(trianglecent2Dsu ^ 2 + trianglecent2Dsv ^ 2)
  4356.  
  4357. perform.overlap.calculations:
  4358. basepointx = int3ABCx
  4359. basepointy = int3ABCy
  4360. basepointz = int3ABCz
  4361. rightpointx = int1ABCx
  4362. rightpointy = int1ABCy
  4363. rightpointz = int1ABCz
  4364. leftpointx = int2ABCx
  4365. leftpointy = int2ABCy
  4366. leftpointz = int2ABCz
  4367. GOSUB compute.triangle.areas.cents
  4368. areaABC = trianglearea3D
  4369. magcentABC = trianglecent3Dmag
  4370. basepointx = int3DEFx
  4371. basepointy = int3DEFy
  4372. basepointz = int3DEFz
  4373. rightpointx = int1DEFx
  4374. rightpointy = int1DEFy
  4375. rightpointz = int1DEFz
  4376. leftpointx = int2DEFx
  4377. leftpointy = int2DEFy
  4378. leftpointz = int2DEFz
  4379. GOSUB compute.triangle.areas.cents
  4380. areaDEF = trianglearea3D
  4381. magcentDEF = trianglecent3Dmag
  4382. magdiff = SQR((magcentABC - magcentDEF) ^ 2)
  4383.  
  4384. create.image.triangle:
  4385. IF trianglearea3D > 0 AND trianglearea2Ds > 0 THEN
  4386.     IF flagindexkused = 0 THEN
  4387.         imageindex = k
  4388.         flagindexkused = 1
  4389.     ELSE
  4390.         pcounttripletsnipimage = pcounttripletsnipimage + 1
  4391.         imageindex = pcounttripletsnipimage
  4392.     END IF
  4393.     ' Code for troubleshooting.
  4394.     'shrinkfactor = .90
  4395.     'centimagex = (1 / 3) * (basepointx + rightpointx + leftpointx)
  4396.     'centimagey = (1 / 3) * (basepointy + rightpointy + leftpointy)
  4397.     'centimagez = (1 / 3) * (basepointz + rightpointz + leftpointz)
  4398.     'basepointx = centimagex + (shrinkfactor) * (basepointx - centimagex)
  4399.     'basepointy = centimagey + (shrinkfactor) * (basepointy - centimagey)
  4400.     'basepointz = centimagez + (shrinkfactor) * (basepointz - centimagez)
  4401.     'rightpointx = centimagex + (shrinkfactor) * (rightpointx - centimagex)
  4402.     'rightpointy = centimagey + (shrinkfactor) * (rightpointy - centimagey)
  4403.     'rightpointz = centimagez + (shrinkfactor) * (rightpointz - centimagez)
  4404.     'leftpointx = centimagex + (shrinkfactor) * (leftpointx - centimagex)
  4405.     'leftpointy = centimagey + (shrinkfactor) * (leftpointy - centimagey)
  4406.     'leftpointz = centimagez + (shrinkfactor) * (leftpointz - centimagez)
  4407.     tripletsnipimage(imageindex, 1) = basepointx
  4408.     tripletsnipimage(imageindex, 2) = basepointy
  4409.     tripletsnipimage(imageindex, 3) = basepointz
  4410.     tripletsnipimage(imageindex, 4) = rightpointx
  4411.     tripletsnipimage(imageindex, 5) = rightpointy
  4412.     tripletsnipimage(imageindex, 6) = rightpointz
  4413.     tripletsnipimage(imageindex, 7) = leftpointx
  4414.     tripletsnipimage(imageindex, 8) = leftpointy
  4415.     tripletsnipimage(imageindex, 9) = leftpointz
  4416.     tripletsnipimage(imageindex, 10) = tripletsnip(i, 10)
  4417.  
  4418. copy.triplets.snip.final:
  4419. FOR i = 1 TO numtripletsnip
  4420.     tripletfinal(i, 1) = tripletsnip(i, 1)
  4421.     tripletfinal(i, 2) = tripletsnip(i, 2)
  4422.     tripletfinal(i, 3) = tripletsnip(i, 3)
  4423.     tripletfinal(i, 4) = tripletsnip(i, 4)
  4424.     tripletfinal(i, 5) = tripletsnip(i, 5)
  4425.     tripletfinal(i, 6) = tripletsnip(i, 6)
  4426.     tripletfinal(i, 7) = tripletsnip(i, 7)
  4427.     tripletfinal(i, 8) = tripletsnip(i, 8)
  4428.     tripletfinal(i, 9) = tripletsnip(i, 9)
  4429.     tripletfinal(i, 10) = tripletsnip(i, 10)
  4430. numtripletfinal = numtripletsnip
  4431.  
  4432. triplet.image.repack:
  4433. pcountimagerepack = 0
  4434. FOR m = 1 TO pcounttripletsnipimage
  4435.     IF m <> k THEN
  4436.         pcountimagerepack = pcountimagerepack + 1
  4437.         tripletsnipimage(pcountimagerepack, 1) = tripletsnipimage(m, 1)
  4438.         tripletsnipimage(pcountimagerepack, 2) = tripletsnipimage(m, 2)
  4439.         tripletsnipimage(pcountimagerepack, 3) = tripletsnipimage(m, 3)
  4440.         tripletsnipimage(pcountimagerepack, 4) = tripletsnipimage(m, 4)
  4441.         tripletsnipimage(pcountimagerepack, 5) = tripletsnipimage(m, 5)
  4442.         tripletsnipimage(pcountimagerepack, 6) = tripletsnipimage(m, 6)
  4443.         tripletsnipimage(pcountimagerepack, 7) = tripletsnipimage(m, 7)
  4444.         tripletsnipimage(pcountimagerepack, 8) = tripletsnipimage(m, 8)
  4445.         tripletsnipimage(pcountimagerepack, 9) = tripletsnipimage(m, 9)
  4446.         tripletsnipimage(pcountimagerepack, 10) = tripletsnipimage(m, 10)
  4447.     END IF
  4448. pcounttripletsnipimage = pcountimagerepack
  4449.  
  4450. ' *** Define functions for plot modes. ***
  4451.  
  4452. plotmode.linearconnect:
  4453. ' Erase old graphics.
  4454. FOR i = 1 TO numparticlevisible - 1
  4455.     x = zoom * vecvisiblepuvs.old(i, 1): y = zoom * vecvisiblepuvs.old(i, 2): GOSUB convert: x1 = x: y1 = y
  4456.     x = zoom * vecvisiblepuvs.old(i + 1, 1): y = zoom * vecvisiblepuvs.old(i + 1, 2): GOSUB convert: x2 = x: y2 = y
  4457.     LINE (x1, y1)-(x2, y2), 0
  4458. ' Draw new graphics.
  4459. FOR i = 1 TO numparticlevisible - 1
  4460.     x = zoom * vecvisiblepuvs(i, 1): y = zoom * vecvisiblepuvs(i, 2): GOSUB convert: x1 = x: y1 = y
  4461.     x = zoom * vecvisiblepuvs(i + 1, 1): y = zoom * vecvisiblepuvs(i + 1, 2): GOSUB convert: x2 = x: y2 = y
  4462.     IF vecvisibledotnhat(i) > 0 THEN
  4463.         LINE (x1, y1)-(x2, y2), vecvisible(i, 4)
  4464.     ELSE
  4465.         LINE (x1, y1)-(x2, y2), 8
  4466.     END IF
  4467.  
  4468. plotmode.simplepoints:
  4469. ' Erase old graphics.
  4470. FOR i = 1 TO numparticlevisible
  4471.     x = zoom * vecvisiblepuvs.old(i, 1): y = zoom * vecvisiblepuvs.old(i, 2): GOSUB convert
  4472.     IF x > 0 AND x < 640 AND y > 0 AND y < 480 THEN
  4473.         PSET (x, y), 0
  4474.     END IF
  4475. ' Draw new graphics.
  4476. FOR i = 1 TO numparticlevisible
  4477.     x = zoom * vecvisiblepuvs(i, 1): y = zoom * vecvisiblepuvs(i, 2): GOSUB convert
  4478.     IF x > 0 AND x < 640 AND y > 0 AND y < 480 THEN
  4479.         PSET (x, y), vecvisible(i, 4)
  4480.     END IF
  4481.  
  4482. plotmode.3denvparticles:
  4483. FOR i = 1 TO numparticlevisible
  4484.     x = zoom * vecvisiblepuvs(i, 1): y = zoom * vecvisiblepuvs(i, 2): GOSUB convert
  4485.     PSET (x, y), vecvisible(i, 4)
  4486.  
  4487. plotmode.molecule:
  4488. 'FOR i = numparticlevisible TO 1 STEP -1
  4489. FOR i = 1 TO numparticlevisible
  4490.     FOR j = 6 TO 10
  4491.         IF vecvisible(i, j) = 0 THEN
  4492.             EXIT FOR
  4493.         ELSE
  4494.             x = zoom * vecvisiblepuvs.old(i, 1): y = zoom * vecvisiblepuvs.old(i, 2): GOSUB convert: x1 = x: y1 = y
  4495.             x = zoom * vecvisiblepuvs.old((vecvisible(i, j)), 1): y = zoom * vecvisiblepuvs.old((vecvisible(i, j)), 2): GOSUB convert: x2 = x: y2 = y
  4496.             LINE (x1, y1)-(x2, y2), 0
  4497.         END IF
  4498.     NEXT
  4499.     x = zoom * vecvisiblepuvs.old(i, 1): y = zoom * vecvisiblepuvs.old(i, 2)
  4500.     GOSUB convert
  4501.     IF x > 0 AND x < 640 AND y > 0 AND y < 480 THEN
  4502.         CIRCLE (x, y), INT(3 + 4 * vecvisible(i, 4) / biggestatom), 0
  4503.         IF toggleatomnumbers = 1 THEN
  4504.             COLOR 0
  4505.             LOCATE ytext, xtext: PRINT vecvisible(i, 5)
  4506.         END IF
  4507.     END IF
  4508.     FOR j = 6 TO 10
  4509.         IF vecvisible(i, j) = 0 THEN
  4510.             EXIT FOR
  4511.         ELSE
  4512.             x = zoom * vecvisiblepuvs(i, 1): y = zoom * vecvisiblepuvs(i, 2): GOSUB convert: x1 = x: y1 = y
  4513.             x = zoom * vecvisiblepuvs((vecvisible(i, j)), 1): y = zoom * vecvisiblepuvs((vecvisible(i, j)), 2): GOSUB convert: x2 = x: y2 = y
  4514.             LINE (x1, y1)-(x2, y2), vecvisible(i, 4)
  4515.         END IF
  4516.     NEXT
  4517.     x = zoom * vecvisiblepuvs(i, 1): y = zoom * vecvisiblepuvs(i, 2)
  4518.     GOSUB convert
  4519.     IF x > 0 AND x < 640 AND y > 0 AND y < 480 THEN
  4520.         CIRCLE (x, y), INT(3 + 4 * vecvisible(i, 4) / biggestatom), vecvisible(i, 4)
  4521.         IF toggleatomnumbers = 1 THEN
  4522.             COLOR vecvisible(i, 4)
  4523.             LOCATE ytext, xtext: PRINT vecvisible(i, 5)
  4524.         END IF
  4525.     END IF
  4526.  
  4527. plotmode.neighbortile:
  4528. tilemin = 1: tilemax = 3
  4529. FOR i = 1 TO numparticlevisible - 1
  4530.     FOR j = (i + 1) TO numparticlevisible
  4531.         vecvisiblesep = SQR((vecvisible(j, 1) - vecvisible(i, 1)) ^ 2 + (vecvisible(j, 2) - vecvisible(i, 2)) ^ 2 + (vecvisible(j, 3) - vecvisible(i, 3)) ^ 2)
  4532.         IF vecvisiblesep > tilemin AND vecvisiblesep < tilemax THEN
  4533.             ' Erase old graphics.
  4534.             x = zoom * vecvisiblepuvs.old(i, 1): y = zoom * vecvisiblepuvs.old(i, 2): GOSUB convert: x1 = x: y1 = y
  4535.             x = zoom * vecvisiblepuvs.old(j, 1): y = zoom * vecvisiblepuvs.old(j, 2): GOSUB convert: x2 = x: y2 = y
  4536.             LINE (x1, y1)-(x2, y2), 0
  4537.             ' Draw new graphics.
  4538.             x = zoom * vecvisiblepuvs(i, 1): y = zoom * vecvisiblepuvs(i, 2): GOSUB convert: x1 = x: y1 = y
  4539.             x = zoom * vecvisiblepuvs(j, 1): y = zoom * vecvisiblepuvs(j, 2): GOSUB convert: x2 = x: y2 = y
  4540.             IF vecvisibledotnhat(j) < 0 THEN
  4541.                 LINE (x1, y1)-(x2, y2), 8
  4542.             ELSE
  4543.                 LINE (x1, y1)-(x2, y2), vecvisible(j, 4)
  4544.             END IF
  4545.         END IF
  4546.     NEXT
  4547.  
  4548. plotmode.3denvdoublets:
  4549. FOR i = 1 TO numdoubletsnip.old
  4550.     ' Erase old graphics.
  4551.     x = zoom * doubletsnippuvs.old(i, 1): y = zoom * doubletsnippuvs.old(i, 2): GOSUB convert
  4552.     u1 = x: v1 = y
  4553.     CIRCLE (u1, v1), 5, 0
  4554.     x = zoom * doubletsnippuvs.old(i, 3): y = zoom * doubletsnippuvs.old(i, 4): GOSUB convert
  4555.     u2 = x: v2 = y
  4556.     CIRCLE (u2, v2), 3, 0
  4557.     LINE (u1, v1)-(u2, v2), 0
  4558. FOR i = 1 TO numdoubletsnip
  4559.     ' Draw new graphics.
  4560.     x = zoom * doubletsnippuvs(i, 1): y = zoom * doubletsnippuvs(i, 2): GOSUB convert
  4561.     u1 = x: v1 = y
  4562.     CIRCLE (u1, v1), 5, doubletsnip(i, 7)
  4563.     x = zoom * doubletsnippuvs(i, 3): y = zoom * doubletsnippuvs(i, 4): GOSUB convert
  4564.     u2 = x: v2 = y
  4565.     CIRCLE (u2, v2), 3, doubletsnip(i, 7)
  4566.     LINE (u1, v1)-(u2, v2), doubletsnip(i, 7)
  4567.  
  4568. plotmode.3denvtriplets:
  4569. 'FOR i = 1 TO numtripletfinal.old
  4570. '    ' Erase old graphics.
  4571. '    x = zoom * tripletfinalpuvs.old(i, 1): y = zoom * tripletfinalpuvs.old(i, 2): GOSUB convert
  4572. '    u1 = x: v1 = y
  4573. '    'CIRCLE (u1, v1), 5, 0
  4574. '    x = zoom * tripletfinalpuvs.old(i, 3): y = zoom * tripletfinalpuvs.old(i, 4): GOSUB convert
  4575. '    u2 = x: v2 = y
  4576. '    'CIRCLE (u2, v2), 4, 0
  4577. '    x = zoom * tripletfinalpuvs.old(i, 5): y = zoom * tripletfinalpuvs.old(i, 6): GOSUB convert
  4578. '    u3 = x: v3 = y
  4579. '    'CIRCLE (u3, v3), 3, 0
  4580. '    centu = (1 / 3) * (u1 + u2 + u3)
  4581. '    centv = (1 / 3) * (v1 + v2 + v3)
  4582. '    LINE (u1, v1)-(u2, v2), 0
  4583. '    LINE (u2, v2)-(u3, v3), 0
  4584. '    LINE (u3, v3)-(u1, v1), 0
  4585. '    'PAINT (centu, centv), 0, 0
  4586. 'NEXT
  4587. FOR i = 1 TO numtripletfinal
  4588.     ' Draw new graphics.
  4589.     x = zoom * tripletfinalpuvs(i, 1): y = zoom * tripletfinalpuvs(i, 2): GOSUB convert
  4590.     u1 = x: v1 = y
  4591.     'CIRCLE (u1, v1), 5, tripletfinal(i, 10)
  4592.     x = zoom * tripletfinalpuvs(i, 3): y = zoom * tripletfinalpuvs(i, 4): GOSUB convert
  4593.     u2 = x: v2 = y
  4594.     'CIRCLE (u2, v2), 4, tripletfinal(i, 10)
  4595.     x = zoom * tripletfinalpuvs(i, 5): y = zoom * tripletfinalpuvs(i, 6): GOSUB convert
  4596.     u3 = x: v3 = y
  4597.     'CIRCLE (u3, v3), 3, tripletfinal(i, 10)
  4598.     LINE (u1, v1)-(u2, v2), tripletfinal(i, 10)
  4599.     LINE (u2, v2)-(u3, v3), tripletfinal(i, 10)
  4600.     LINE (u3, v3)-(u1, v1), tripletfinal(i, 10)
  4601.     centu = (1 / 3) * (u1 + u2 + u3)
  4602.     centv = (1 / 3) * (v1 + v2 + v3)
  4603.     'PAINT (centu, centv), tripletfinal(i, 10), tripletfinal(i, 10)
  4604.  
  4605. plotmode.simplemesh:
  4606. FOR i = 1 TO numparticlevisible - 1
  4607.     IF i MOD yrange <> 0 THEN 'point obeys normal neighbor-connect scheme
  4608.         ' Erase old graphics.
  4609.         x = zoom * vecvisiblepuvs.old(i, 1): y = zoom * vecvisiblepuvs.old(i, 2): GOSUB convert: x1 = x: y1 = y
  4610.         x = zoom * vecvisiblepuvs.old(i + 1, 1): y = zoom * vecvisiblepuvs.old(i + 1, 2): GOSUB convert: x2 = x: y2 = y
  4611.         x = zoom * vecvisiblepuvs.old(i + yrange, 1): y = zoom * vecvisiblepuvs.old(i + yrange, 2): GOSUB convert: x3 = x: y3 = y
  4612.         LINE (x1, y1)-(x2, y2), 0
  4613.         IF i < (numparticlevisible - yrange) THEN LINE (x1, y1)-(x3, y3), 0
  4614.         ' Draw new graphics.
  4615.         x = zoom * vecvisiblepuvs(i, 1): y = zoom * vecvisiblepuvs(i, 2): GOSUB convert: x1 = x: y1 = y
  4616.         x = zoom * vecvisiblepuvs(i + 1, 1): y = zoom * vecvisiblepuvs(i + 1, 2): GOSUB convert: x2 = x: y2 = y
  4617.         x = zoom * vecvisiblepuvs(i + yrange, 1): y = zoom * vecvisiblepuvs(i + yrange, 2): GOSUB convert: x3 = x: y3 = y
  4618.         LINE (x1, y1)-(x2, y2), vecvisible(i, 4)
  4619.         IF i < (numparticlevisible - yrange) THEN LINE (x1, y1)-(x3, y3), vecvisible(i, 4)
  4620.     ELSE 'point does not obey normal neighbor-connect scheme
  4621.         ' Erase old graphics.
  4622.         x = zoom * vecvisiblepuvs.old(i, 1): y = zoom * vecvisiblepuvs.old(i, 2): GOSUB convert: x1 = x: y1 = y
  4623.         x = zoom * vecvisiblepuvs.old(i + yrange, 1): y = zoom * vecvisiblepuvs.old(i + yrange, 2): GOSUB convert: x3 = x: y3 = y
  4624.         IF i < (numparticlevisible - yrange + 1) THEN LINE (x1, y1)-(x3, y3), 0
  4625.         ' Draw new graphics.
  4626.         x = zoom * vecvisiblepuvs(i, 1): y = zoom * vecvisiblepuvs(i, 2): GOSUB convert: x1 = x: y1 = y
  4627.         x = zoom * vecvisiblepuvs(i + yrange, 1): y = zoom * vecvisiblepuvs(i + yrange, 2): GOSUB convert: x3 = x: y3 = y
  4628.         IF i < (numparticlevisible - yrange + 1) THEN LINE (x1, y1)-(x3, y3), vecvisible(i, 4)
  4629.     END IF
  4630.  
  4631. plotmode.meshtech2:
  4632. FOR i = 1 TO numparticlevisible - yrange
  4633.     vecvisible1temp1 = vecvisible(i + 1, 1) - vecvisible(i, 1)
  4634.     vecvisible1temp2 = vecvisible(i + 1, 2) - vecvisible(i, 2)
  4635.     vecvisible1temp3 = vecvisible(i + 1, 3) - vecvisible(i, 3)
  4636.     vecvisible2temp1 = vecvisible(i + yrange, 1) - vecvisible(i, 1)
  4637.     vecvisible2temp2 = vecvisible(i + yrange, 2) - vecvisible(i, 2)
  4638.     vecvisible2temp3 = vecvisible(i + yrange, 3) - vecvisible(i, 3)
  4639.     vecvisiblet1 = -vecvisible1temp2 * vecvisible2temp3 + vecvisible1temp3 * vecvisible2temp2
  4640.     vecvisiblet2 = -vecvisible1temp3 * vecvisible2temp1 + vecvisible1temp1 * vecvisible2temp3
  4641.     vecvisiblet3 = -vecvisible1temp1 * vecvisible2temp2 + vecvisible1temp2 * vecvisible2temp1
  4642.     vecvisibletdotnhat = vecvisiblet1 * nhat(1) + vecvisiblet2 * nhat(2) + vecvisiblet3 * nhat(3)
  4643.     IF vecvisibletdotnhat > 0 THEN plotflag(i) = 1 ELSE plotflag(i) = -1
  4644. FOR i = 1 TO numparticlevisible - yrange
  4645.     IF i MOD yrange <> 0 THEN 'point obeys normal neighbor-connect scheme
  4646.         ' Erase old graphics.
  4647.         IF plotflag.old(i) = 1 THEN
  4648.             x = zoom * vecvisiblepuvs.old(i, 1): y = zoom * vecvisiblepuvs.old(i, 2): GOSUB convert: x1 = x: y1 = y
  4649.             x = zoom * vecvisiblepuvs.old(i + 1, 1): y = zoom * vecvisiblepuvs.old(i + 1, 2): GOSUB convert: x2 = x: y2 = y
  4650.             x = zoom * vecvisiblepuvs.old(i + yrange, 1): y = zoom * vecvisiblepuvs.old(i + yrange, 2): GOSUB convert: x3 = x: y3 = y
  4651.             LINE (x1, y1)-(x2, y2), 0
  4652.             LINE (x1, y1)-(x3, y3), 0
  4653.         END IF
  4654.         ' Draw new graphics.
  4655.         IF plotflag(i) = 1 THEN
  4656.             x = zoom * vecvisiblepuvs(i, 1): y = zoom * vecvisiblepuvs(i, 2): GOSUB convert: x1 = x: y1 = y
  4657.             x = zoom * vecvisiblepuvs(i + 1, 1): y = zoom * vecvisiblepuvs(i + 1, 2): GOSUB convert: x2 = x: y2 = y
  4658.             x = zoom * vecvisiblepuvs(i + yrange, 1): y = zoom * vecvisiblepuvs(i + yrange, 2): GOSUB convert: x3 = x: y3 = y
  4659.             LINE (x1, y1)-(x2, y2), vecvisible(i, 4)
  4660.             LINE (x1, y1)-(x3, y3), vecvisible(i, 4)
  4661.         END IF
  4662.         plotflag.old(i) = plotflag(i)
  4663.     END IF
  4664.  
  4665. plotmode.meshtech2planet:
  4666. FOR i = 1 TO numparticlevisible - 1
  4667.     IF i MOD yrange <> 0 THEN
  4668.         ' Erase old graphics.
  4669.         IF vecvisibledotnhatunit.old(i) > 0 THEN
  4670.             x = zoom * vecvisiblepuvs.old(i, 1): y = zoom * vecvisiblepuvs.old(i, 2): GOSUB convert: x1 = x: y1 = y
  4671.             x = zoom * vecvisiblepuvs.old(i + 1, 1): y = zoom * vecvisiblepuvs.old(i + 1, 2): GOSUB convert: x2 = x: y2 = y
  4672.             x = zoom * vecvisiblepuvs.old(i + yrange, 1): y = zoom * vecvisiblepuvs.old(i + yrange, 2): GOSUB convert: x3 = x: y3 = y
  4673.             LINE (x1, y1)-(x2, y2), 0
  4674.             IF i < (numparticlevisible - yrange) THEN LINE (x1, y1)-(x3, y3), 0
  4675.         END IF
  4676.         ' Draw new graphics.
  4677.         IF vecvisibledotnhat(i) > 0 THEN
  4678.             x = zoom * vecvisiblepuvs(i, 1): y = zoom * vecvisiblepuvs(i, 2): GOSUB convert: x1 = x: y1 = y
  4679.             x = zoom * vecvisiblepuvs(i + 1, 1): y = zoom * vecvisiblepuvs(i + 1, 2): GOSUB convert: x2 = x: y2 = y
  4680.             x = zoom * vecvisiblepuvs(i + yrange, 1): y = zoom * vecvisiblepuvs(i + yrange, 2): GOSUB convert: x3 = x: y3 = y
  4681.             LINE (x1, y1)-(x2, y2), vecvisible(i, 4)
  4682.             IF i < (numparticlevisible - yrange) THEN LINE (x1, y1)-(x3, y3), vecvisible(i, 4)
  4683.         END IF
  4684.     END IF
  4685.     vecvisibledotnhatunit.old(i) = vecvisibledotnhat(i)
  4686.  
  4687. plotmode.simplepointsbacteria:
  4688. FOR i = numparticlevisible TO 1 STEP -1
  4689.     IF vecvisible(i, 4) = 8 THEN
  4690.         ' Erase old graphics.
  4691.         x = zoom * vecvisiblepuvs.old(i, 1): y = zoom * vecvisiblepuvs.old(i, 2): GOSUB convert
  4692.         IF x > 0 AND x < 640 AND y > 0 AND y < 480 THEN
  4693.             PSET (x, y), 0
  4694.         END IF
  4695.         ' Draw new graphics.
  4696.         x = zoom * vecvisiblepuvs(i, 1): y = zoom * vecvisiblepuvs(i, 2): GOSUB convert
  4697.         IF x > 0 AND x < 640 AND y > 0 AND y < 480 THEN
  4698.             IF vecvisibledotnhat(i) > 0 THEN
  4699.                 PSET (x, y), vecvisible(i, 4)
  4700.             ELSE
  4701.                 PSET (x, y), 8
  4702.             END IF
  4703.         END IF
  4704.     ELSE
  4705.         ' Erase old graphics.
  4706.         x = zoom * vecvisiblepuvs.old(i, 1): y = zoom * vecvisiblepuvs.old(i, 2): GOSUB convert
  4707.         IF x > 0 AND x < 640 AND y > 0 AND y < 480 THEN
  4708.             CIRCLE (x, y), INT(vecvisible(i, 7) * zoom) + 1, 0
  4709.         END IF
  4710.         ' Draw new graphics.
  4711.         x = zoom * vecvisiblepuvs(i, 1): y = zoom * vecvisiblepuvs(i, 2): GOSUB convert
  4712.         IF x > 0 AND x < 640 AND y > 0 AND y < 480 THEN
  4713.             CIRCLE (x, y), INT(vecvisible(i, 6) * zoom) + 1, vecvisible(i, 4)
  4714.         END IF
  4715.     END IF
  4716.  
  4717. plotmode.linearneuron:
  4718. FOR i = 1 TO numneuralnodes
  4719.     FOR j = 1 TO numparticlevisible
  4720.         IF i <> j AND vecvisible(j, 5) = i THEN
  4721.             ' Erase old graphics.
  4722.             x = zoom * vecvisiblepuvs.old(i, 1): y = zoom * vecvisiblepuvs.old(i, 2): GOSUB convert: x1 = x: y1 = y
  4723.             x = zoom * vecvisiblepuvs.old(j, 1): y = zoom * vecvisiblepuvs.old(j, 2): GOSUB convert: x2 = x: y2 = y
  4724.             IF x1 > 0 AND x1 < 640 AND y1 > 0 AND y1 < 480 AND x2 > 0 AND x2 < 640 AND y2 > 0 AND y2 < 480 THEN
  4725.                 LINE (x1, y1)-(x2, y2), 0
  4726.             END IF
  4727.             ' Draw new graphics.
  4728.             x = zoom * vecvisiblepuvs(i, 1): y = zoom * vecvisiblepuvs(i, 2): GOSUB convert: x1 = x: y1 = y
  4729.             x = zoom * vecvisiblepuvs(j, 1): y = zoom * vecvisiblepuvs(j, 2): GOSUB convert: x2 = x: y2 = y
  4730.             IF x1 > 0 AND x1 < 640 AND y1 > 0 AND y1 < 480 AND x2 > 0 AND x2 < 640 AND y2 > 0 AND y2 < 480 THEN
  4731.                 LINE (x1, y1)-(x2, y2), vecvisible(j, 4)
  4732.             END IF
  4733.         END IF
  4734.     NEXT
  4735.  
  4736. ' *** Define functions for generation schemes. ***
  4737.  
  4738. ' *****************************************************************************
  4739. 'ALLYLDICHLOROSILANE SGI MOLECULE BEGIN
  4740. DATA 0.000000,0.000000,0.000000,6,1,2,0,0,0,0
  4741. DATA 0.000000,0.000000,1.317000,6,2,0,0,0,0,0
  4742. DATA 1.253339,0.000000,2.174135,6,3,2,0,0,0,0
  4743. DATA 1.648740,-1.728751,2.759165,14,4,3,0,0,0,0
  4744. DATA 1.861829,-2.662286,1.657558,1,5,4,0,0,0,0
  4745. DATA 0.909973,0.026847,-0.570958,1,6,1,0,0,0,0
  4746. DATA -0.914351,-0.018888,-0.560617,1,7,1,0,0,0,0
  4747. DATA -0.931482,-0.023791,1.853298,1,8,2,0,0,0,0
  4748. DATA 1.132146,0.660744,3.028965,1,9,3,0,0,0,0
  4749. DATA 2.102271,0.367006,1.600915,1,10,3,0,0,0,0
  4750. DATA 3.353124,-1.699853,3.896830,17,11,4,0,0,0,0
  4751. DATA 0.105750,-2.448640,3.896713,17,12,4,0,0,0,0
  4752. 'DATA x, y, z, atomic number, atom index, neighbor 1, neighbor 2, etc.
  4753. 'ALLYLDICHLOROSILANE SGI MOLECULE END
  4754. ' *****************************************************************************
  4755.  
  4756. genschemeUSAcolors:
  4757. 'delinearize
  4758. pcountparticleorig = 0
  4759. FOR i = 1 TO xrange
  4760.     FOR j = 1 TO yrange
  4761.         pcountparticleorig = pcountparticleorig + 1
  4762.         vec2dztemp(i, j) = vec(pcountparticleorig, 4)
  4763.     NEXT
  4764. FOR i = 1 TO xrange
  4765.     FOR jj = 0 TO 12 STEP 2
  4766.         FOR j = jj * yrange / 13 + 1 TO (jj + 1) * yrange / 13
  4767.             vec2dztemp(i, j) = 4
  4768.         NEXT
  4769.     NEXT
  4770.     FOR jj = 1 TO 11 STEP 2
  4771.         FOR j = jj * yrange / 13 + 1 TO (jj + 1) * yrange / 13
  4772.             vec2dztemp(i, j) = 7
  4773.         NEXT
  4774.     NEXT
  4775. starflag = -1
  4776. FOR i = 1 TO xrange * .76 / 1.9
  4777.     FOR j = yrange TO yrange * .5385 STEP -1
  4778.         IF starflag = 1 THEN
  4779.             vec2dztemp(i, j) = 15
  4780.         ELSE
  4781.             vec2dztemp(i, j) = 1
  4782.         END IF
  4783.         starflag = -starflag
  4784.     NEXT
  4785. 'relinearize
  4786. pcountparticleorig = 0
  4787. FOR i = 1 TO xrange
  4788.     FOR j = 1 TO yrange
  4789.         pcountparticleorig = pcountparticleorig + 1
  4790.         vec(pcountparticleorig, 4) = vec2dztemp(i, j)
  4791.     NEXT
  4792.  
  4793. genscheme.curve:
  4794. helixL = 15
  4795. helixR1 = 5
  4796. helixR2 = 2.5
  4797. helixalpha = .1
  4798. xl = -helixL / 2: xr = helixL / 2: Dx = .005
  4799. gridxhalfsize = 10
  4800. gridyhalfsize = 30
  4801. gridzhalfsize = 5
  4802. gridxstep = 1
  4803. gridystep = 1
  4804. gridzstep = 1
  4805. pcountparticleorig = 0
  4806. FOR i = xl TO xr STEP Dx
  4807.     pcountparticleorig = pcountparticleorig + 1
  4808.     RZ = helixR1 - (helixR1 - helixR2) * (i + helixL / 2) / helixL
  4809.     vec(pcountparticleorig, 1) = RZ * COS(i)
  4810.     vec(pcountparticleorig, 2) = RZ * SIN(i)
  4811.     vec(pcountparticleorig, 3) = helixalpha * i
  4812.     vec(pcountparticleorig, 4) = 5
  4813.  
  4814. genscheme.simplepoints:
  4815. xl = -3.2: xr = 5.98
  4816. yl = -4.01: yr = 6.1
  4817. Dx = .2: Dy = .1
  4818. pcountparticleorig = 0
  4819. FOR i = xl TO xr STEP Dx
  4820.     FOR j = yl TO yr STEP Dy
  4821.         pcountparticleorig = pcountparticleorig + 1
  4822.         vec(pcountparticleorig, 1) = i
  4823.         vec(pcountparticleorig, 2) = j
  4824.         vec(pcountparticleorig, 3) = COS((i ^ 2 - j ^ 2))
  4825.         vec(pcountparticleorig, 4) = 9
  4826.     NEXT
  4827.  
  4828. genscheme.3denvparticles.init:
  4829. pcountparticleorig = 0
  4830. 'particle grass
  4831. FOR i = -50 TO 50 STEP 1
  4832.     FOR j = -50 TO 50 STEP 1
  4833.         k = 0
  4834.         pcountparticleorig = pcountparticleorig + 1
  4835.         vec(pcountparticleorig, 1) = i + RND - RND
  4836.         vec(pcountparticleorig, 2) = j + RND - RND
  4837.         vec(pcountparticleorig, 3) = k - COS((i - 15) * .08) + COS((j - 6) * .12)
  4838.         IF COS((i - 15) * .08) + COS((j - 6) * .12) < .5 THEN
  4839.             vec(pcountparticleorig, 4) = 2
  4840.         ELSE
  4841.             IF RND > .2 THEN
  4842.                 vec(pcountparticleorig, 4) = 9
  4843.             ELSE
  4844.                 vec(pcountparticleorig, 4) = 1
  4845.             END IF
  4846.         END IF
  4847.     NEXT
  4848. 'particle sky
  4849. FOR i = -50 TO 50 STEP 1
  4850.     FOR j = -50 TO 50 STEP 1
  4851.         k = -50
  4852.         pcountparticleorig = pcountparticleorig + 1
  4853.         vec(pcountparticleorig, 1) = i + RND
  4854.         vec(pcountparticleorig, 2) = j + RND
  4855.         vec(pcountparticleorig, 3) = -k - RND
  4856.         IF RND > .5 THEN
  4857.             vec(pcountparticleorig, 4) = 9
  4858.         ELSE
  4859.             vec(pcountparticleorig, 4) = 15
  4860.         END IF
  4861.     NEXT
  4862. 'particle wave art 1
  4863. FOR i = 1 TO 5 STEP .05
  4864.     FOR k = 1 TO 5 STEP .05
  4865.         pcountparticleorig = pcountparticleorig + 1
  4866.         vec(pcountparticleorig, 1) = -7 * i
  4867.         vec(pcountparticleorig, 2) = 50 + 1 * COS(2 * ((i - 7) ^ 2 - (k - 5) ^ 2))
  4868.         vec(pcountparticleorig, 3) = 10 + 7 * k
  4869.         IF vec(pcountparticleorig, 2) < 50 THEN
  4870.             vec(pcountparticleorig, 4) = 13
  4871.         ELSE
  4872.             vec(pcountparticleorig, 4) = 4
  4873.         END IF
  4874.     NEXT
  4875. 'particle wave art 2
  4876. FOR i = 1 TO 5 STEP .05
  4877.     FOR k = 1 TO 5 STEP .05
  4878.         pcountparticleorig = pcountparticleorig + 1
  4879.         vec(pcountparticleorig, 1) = 7 * i
  4880.         vec(pcountparticleorig, 2) = 50 + 1 * COS((i ^ 2 - k ^ 2))
  4881.         vec(pcountparticleorig, 3) = 10 + 7 * k
  4882.         IF vec(pcountparticleorig, 2) < 50 THEN
  4883.             vec(pcountparticleorig, 4) = 2
  4884.         ELSE
  4885.             vec(pcountparticleorig, 4) = 1
  4886.         END IF
  4887.     NEXT
  4888. 'air ball
  4889. FOR j = 1 TO 5
  4890.     p1 = RND * 5
  4891.     p2 = RND * 5
  4892.     p3 = RND * 5
  4893.     FOR i = -pi TO pi STEP .15 '.0005 for Menon demo
  4894.         pcountparticleorig = pcountparticleorig + 1
  4895.         vec(pcountparticleorig, 1) = 30 + 5 * COS(i) * SIN(p1 * i) + SIN(p3 * i)
  4896.         vec(pcountparticleorig, 2) = 20 + 5 * SIN(i) * COS(p2 * i) + COS(p2 * i)
  4897.         vec(pcountparticleorig, 3) = 20 - 5 * COS(i) * SIN(p3 * i) + SIN(p1 * i)
  4898.         vec(pcountparticleorig, 4) = 6
  4899.     NEXT
  4900. animpcountparticleflag = pcountparticleorig
  4901. 'particle snake
  4902. FOR i = -pi TO pi STEP .005
  4903.     pcountparticleorig = pcountparticleorig + 1
  4904.     vec(pcountparticleorig, 1) = -10 + 5 * COS(i)
  4905.     vec(pcountparticleorig, 2) = -20 + 5 * SIN(i)
  4906.     vec(pcountparticleorig, 3) = 25 - 3 * COS(6 * i) * SIN(3 * i)
  4907.     vec(pcountparticleorig, 4) = 12
  4908. 'rain drops
  4909. FOR i = -50 TO 50 STEP 5
  4910.     FOR j = -50 TO 50 STEP 5
  4911.         k = 50
  4912.         pcountparticleorig = pcountparticleorig + 1
  4913.         vec(pcountparticleorig, 1) = i + RND
  4914.         vec(pcountparticleorig, 2) = j + RND
  4915.         vec(pcountparticleorig, 3) = k * RND
  4916.         IF RND > .66 THEN
  4917.             vec(pcountparticleorig, 4) = 9
  4918.         ELSE
  4919.             vec(pcountparticleorig, 4) = 7
  4920.         END IF
  4921.     NEXT
  4922.  
  4923. genscheme.3denvparticles.timeanimate:
  4924. T = timevar / 50
  4925. pcountparticleorig = animpcountparticleflag
  4926. 'particle snake
  4927. FOR i = -pi TO pi STEP .005
  4928.     pcountparticleorig = pcountparticleorig + 1
  4929.     vec(pcountparticleorig, 1) = camx - 10 + 5 * COS(i + T)
  4930.     vec(pcountparticleorig, 2) = camy - 20 + 5 * SIN(i + T)
  4931.     vec(pcountparticleorig, 3) = camz + 25 - 3 * COS(6 * i + T) * SIN(3 * i + T)
  4932.     vec(pcountparticleorig, 4) = 12
  4933. 'rain drops
  4934. FOR i = -50 TO 50 STEP 5
  4935.     FOR j = -50 TO 50 STEP 5
  4936.         pcountparticleorig = pcountparticleorig + 1
  4937.         vec(pcountparticleorig, 1) = vec(pcountparticleorig, 1)
  4938.         vec(pcountparticleorig, 2) = vec(pcountparticleorig, 2)
  4939.         vec(pcountparticleorig, 3) = vec(pcountparticleorig, 3) - .3
  4940.         IF vec(pcountparticleorig, 3) < camz THEN vec(pcountparticleorig, 3) = vec(pcountparticleorig, 3) + 50
  4941.     NEXT
  4942.  
  4943. ' *****************************************************************************
  4944. 'ETHANE MOLECULE BEGIN
  4945. 'DATA 0,0,-0.771209,6,1,0,0,0,0,0
  4946. 'DATA 0,0,0.771209,6,2,1,0,0,0,0
  4947. 'DATA 1.013466,0,1.156212,2,3,2,0,0,0,0
  4948. 'DATA -1.013466,0,-1.156212,2,4,1,0,0,0,0
  4949. 'DATA -0.506733,-0.877687,1.156212,2,5,2,0,0,0,0
  4950. 'DATA -0.506733,0.877687,1.156212,2,6,2,0,0,0,0
  4951. 'DATA 0.506733,-0.877687,-1.156212,2,7,1,0,0,0,0
  4952. 'DATA 0.506733,0.877687,-1.156212,2,8,1,0,0,0,0
  4953. 'DATA x, y, z, atomic number, atom index, neighbor 1, neighbor 2, etc.
  4954. 'ETHANE MOLECULE END
  4955. ' *****************************************************************************
  4956.  
  4957. genscheme.molecule:
  4958. 'DATA x, y, z, atomic number, atom index, neighbor 1, neighbor 2, etc.
  4959. biggestatom = -999999999
  4960. FOR i = 1 TO numparticleorig
  4961.     IF vec(i, 4) > 15 THEN
  4962.         DO
  4963.             vec(i, 4) = vec(i, 4) * .75
  4964.         LOOP UNTIL vec(i, 4) <= 15
  4965.     END IF
  4966.     IF vec(i, 4) > biggestatom THEN biggestatom = vec(i, 4)
  4967.  
  4968. genscheme.neighbortile:
  4969. pcountparticleorig = 0
  4970. pcountparticleorig = 0
  4971. FOR i = -8 TO 8 STEP 1
  4972.     FOR j = -8 TO 8 STEP 1
  4973.         FOR k = -8 TO 8 STEP 1
  4974.             mag = SQR((i ^ 2) + (j ^ 2) + (k ^ 2)) - 6
  4975.             IF SQR(mag ^ 2) < .1 AND i > 0 THEN
  4976.                 pcountparticleorig = pcountparticleorig + 1
  4977.                 vec(pcountparticleorig, 1) = i
  4978.                 vec(pcountparticleorig, 2) = j
  4979.                 vec(pcountparticleorig, 3) = k
  4980.                 vec(pcountparticleorig, 4) = 4
  4981.             END IF
  4982.             mag = SQR((i ^ 2) + (j ^ 2) + (k ^ 2)) - 3
  4983.             IF SQR(mag ^ 2) < .1 AND i < 2 THEN
  4984.                 pcountparticleorig = pcountparticleorig + 1
  4985.                 vec(pcountparticleorig, 1) = i - 5
  4986.                 vec(pcountparticleorig, 2) = j
  4987.                 vec(pcountparticleorig, 3) = k
  4988.                 vec(pcountparticleorig, 4) = 5
  4989.             END IF
  4990.         NEXT
  4991.     NEXT
  4992. FOR i = -3 TO 2
  4993.     pcountparticleorig = pcountparticleorig + 1
  4994.     vec(pcountparticleorig, 1) = i: vec(pcountparticleorig, 2) = -3: vec(pcountparticleorig, 3) = -3: vec(pcountparticleorig, 4) = 2
  4995.     pcountparticleorig = pcountparticleorig + 1
  4996.     vec(pcountparticleorig, 1) = i: vec(pcountparticleorig, 2) = -3: vec(pcountparticleorig, 3) = 3: vec(pcountparticleorig, 4) = 2
  4997.     pcountparticleorig = pcountparticleorig + 1
  4998.     vec(pcountparticleorig, 1) = i: vec(pcountparticleorig, 2) = 3: vec(pcountparticleorig, 3) = -3: vec(pcountparticleorig, 4) = 2
  4999.     pcountparticleorig = pcountparticleorig + 1
  5000.     vec(pcountparticleorig, 1) = i: vec(pcountparticleorig, 2) = 3: vec(pcountparticleorig, 3) = 3: vec(pcountparticleorig, 4) = 2
  5001.  
  5002. genscheme.3denvdoublets:
  5003. pcountdoubletorig = 0
  5004. pcountdoubletorig = pcountdoubletorig + 1
  5005. doubletorig(pcountdoubletorig, 1) = 5
  5006. doubletorig(pcountdoubletorig, 2) = 0
  5007. doubletorig(pcountdoubletorig, 3) = 0
  5008. doubletorig(pcountdoubletorig, 4) = 30
  5009. doubletorig(pcountdoubletorig, 5) = 0
  5010. doubletorig(pcountdoubletorig, 6) = 0
  5011. doubletorig(pcountdoubletorig, 7) = 14
  5012. FOR j = 1 TO 5
  5013.     pcountdoubletorig = pcountdoubletorig + 1
  5014.     doubletorig(pcountdoubletorig, 1) = 5
  5015.     doubletorig(pcountdoubletorig, 2) = -20
  5016.     doubletorig(pcountdoubletorig, 3) = j
  5017.     doubletorig(pcountdoubletorig, 4) = 5
  5018.     doubletorig(pcountdoubletorig, 5) = 20
  5019.     doubletorig(pcountdoubletorig, 6) = j
  5020.     doubletorig(pcountdoubletorig, 7) = 13
  5021. FOR j = 1 TO 5
  5022.     pcountdoubletorig = pcountdoubletorig + 1
  5023.     doubletorig(pcountdoubletorig, 1) = 15
  5024.     doubletorig(pcountdoubletorig, 2) = j
  5025.     doubletorig(pcountdoubletorig, 3) = -20
  5026.     doubletorig(pcountdoubletorig, 4) = 15
  5027.     doubletorig(pcountdoubletorig, 5) = j
  5028.     doubletorig(pcountdoubletorig, 6) = 20
  5029.     doubletorig(pcountdoubletorig, 7) = 4
  5030. 'dot grid
  5031. pcountparticleorig = 0
  5032. FOR i = -20 TO 20 STEP 2
  5033.     FOR j = -20 TO 20 STEP 2
  5034.         FOR k = -20 TO 20 STEP 5
  5035.             pcountparticleorig = pcountparticleorig + 1
  5036.             vec(pcountparticleorig, 1) = i
  5037.             vec(pcountparticleorig, 2) = j
  5038.             vec(pcountparticleorig, 3) = k
  5039.             vec(pcountparticleorig, 4) = 6
  5040.         NEXT
  5041.     NEXT
  5042.  
  5043. genscheme.3denvtriplets:
  5044. pcounttripletorig = 0
  5045. 'cubes
  5046. length = 5
  5047. cubecenterx = 0: cubecentery = 0: cubecenterz = -15: GOSUB genscheme.3denvtriplets.makecube
  5048. cubecenterx = 20: cubecentery = 15: cubecenterz = -15: GOSUB genscheme.3denvtriplets.makecube
  5049. cubecenterx = 40: cubecentery = 0: cubecenterz = -25: GOSUB genscheme.3denvtriplets.makecube
  5050.  
  5051. genscheme.3denvtriplets.makecube:
  5052. basepointx = cubecenterx + length
  5053. basepointy = cubecentery + length
  5054. basepointz = cubecenterz - length
  5055. rightpointx = cubecenterx + length
  5056. rightpointy = cubecentery - length
  5057. rightpointz = cubecenterz - length
  5058. leftpointx = cubecenterx - length
  5059. leftpointy = cubecentery + length
  5060. leftpointz = cubecenterz - length
  5061. panelcolor = INT(RND * 14) + 1
  5062. GOSUB create.original.triangle
  5063. basepointx = cubecenterx - length
  5064. basepointy = cubecentery + length
  5065. basepointz = cubecenterz - length
  5066. rightpointx = cubecenterx + length
  5067. rightpointy = cubecentery - length
  5068. rightpointz = cubecenterz - length
  5069. leftpointx = cubecenterx - length
  5070. leftpointy = cubecentery - length
  5071. leftpointz = cubecenterz - length
  5072. 'panelcolor = 9
  5073. GOSUB create.original.triangle
  5074. basepointx = cubecenterx - length
  5075. basepointy = cubecentery + length
  5076. basepointz = cubecenterz - length
  5077. rightpointx = cubecenterx - length
  5078. rightpointy = cubecentery - length
  5079. rightpointz = cubecenterz - length
  5080. leftpointx = cubecenterx - length
  5081. leftpointy = cubecentery + length
  5082. leftpointz = cubecenterz + length
  5083. panelcolor = INT(RND * 14) + 1
  5084. GOSUB create.original.triangle
  5085. basepointx = cubecenterx - length
  5086. basepointy = cubecentery + length
  5087. basepointz = cubecenterz + length
  5088. rightpointx = cubecenterx - length
  5089. rightpointy = cubecentery - length
  5090. rightpointz = cubecenterz - length
  5091. leftpointx = cubecenterx - length
  5092. leftpointy = cubecentery - length
  5093. leftpointz = cubecenterz + length
  5094. 'panelcolor = 10
  5095. GOSUB create.original.triangle
  5096. basepointx = cubecenterx - length
  5097. basepointy = cubecentery - length
  5098. basepointz = cubecenterz - length
  5099. rightpointx = cubecenterx + length
  5100. rightpointy = cubecentery - length
  5101. rightpointz = cubecenterz - length
  5102. leftpointx = cubecenterx - length
  5103. leftpointy = cubecentery - length
  5104. leftpointz = cubecenterz + length
  5105. panelcolor = INT(RND * 14) + 1
  5106. GOSUB create.original.triangle
  5107. basepointx = cubecenterx - length
  5108. basepointy = cubecentery - length
  5109. basepointz = cubecenterz + length
  5110. rightpointx = cubecenterx + length
  5111. rightpointy = cubecentery - length
  5112. rightpointz = cubecenterz - length
  5113. leftpointx = cubecenterx + length
  5114. leftpointy = cubecentery - length
  5115. leftpointz = cubecenterz + length
  5116. 'panelcolor = 11
  5117. GOSUB create.original.triangle
  5118. basepointx = cubecenterx - length
  5119. basepointy = cubecentery + length
  5120. basepointz = cubecenterz + length
  5121. rightpointx = cubecenterx - length
  5122. rightpointy = cubecentery - length
  5123. rightpointz = cubecenterz + length
  5124. leftpointx = cubecenterx + length
  5125. leftpointy = cubecentery + length
  5126. leftpointz = cubecenterz + length
  5127. panelcolor = INT(RND * 14) + 1
  5128. GOSUB create.original.triangle
  5129. basepointx = cubecenterx + length
  5130. basepointy = cubecentery + length
  5131. basepointz = cubecenterz + length
  5132. rightpointx = cubecenterx - length
  5133. rightpointy = cubecentery - length
  5134. rightpointz = cubecenterz + length
  5135. leftpointx = cubecenterx + length
  5136. leftpointy = cubecentery - length
  5137. leftpointz = cubecenterz + length
  5138. 'panelcolor = 12
  5139. GOSUB create.original.triangle
  5140. basepointx = cubecenterx + length
  5141. basepointy = cubecentery - length
  5142. basepointz = cubecenterz - length
  5143. rightpointx = cubecenterx + length
  5144. rightpointy = cubecentery + length
  5145. rightpointz = cubecenterz - length
  5146. leftpointx = cubecenterx + length
  5147. leftpointy = cubecentery - length
  5148. leftpointz = cubecenterz + length
  5149. panelcolor = INT(RND * 14) + 1
  5150. GOSUB create.original.triangle
  5151. basepointx = cubecenterx + length
  5152. basepointy = cubecentery - length
  5153. basepointz = cubecenterz + length
  5154. rightpointx = cubecenterx + length
  5155. rightpointy = cubecentery + length
  5156. rightpointz = cubecenterz - length
  5157. leftpointx = cubecenterx + length
  5158. leftpointy = cubecentery + length
  5159. leftpointz = cubecenterz + length
  5160. 'panelcolor = 13
  5161. GOSUB create.original.triangle
  5162. basepointx = cubecenterx + length
  5163. basepointy = cubecentery + length
  5164. basepointz = cubecenterz - length
  5165. rightpointx = cubecenterx - length
  5166. rightpointy = cubecentery + length
  5167. rightpointz = cubecenterz - length
  5168. leftpointx = cubecenterx + length
  5169. leftpointy = cubecentery + length
  5170. leftpointz = cubecenterz + length
  5171. panelcolor = INT(RND * 14) + 1
  5172. GOSUB create.original.triangle
  5173. basepointx = cubecenterx + length
  5174. basepointy = cubecentery + length
  5175. basepointz = cubecenterz + length
  5176. rightpointx = cubecenterx - length
  5177. rightpointy = cubecentery + length
  5178. rightpointz = cubecenterz - length
  5179. leftpointx = cubecenterx - length
  5180. leftpointy = cubecentery + length
  5181. leftpointz = cubecenterz + length
  5182. 'panelcolor = 14
  5183. GOSUB create.original.triangle
  5184.  
  5185. create.original.triangle:
  5186. shrinkfactor = .90
  5187. centorigx = (1 / 3) * (basepointx + rightpointx + leftpointx)
  5188. centorigy = (1 / 3) * (basepointy + rightpointy + leftpointy)
  5189. centorigz = (1 / 3) * (basepointz + rightpointz + leftpointz)
  5190. basepointx = centorigx + (shrinkfactor) * (basepointx - centorigx)
  5191. basepointy = centorigy + (shrinkfactor) * (basepointy - centorigy)
  5192. basepointz = centorigz + (shrinkfactor) * (basepointz - centorigz)
  5193. rightpointx = centorigx + (shrinkfactor) * (rightpointx - centorigx)
  5194. rightpointy = centorigy + (shrinkfactor) * (rightpointy - centorigy)
  5195. rightpointz = centorigz + (shrinkfactor) * (rightpointz - centorigz)
  5196. leftpointx = centorigx + (shrinkfactor) * (leftpointx - centorigx)
  5197. leftpointy = centorigy + (shrinkfactor) * (leftpointy - centorigy)
  5198. leftpointz = centorigz + (shrinkfactor) * (leftpointz - centorigz)
  5199. pcounttripletorig = pcounttripletorig + 1
  5200. tripletorig(pcounttripletorig, 1) = basepointx
  5201. tripletorig(pcounttripletorig, 2) = basepointy
  5202. tripletorig(pcounttripletorig, 3) = basepointz
  5203. tripletorig(pcounttripletorig, 4) = rightpointx
  5204. tripletorig(pcounttripletorig, 5) = rightpointy
  5205. tripletorig(pcounttripletorig, 6) = rightpointz
  5206. tripletorig(pcounttripletorig, 7) = leftpointx
  5207. tripletorig(pcounttripletorig, 8) = leftpointy
  5208. tripletorig(pcounttripletorig, 9) = leftpointz
  5209. tripletorig(pcounttripletorig, 10) = panelcolor
  5210.  
  5211. genscheme.animatedsurface.init:
  5212. xl = -1.9: xr = 1.9
  5213. yl = -1: yr = 1
  5214. xl = xl * 4: xr = xr * 4: yl = yl * 4: yr = yr * 4
  5215. Dx = .32
  5216. Dy = .32
  5217. xrange = 1 + INT((-xl + xr) / Dx)
  5218. yrange = 1 + INT((-yl + yr) / Dy)
  5219. pcountparticleorig = 0
  5220. FOR i = xl TO xr STEP Dx
  5221.     FOR j = yl TO yr STEP Dy
  5222.         pcountparticleorig = pcountparticleorig + 1
  5223.         vec(pcountparticleorig, 1) = i
  5224.         vec(pcountparticleorig, 2) = j
  5225.         vec(pcountparticleorig, 3) = .25 + .25 * COS(i - 2 * T) ^ 2 - .25 * SIN(j - T) ^ 2
  5226.         '*'vec(pcountparticleorig, 4) = 14 'use special color scheme
  5227.     NEXT
  5228.  
  5229. genscheme.animatedsurface.timeanimate:
  5230. T = timevar / 5
  5231. pcountparticleorig = 0
  5232. FOR i = xl TO xr STEP Dx
  5233.     FOR j = yl TO yr STEP Dy
  5234.         pcountparticleorig = pcountparticleorig + 1
  5235.         vec(pcountparticleorig, 1) = i
  5236.         vec(pcountparticleorig, 2) = j
  5237.         vec(pcountparticleorig, 3) = .25 + .25 * COS(i - 2 * T) ^ 2 - .25 * SIN(j - T) ^ 2
  5238.         '*'vec(pcountparticleorig, 4) = 14 'use special color scheme
  5239.     NEXT
  5240.  
  5241. genscheme.animatedpretzel.init:
  5242. rho = 4: beta = .5: a = 1: b = 5: L = 4
  5243. xl = -L: xr = L
  5244. yl = 0: yr = 2 * pi
  5245. Dx = .10: Dy = .157
  5246. xrange = 1 + INT((-xl + xr) / Dx)
  5247. yrange = 1 + INT((-yl + yr) / Dy)
  5248. pcountparticleorig = 0
  5249. FOR i = xl TO xr STEP Dx
  5250.     FOR j = yl TO yr STEP Dy
  5251.         pcountparticleorig = pcountparticleorig + 1
  5252.         R = rho - (T / 100) * beta * (i ^ 2)
  5253.         h = a * SQR(1 - (i / b) ^ 2)
  5254.         k = 1 / SQR((2 * beta * i) ^ 2 + R ^ 2)
  5255.         vec(pcountparticleorig, 1) = R * COS(i) + h * k * (R * COS(i) - 2 * beta * i * SIN(i)) * COS(j)
  5256.         vec(pcountparticleorig, 2) = R * SIN(i) + h * k * (R * SIN(i) + 2 * beta * i * COS(i)) * COS(j)
  5257.         vec(pcountparticleorig, 3) = h * SIN(j)
  5258.         vec(pcountparticleorig, 4) = 5
  5259.     NEXT
  5260.  
  5261. genscheme.animatedpretzel.timeanimate:
  5262. T = timevar
  5263. pcountparticleorig = 0
  5264. FOR i = xl TO xr STEP Dx
  5265.     FOR j = yl TO yr STEP Dy
  5266.         pcountparticleorig = pcountparticleorig + 1
  5267.         R = rho - (T / 100) * beta * (i ^ 2)
  5268.         h = a * SQR(1 - (i / b) ^ 2)
  5269.         k = 1 / SQR((2 * beta * i) ^ 2 + R ^ 2)
  5270.         vec(pcountparticleorig, 1) = R * COS(i) + h * k * (R * COS(i) - 2 * beta * i * SIN(i)) * COS(j)
  5271.         vec(pcountparticleorig, 2) = R * SIN(i) + h * k * (R * SIN(i) + 2 * beta * i * COS(i)) * COS(j)
  5272.         vec(pcountparticleorig, 3) = h * SIN(j)
  5273.         vec(pcountparticleorig, 4) = 5
  5274.     NEXT
  5275.  
  5276. genscheme.sphericalharmonics:
  5277. xl = 0: xr = pi: Dx = .05
  5278. yl = 0: yr = 2 * pi: Dy = .05
  5279. xrange = 1 + INT((-xl + xr) / Dx)
  5280. yrange = 1 + INT((-yl + yr) / Dy)
  5281. L = 0
  5282. ml = 0
  5283. PRINT " Choose the orbital L value (must be >= 0)."
  5284. PRINT: INPUT " Enter a choice: ", L
  5285. IF L < 0 THEN L = 0
  5286. PRINT " Choose the orbital mL value (must have -L < mL < L)."
  5287. PRINT: INPUT " Enter a choice: ", ml
  5288. IF ml < -L THEN ml = -L
  5289. IF ml > L THEN ml = L
  5290. pcountparticleorig = 0
  5291. FOR i = xl TO xr STEP Dx
  5292.     FOR j = yl TO yr STEP Dy
  5293.         pcountparticleorig = pcountparticleorig + 1
  5294.         x0 = 10 * SIN(i) * COS(j)
  5295.         y0 = 10 * SIN(i) * SIN(j)
  5296.         z0 = 10 * COS(i)
  5297.         SELECT CASE L
  5298.             CASE 0
  5299.                 vec(pcountparticleorig, 1) = x0 * (1 / 2) * SQR(1 / pi)
  5300.                 vec(pcountparticleorig, 2) = y0 * (1 / 2) * SQR(1 / pi)
  5301.                 vec(pcountparticleorig, 3) = z0 * (1 / 2) * SQR(1 / pi)
  5302.                 vec(pcountparticleorig, 4) = 9
  5303.             CASE 1
  5304.                 SELECT CASE ml
  5305.                     CASE -1
  5306.                         vec(pcountparticleorig, 1) = x0 * (1 / 2) * SQR(3 / pi) * SIN(i) * COS(j)
  5307.                         vec(pcountparticleorig, 2) = y0 * (1 / 2) * SQR(3 / pi) * SIN(i) * COS(j)
  5308.                         vec(pcountparticleorig, 3) = z0 * (1 / 2) * SQR(3 / pi) * SIN(i) * COS(j)
  5309.                         vec(pcountparticleorig, 4) = 9
  5310.                     CASE 0
  5311.                         vec(pcountparticleorig, 1) = x0 * (1 / 2) * SQR(3 / pi) * COS(i)
  5312.                         vec(pcountparticleorig, 2) = y0 * (1 / 2) * SQR(3 / pi) * COS(i)
  5313.                         vec(pcountparticleorig, 3) = z0 * (1 / 2) * SQR(3 / pi) * COS(i)
  5314.                         vec(pcountparticleorig, 4) = 9
  5315.                     CASE 1
  5316.                         vec(pcountparticleorig, 1) = x0 * (1 / 2) * SQR(3 / pi) * SIN(i) * COS(j)
  5317.                         vec(pcountparticleorig, 2) = y0 * (1 / 2) * SQR(3 / pi) * SIN(i) * COS(j)
  5318.                         vec(pcountparticleorig, 3) = z0 * (1 / 2) * SQR(3 / pi) * SIN(i) * COS(j)
  5319.                         vec(pcountparticleorig, 4) = 9
  5320.                 END SELECT
  5321.             CASE 2
  5322.                 SELECT CASE ml
  5323.                     CASE -2
  5324.                         vec(pcountparticleorig, 1) = x0 * (1 / 2) * SQR(3 / pi) * SIN(i) ^ 2 * COS(2 * j)
  5325.                         vec(pcountparticleorig, 2) = y0 * (1 / 2) * SQR(3 / pi) * SIN(i) ^ 2 * COS(2 * j)
  5326.                         vec(pcountparticleorig, 3) = z0 * (1 / 2) * SQR(3 / pi) * SIN(i) ^ 2 * COS(2 * j)
  5327.                         vec(pcountparticleorig, 4) = 9
  5328.                     CASE -1
  5329.                         vec(pcountparticleorig, 1) = x0 * (1 / 2) * SQR(3 / pi) * SIN(i) * COS(i) * COS(j)
  5330.                         vec(pcountparticleorig, 2) = y0 * (1 / 2) * SQR(3 / pi) * SIN(i) * COS(i) * COS(j)
  5331.                         vec(pcountparticleorig, 3) = z0 * (1 / 2) * SQR(3 / pi) * SIN(i) * COS(i) * COS(j)
  5332.                         vec(pcountparticleorig, 4) = 9
  5333.                     CASE 0
  5334.                         vec(pcountparticleorig, 1) = x0 * (1 / 4) * SQR(5 / pi) * (3 * COS(i) ^ 2 - 1)
  5335.                         vec(pcountparticleorig, 2) = y0 * (1 / 4) * SQR(5 / pi) * (3 * COS(i) ^ 2 - 1)
  5336.                         vec(pcountparticleorig, 3) = z0 * (1 / 4) * SQR(5 / pi) * (3 * COS(i) ^ 2 - 1)
  5337.                         vec(pcountparticleorig, 4) = 9
  5338.                     CASE 1
  5339.                         vec(pcountparticleorig, 1) = x0 * (1 / 2) * SQR(3 / pi) * SIN(i) * COS(i) * COS(j)
  5340.                         vec(pcountparticleorig, 2) = y0 * (1 / 2) * SQR(3 / pi) * SIN(i) * COS(i) * COS(j)
  5341.                         vec(pcountparticleorig, 3) = z0 * (1 / 2) * SQR(3 / pi) * SIN(i) * COS(i) * COS(j)
  5342.                         vec(pcountparticleorig, 4) = 9
  5343.                     CASE 2
  5344.                         vec(pcountparticleorig, 1) = x0 * (1 / 2) * SQR(3 / pi) * SIN(i) ^ 2 * COS(2 * j)
  5345.                         vec(pcountparticleorig, 2) = y0 * (1 / 2) * SQR(3 / pi) * SIN(i) ^ 2 * COS(2 * j)
  5346.                         vec(pcountparticleorig, 3) = z0 * (1 / 2) * SQR(3 / pi) * SIN(i) ^ 2 * COS(2 * j)
  5347.                         vec(pcountparticleorig, 4) = 9
  5348.                 END SELECT
  5349.             CASE 3
  5350.                 SELECT CASE ml
  5351.                     CASE -3
  5352.                     CASE -2
  5353.                     CASE -1
  5354.                     CASE 0
  5355.                     CASE 1
  5356.                     CASE 2
  5357.                     CASE 3
  5358.                 END SELECT
  5359.             CASE ELSE
  5360.                 L = 0
  5361.                 ml = 0
  5362.         END SELECT
  5363.     NEXT
  5364.  
  5365. genscheme.laplace2d.init:
  5366. xl = -5: xr = 5
  5367. yl = -7: yr = 7
  5368. Dx = .25
  5369. Dy = .25
  5370. xrange = 1 + INT((-xl + xr) / Dx)
  5371. yrange = 1 + INT((-yl + yr) / Dy)
  5372. pcountparticleorig = 0
  5373. FOR i = xl TO xr STEP Dx
  5374.     FOR j = yl TO yr STEP Dy
  5375.         pcountparticleorig = pcountparticleorig + 1
  5376.         vec(pcountparticleorig, 1) = i
  5377.         vec(pcountparticleorig, 2) = j
  5378.         vec(pcountparticleorig, 3) = 0
  5379.         vec(pcountparticleorig, 4) = 6
  5380.     NEXT
  5381.  
  5382. genscheme.laplace2d.gridinit:
  5383. pcountparticleorig = 0
  5384. FOR i = 1 TO xrange
  5385.     FOR j = 1 TO yrange
  5386.         pcountparticleorig = pcountparticleorig + 1
  5387.         vec2dzfixed(i, j) = -1
  5388.         '''
  5389.         randnum = RND * 1000
  5390.         IF randnum < 40 AND i > xrange * .33 AND i < xrange * .66 AND j > yrange * .33 AND j < yrange * .66 THEN
  5391.             vec(pcountparticleorig, 3) = RND * 6
  5392.             vec(pcountparticleorig, 4) = 15
  5393.             vec2dzfixed(i, j) = 1
  5394.         END IF
  5395.         IF randnum > 995 THEN
  5396.             vec(pcountparticleorig, 3) = -RND * 5
  5397.             vec(pcountparticleorig, 4) = 1
  5398.             vec2dzfixed(i, j) = 1
  5399.         END IF
  5400.         '''
  5401.         '''
  5402.         '        IF i = 1 THEN
  5403.         '            vec2dzfixed(i, j) = 1
  5404.         '            vec(pcountparticleorig, 3) = pi / 2
  5405.         '        END IF
  5406.         '        IF i = xrange THEN
  5407.         '            vec2dzfixed(i, j) = 1
  5408.         '            vec(pcountparticleorig, 3) = 0
  5409.         '        END IF
  5410.         '        IF j = 1 THEN
  5411.         '            vec2dzfixed(i, j) = 1
  5412.         '            vec(pcountparticleorig, 3) = pi / 2
  5413.         '        END IF
  5414.         '        IF j = yrange THEN
  5415.         '            vec2dzfixed(i, j) = 1
  5416.         '            vec(pcountparticleorig, 3) = pi / 2
  5417.         '        END IF
  5418.         '''
  5419.     NEXT
  5420.  
  5421. genscheme.laplace2d.timeanimate:
  5422. 'delinearize
  5423. pcountparticleorig = 0
  5424. FOR i = 1 TO xrange
  5425.     FOR j = 1 TO yrange
  5426.         pcountparticleorig = pcountparticleorig + 1
  5427.         vec2dztemp(i, j) = vec(pcountparticleorig, 3)
  5428.     NEXT
  5429. 'begin relax process
  5430. FOR i = 2 TO xrange - 1 'boDy, no edges
  5431.     FOR j = 2 TO yrange - 1
  5432.         IF vec2dzfixed(i, j) = -1 THEN
  5433.             rx1 = vec2dztemp(i + 1, j)
  5434.             rx2 = vec2dztemp(i - 1, j)
  5435.             rx3 = vec2dztemp(i, j - 1)
  5436.             rx4 = vec2dztemp(i, j + 1)
  5437.             vec2dz(i, j) = (1 / 4) * (rx1 + rx2 + rx3 + rx4)
  5438.         END IF
  5439.     NEXT
  5440. FOR j = 2 TO yrange - 1 'left edge, right edge, no corners
  5441.     i = 1
  5442.     IF vec2dzfixed(i, j) = -1 THEN
  5443.         rx1 = vec2dztemp(i + 1, j)
  5444.         rx3 = vec2dztemp(i, j - 1)
  5445.         rx4 = vec2dztemp(i, j + 1)
  5446.         vec2dz(i, j) = (1 / 3) * (rx1 + rx3 + rx4)
  5447.     END IF
  5448.     i = xrange
  5449.     IF vec2dzfixed(i, j) = -1 THEN
  5450.         rx2 = vec2dztemp(i - 1, j)
  5451.         rx3 = vec2dztemp(i, j - 1)
  5452.         rx4 = vec2dztemp(i, j + 1)
  5453.         vec2dz(i, j) = (1 / 3) * (rx2 + rx3 + rx4)
  5454.     END IF
  5455. FOR i = 2 TO xrange - 1 'top edge, bottom edge, no corners
  5456.     j = 1
  5457.     IF vec2dzfixed(i, j) = -1 THEN
  5458.         rx1 = vec2dztemp(i + 1, j)
  5459.         rx2 = vec2dztemp(i - 1, j)
  5460.         rx4 = vec2dztemp(i, j + 1)
  5461.         vec2dz(i, j) = (1 / 3) * (rx1 + rx2 + rx4)
  5462.     END IF
  5463.     j = yrange
  5464.     IF vec2dzfixed(i, j) = -1 THEN
  5465.         rx1 = vec2dztemp(i + 1, j)
  5466.         rx2 = vec2dztemp(i - 1, j)
  5467.         rx3 = vec2dztemp(i, j - 1)
  5468.         vec2dz(i, j) = (1 / 3) * (rx1 + rx2 + rx3)
  5469.     END IF
  5470. 'four corners
  5471. IF vec2dzfixed(1, 1) = -1 THEN vec2dz(1, 1) = (1 / 2) * (vec2dztemp(1, 2) + vec2dztemp(2, 1))
  5472. IF vec2dzfixed(xrange, 1) = -1 THEN vec2dz(xrange, 1) = (1 / 2) * (vec2dztemp(xrange - 1, 1) + vec2dztemp(xrange, 2))
  5473. IF vec2dzfixed(1, yrange) = -1 THEN vec2dz(1, yrange) = (1 / 2) * (vec2dztemp(2, yrange) + vec2dztemp(1, yrange - 1))
  5474. IF vec2dzfixed(xrange, yrange) = -1 THEN vec2dz(xrange, yrange) = (1 / 2) * (vec2dztemp(xrange - 1, yrange) + vec2dztemp(xrange, yrange - 1))
  5475. 'relinearize
  5476. pcountparticleorig = 0
  5477. FOR i = 1 TO xrange
  5478.     FOR j = 1 TO yrange
  5479.         pcountparticleorig = pcountparticleorig + 1
  5480.         IF vec2dzfixed(i, j) = -1 THEN vec(pcountparticleorig, 3) = vec2dz(i, j)
  5481.         IF vec2dz(i, j) > 2 THEN vec(pcountparticleorig, 4) = 15
  5482.         IF vec2dz(i, j) < -1 THEN vec(pcountparticleorig, 4) = 1
  5483.     NEXT
  5484.  
  5485. genscheme.planet.init:
  5486. planetradius = 5
  5487. Dx = .0628
  5488. Dy = .0628
  5489. xl = 0: xr = 2 * pi
  5490. yl = 0: yr = pi
  5491. xrange = 1 + INT((-xl + xr) / Dx)
  5492. yrange = 1 + INT((-yl + yr) / Dy)
  5493. pcountparticleorig = 0
  5494. FOR i = 1 TO xrange
  5495.     FOR j = 1 TO yrange
  5496.         pcountparticleorig = pcountparticleorig + 1
  5497.         theta = i * Dx - Dx
  5498.         phi = j * Dy - Dy
  5499.         vec(pcountparticleorig, 1) = planetradius * SIN(phi) * COS(theta)
  5500.         vec(pcountparticleorig, 2) = planetradius * SIN(phi) * SIN(theta)
  5501.         vec(pcountparticleorig, 3) = planetradius * COS(phi)
  5502.         vec(pcountparticleorig, 4) = 2
  5503.         'randnum = RND * 1000
  5504.         'IF randnum > 600 THEN vec(pcountparticleorig, 4) = 2
  5505.     NEXT
  5506.  
  5507. genscheme.planet.gridinit:
  5508. pcountparticleorig = 0
  5509. FOR i = 1 TO xrange
  5510.     FOR j = 1 TO yrange
  5511.         pcountparticleorig = pcountparticleorig + 1
  5512.         theta = i * Dx - Dx
  5513.         phi = j * Dy - Dy
  5514.         vec2dsfixed(i, j) = -1
  5515.         IF phi > pi / 8 AND phi < pi - pi / 8 THEN
  5516.             randnum = RND * 1000
  5517.             IF randnum < 20 THEN
  5518.                 plrad = planetradius + RND * 1.25
  5519.                 vec(pcountparticleorig, 1) = plrad * SIN(phi) * COS(theta)
  5520.                 vec(pcountparticleorig, 2) = plrad * SIN(phi) * SIN(theta)
  5521.                 vec(pcountparticleorig, 3) = plrad * COS(phi)
  5522.                 vec2dsfixed(i, j) = 1
  5523.             END IF
  5524.             IF randnum > 980 THEN
  5525.                 plrad = planetradius - RND * 1.25
  5526.                 vec(pcountparticleorig, 1) = plrad * SIN(phi) * COS(theta)
  5527.                 vec(pcountparticleorig, 2) = plrad * SIN(phi) * SIN(theta)
  5528.                 vec(pcountparticleorig, 3) = plrad * COS(phi)
  5529.                 vec2dsfixed(i, j) = 1
  5530.             END IF
  5531.             vec(pcountparticleorig, 4) = 2
  5532.         ELSE
  5533.             vec(pcountparticleorig, 4) = 15
  5534.         END IF
  5535.     NEXT
  5536.  
  5537. genscheme.planet.timeanimate:
  5538. pcountparticleorig = 0
  5539. FOR i = 1 TO xrange
  5540.     FOR j = 1 TO yrange
  5541.         pcountparticleorig = pcountparticleorig + 1
  5542.         vec2dstemp(i, j) = SQR(vec(pcountparticleorig, 1) ^ 2 + vec(pcountparticleorig, 2) ^ 2 + vec(pcountparticleorig, 3) ^ 2)
  5543.     NEXT
  5544. 'begin relax process
  5545. FOR i = 2 TO xrange - 1 'boDy, no seam
  5546.     FOR j = 2 TO yrange - 1
  5547.         IF vec2dsfixed(i, j) = -1 THEN
  5548.             rx1 = vec2dstemp(i + 1, j)
  5549.             rx2 = vec2dstemp(i - 1, j)
  5550.             rx3 = vec2dstemp(i, j - 1)
  5551.             rx4 = vec2dstemp(i, j + 1)
  5552.             vec2ds(i, j) = (1 / 4) * (rx1 + rx2 + rx3 + rx4)
  5553.         END IF
  5554.     NEXT
  5555. FOR j = 2 TO yrange - 1 'seam
  5556.     IF vec2dsfixed(1, j) = -1 THEN
  5557.         rx1 = vec2dstemp(2, j)
  5558.         rx2 = vec2dstemp(xrange, j)
  5559.         rx3 = vec2dstemp(1, j - 1)
  5560.         rx4 = vec2dstemp(1, j + 1)
  5561.         vec2ds(1, j) = (1 / 4) * (rx1 + rx2 + rx3 + rx4)
  5562.     END IF
  5563.     IF vec2dsfixed(xrange, j) = -1 THEN
  5564.         rx1 = vec2dstemp(1, j)
  5565.         rx2 = vec2dstemp(xrange - 1, j)
  5566.         rx3 = vec2dstemp(xrange, j - 1)
  5567.         rx4 = vec2dstemp(xrange, j + 1)
  5568.         vec2ds(xrange, j) = (1 / 4) * (rx1 + rx2 + rx3 + rx4)
  5569.     END IF
  5570. 'relinearize
  5571. pcountparticleorig = 0
  5572. FOR i = 1 TO xrange
  5573.     FOR j = 1 TO yrange
  5574.         pcountparticleorig = pcountparticleorig + 1
  5575.         IF vec2dsfixed(i, j) = -1 AND j <> 1 AND j <> yrange THEN
  5576.             vec(pcountparticleorig, 1) = vec(pcountparticleorig, 1) * vec2ds(i, j) / vec2dstemp(i, j)
  5577.             vec(pcountparticleorig, 2) = vec(pcountparticleorig, 2) * vec2ds(i, j) / vec2dstemp(i, j)
  5578.             vec(pcountparticleorig, 3) = vec(pcountparticleorig, 3) * vec2ds(i, j) / vec2dstemp(i, j)
  5579.         END IF
  5580.         SELECT CASE SQR(vec(pcountparticleorig, 1) ^ 2 + vec(pcountparticleorig, 2) ^ 2 + vec(pcountparticleorig, 3) ^ 2)
  5581.             CASE IS > planetradius + 0.25
  5582.                 vec(pcountparticleorig, 4) = 6
  5583.             CASE IS < planetradius - 0.25
  5584.                 vec(pcountparticleorig, 4) = 1
  5585.         END SELECT
  5586.     NEXT
  5587.  
  5588. genscheme.wave2d.init:
  5589. xl = -1.9: xr = 1.9
  5590. yl = -1: yr = 1
  5591. xl = xl * 4: xr = xr * 4: yl = yl * 4: yr = yr * 4
  5592. Dx = .32
  5593. Dy = .32
  5594. xrange = 1 + INT((-xl + xr) / Dx)
  5595. yrange = 1 + INT((-yl + yr) / Dy)
  5596. alpha = .25
  5597. pcountparticleorig = 0
  5598. FOR i = xl TO xr STEP Dx
  5599.     FOR j = yl TO yr STEP Dy
  5600.         pcountparticleorig = pcountparticleorig + 1
  5601.         vec(pcountparticleorig, 1) = i
  5602.         vec(pcountparticleorig, 2) = j
  5603.         vec(pcountparticleorig, 3) = 0
  5604.         '*' vec(pcountparticleorig, 4) = 14 'use special color scheme
  5605.     NEXT
  5606.  
  5607. genscheme.wave2d.gridinit:
  5608. 'delinearize
  5609. pcountparticleorig = 0
  5610. FOR i = 1 TO xrange
  5611.     FOR j = 1 TO yrange
  5612.         pcountparticleorig = pcountparticleorig + 1
  5613.         vec2dztemp(i, j) = vec(pcountparticleorig, 3)
  5614.     NEXT
  5615. 'initial position condition
  5616. 'FOR i = 1 TO xrange 'random high points
  5617. '  FOR j = 1 TO yrange
  5618. '      nrand = RND * 1000
  5619. '      IF nrand < 10 THEN
  5620. '          vec2dz(i, j) = 5
  5621. '      END IF
  5622. '  NEXT
  5623. 'NEXT
  5624. 'vec2dz(xrange * .8, yrange * .2) = -2.5 'single plucked point
  5625. 'FOR i = 1 TO xrange 'cross arm
  5626. '   vec2dz(i, yrange / 3) = 2
  5627. 'NEXT
  5628. 'FOR j = 1 TO yrange 'cross arm
  5629. '   vec2dz(xrange / 2, j) = 1
  5630. 'NEXT
  5631. 'sync
  5632. pcountparticleorig = 0
  5633. FOR i = 1 TO xrange
  5634.     FOR j = 1 TO yrange
  5635.         pcountparticleorig = pcountparticleorig + 1
  5636.         vec2dzprev(i, j) = vec2dz(i, j)
  5637.         vec2dztemp(i, j) = vec2dz(i, j)
  5638.     NEXT
  5639. 'initial velocity condition
  5640. vec2dzprev(xrange * .8, yrange * .8) = 1.5 'single struck point
  5641. 'relinearize
  5642. pcountparticleorig = 0
  5643. FOR i = 1 TO xrange
  5644.     FOR j = 1 TO yrange
  5645.         pcountparticleorig = pcountparticleorig + 1
  5646.         vec(pcountparticleorig, 3) = vec2dz(i, j)
  5647.     NEXT
  5648.  
  5649. genscheme.wave2d.timeanimate:
  5650. 'delinearize
  5651. pcountparticleorig = 0
  5652. FOR i = 1 TO xrange
  5653.     FOR j = 1 TO yrange
  5654.         pcountparticleorig = pcountparticleorig + 1
  5655.         vec2dztemp(i, j) = vec(pcountparticleorig, 3)
  5656.     NEXT
  5657. 'begin propagation process
  5658. FOR i = 2 TO xrange - 1 'boDy, no edges
  5659.     FOR j = 2 TO yrange - 1
  5660.         wp1 = alpha * (vec2dztemp(i + 1, j) + vec2dztemp(i - 1, j)) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5661.         wp2 = alpha * (vec2dztemp(i, j + 1) + vec2dztemp(i, j - 1)) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5662.         vec2dz(i, j) = (1 / 2) * (wp1 + wp2)
  5663.     NEXT
  5664. 'comment out this section for fixed edges (or pieces of this section)
  5665. i = 1 'left edge
  5666. FOR j = 2 TO yrange - 1
  5667.     wfp = vec2dztemp(i, j)
  5668.     wp1 = alpha * (vec2dztemp(i + 1, j) + wfp) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5669.     wp2 = alpha * (vec2dztemp(i, j + 1) + vec2dztemp(i, j - 1)) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5670.     'vec2dz(i, j) = (1 / 2) * (wp1 + wp2)
  5671. i = xrange 'right edge
  5672. FOR j = 2 TO yrange - 1
  5673.     wfp = vec2dztemp(i, j)
  5674.     wp1 = alpha * (wfp + vec2dztemp(i - 1, j)) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5675.     wp2 = alpha * (vec2dztemp(i, j + 1) + vec2dztemp(i, j - 1)) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5676.     vec2dz(i, j) = (1 / 2) * (wp1 + wp2)
  5677. j = 1 'bottom edge
  5678. FOR i = 2 TO xrange - 1
  5679.     wfp = vec2dztemp(i, j)
  5680.     wp2 = alpha * (vec2dztemp(i, j + 1) + wfp) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5681.     wp1 = alpha * (vec2dztemp(i + 1, j) + vec2dztemp(i - 1, j)) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5682.     vec2dz(i, j) = (1 / 2) * (wp1 + wp2)
  5683. j = yrange 'top edge
  5684. FOR i = 2 TO xrange - 1
  5685.     wfp = vec2dztemp(i, j)
  5686.     wp2 = alpha * (wfp + vec2dztemp(i, j - 1)) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5687.     wp1 = alpha * (vec2dztemp(i + 1, j) + vec2dztemp(i - 1, j)) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5688.     vec2dz(i, j) = (1 / 2) * (wp1 + wp2)
  5689. 'bottom left corner
  5690. i = 1: j = 1
  5691. wfp1 = vec2dztemp(i, j)
  5692. wfp2 = vec2dztemp(i, j)
  5693. wp1 = alpha * (vec2dztemp(i + 1, j) + wfp1) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5694. wp2 = alpha * (vec2dztemp(i, j + 1) + wfp2) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5695. 'vec2dz(i, j) = (1 / 2) * (wp1 + wp2)
  5696. 'bottom right corner
  5697. i = xrange: j = 1
  5698. wfp1 = vec2dztemp(i, j)
  5699. wfp2 = vec2dztemp(i, j)
  5700. wp1 = alpha * (wfp1 + vec2dztemp(i - 1, j)) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5701. wp2 = alpha * (vec2dztemp(i, j + 1) + wfp2) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5702. vec2dz(i, j) = (1 / 2) * (wp1 + wp2)
  5703. 'top left corner
  5704. i = 1: j = yrange
  5705. wfp1 = vec2dztemp(i, j)
  5706. wfp2 = vec2dztemp(i, j)
  5707. wp1 = alpha * (vec2dztemp(i + 1, j) + wfp1) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5708. wp2 = alpha * (wfp2 + vec2dztemp(i, j - 1)) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5709. 'vec2dz(i, j) = (1 / 2) * (wp1 + wp2)
  5710. 'top right corner
  5711. i = xrange: j = yrange
  5712. wfp1 = vec2dztemp(i, j)
  5713. wfp2 = vec2dztemp(i, j)
  5714. wp1 = alpha * (wfp1 + vec2dztemp(i - 1, j)) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5715. wp2 = alpha * (wfp2 + vec2dztemp(i, j - 1)) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5716. vec2dz(i, j) = (1 / 2) * (wp1 + wp2)
  5717. 'start special movements
  5718. T = timevar / 5
  5719. IF T < pi THEN 'wave left edge just once
  5720.     FOR j = 1 TO yrange
  5721.         i = 1
  5722.         vec2dz(i, j) = (j / yrange) * 1.5 * SIN(T)
  5723.     NEXT
  5724. IF T < pi THEN 'wave bottom edge just once
  5725.     FOR i = 1 TO xrange
  5726.         j = 1
  5727.         vec2dz(i, j) = (i / xrange) * .45 * SIN(T)
  5728.     NEXT
  5729. 'relinearize
  5730. pcountparticleorig = 0
  5731. FOR i = 1 TO xrange
  5732.     FOR j = 1 TO yrange
  5733.         pcountparticleorig = pcountparticleorig + 1
  5734.         vec2dzprev(i, j) = vec2dztemp(i, j)
  5735.         vec2dztemp(i, j) = vec2dz(i, j)
  5736.         vec(pcountparticleorig, 3) = vec2dz(i, j)
  5737.     NEXT
  5738.  
  5739. genscheme.wave2dinf.init:
  5740. xl = -12: xr = 12
  5741. yl = -12: yr = 12
  5742. Dx = .33
  5743. Dy = .33
  5744. xrange = 1 + INT((-xl + xr) / Dx)
  5745. yrange = 1 + INT((-yl + yr) / Dy)
  5746. alpha = .25
  5747. pcountparticleorig = 0
  5748. FOR i = xl TO xr STEP Dx
  5749.     FOR j = yl TO yr STEP Dy
  5750.         pcountparticleorig = pcountparticleorig + 1
  5751.         vec(pcountparticleorig, 1) = i
  5752.         vec(pcountparticleorig, 2) = j
  5753.         vec(pcountparticleorig, 3) = 0
  5754.         vec(pcountparticleorig, 4) = 1
  5755.     NEXT
  5756.  
  5757. genscheme.wave2dinf.gridinit:
  5758. 'delinearize
  5759. pcountparticleorig = 0
  5760. FOR i = 1 TO xrange
  5761.     FOR j = 1 TO yrange
  5762.         pcountparticleorig = pcountparticleorig + 1
  5763.         vec2dzfixed(i, j) = -1
  5764.         vec2dztemp(i, j) = vec(pcountparticleorig, 3)
  5765.     NEXT
  5766. 'set edge damping constants
  5767. xrdamp = INT(xrange / 10)
  5768. yrdamp = INT(yrange / 10)
  5769. 'create fixed heights
  5770. FOR j = 1 TO INT(yrange / 2 - 3)
  5771.     FOR i = INT(xrange / 3 - 5) TO INT(xrange / 3 - 3)
  5772.         vec2dzfixed(i, j) = 1
  5773.         vec2dz(i, j) = 0
  5774.     NEXT
  5775. FOR j = INT(yrange / 2 + 3) TO yrange
  5776.     FOR i = INT(xrange / 3 - 5) TO INT(xrange / 3 - 3)
  5777.         vec2dzfixed(i, j) = 1
  5778.         vec2dz(i, j) = 0
  5779.     NEXT
  5780. 'initial position condition
  5781. 'FOR i = 1 TO xrange 'random high points
  5782. '   FOR j = 1 TO yrange
  5783. '       nrand = RND * 1000
  5784. '       IF nrand < 10 THEN
  5785. '           vec2dz(i, j) = 1
  5786. '       END IF
  5787. '   NEXT
  5788. 'NEXT
  5789. 'i = xrange / 2: j = yrange / 2: vec2dz(i, j) = 8 'pluck middle
  5790. 'sync
  5791. pcountparticleorig = 0
  5792. FOR i = 1 TO xrange
  5793.     FOR j = 1 TO yrange
  5794.         pcountparticleorig = pcountparticleorig + 1
  5795.         vec2dzprev(i, j) = vec2dz(i, j)
  5796.         vec2dztemp(i, j) = vec2dz(i, j)
  5797.     NEXT
  5798. 'initial velocity condition
  5799. 'vec2dzprev(xrange / 2, yrange / 2) = 1.5 'single struck point
  5800. 'relinearize
  5801. pcountparticleorig = 0
  5802. FOR i = 1 TO xrange
  5803.     FOR j = 1 TO yrange
  5804.         pcountparticleorig = pcountparticleorig + 1
  5805.         vec(pcountparticleorig, 3) = vec2dz(i, j)
  5806.         IF i < xrdamp THEN vec(pcountparticleorig, 4) = 8
  5807.         IF i > xrange - xrdamp THEN vec(pcountparticleorig, 4) = 8
  5808.         IF j < yrdamp THEN vec(pcountparticleorig, 4) = 8
  5809.         IF j > yrange - yrdamp THEN vec(pcountparticleorig, 4) = 8
  5810.         IF vec2dzfixed(i, j) = 1 THEN vec(pcountparticleorig, 4) = 4
  5811.     NEXT
  5812.  
  5813. genscheme.wave2dinf.timeanimate:
  5814. 'delinearize
  5815. pcountparticleorig = 0
  5816. FOR i = 1 TO xrange
  5817.     FOR j = 1 TO yrange
  5818.         pcountparticleorig = pcountparticleorig + 1
  5819.         vec2dztemp(i, j) = vec(pcountparticleorig, 3)
  5820.     NEXT
  5821. 'start pre-propagation special movements
  5822. T = timevar
  5823. IF RND * 250 < 10 THEN 'rain drops
  5824.     i = INT(RND * xrange - xrdamp - 2) + xrdamp + 2
  5825.     j = INT(RND * yrange - yrdamp - 2) + yrdamp + 2
  5826.     'IF vec2dzfixed(i, j) = -1 THEN vec2dzprev(i, j) = -2 'set velocity or
  5827.     IF vec2dzfixed(i, j) = -1 THEN vec2dztemp(i, j) = 2 'set position
  5828. 'begin propagation process
  5829. FOR i = 2 TO xrange - 1 'boDy, no edges
  5830.     FOR j = 2 TO yrange - 1
  5831.         vp1 = vec2dztemp(i + 1, j)
  5832.         vp2 = vec2dztemp(i - 1, j)
  5833.         vp3 = vec2dztemp(i, j + 1)
  5834.         vp4 = vec2dztemp(i, j - 1)
  5835.         IF vec2dzfixed(i + 1, j) = 1 THEN vp1 = 0
  5836.         IF vec2dzfixed(i - 1, j) = 1 THEN vp2 = 0
  5837.         IF vec2dzfixed(i, j + 1) = 1 THEN vp3 = 0
  5838.         IF vec2dzfixed(i, j - 1) = 1 THEN vp4 = 0
  5839.         wp1 = alpha * (vp1 + vp2) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5840.         wp2 = alpha * (vp3 + vp4) + 2 * (1 - alpha) * vec2dztemp(i, j) - vec2dzprev(i, j)
  5841.         vec2dz(i, j) = (1 / 2) * (wp1 + wp2)
  5842.     NEXT
  5843. 'damp out motion at edges
  5844. 'left edge
  5845. FOR j = 2 TO yrange - 1
  5846.     FOR i = xrdamp TO 2 STEP -1
  5847.         vec2dz(i, j) = (1 / 4) * (vec2dztemp(i, j) + vec2dztemp(i + 1, j) + vec2dztemp(i, j + 1) + vec2dztemp(i, j - 1))
  5848.     NEXT
  5849. 'right edge
  5850. FOR j = 2 TO yrange - 1
  5851.     FOR i = (xrange - xrdamp) TO (xrange - 1)
  5852.         vec2dz(i, j) = (1 / 4) * (vec2dztemp(i, j) + vec2dztemp(i - 1, j) + vec2dztemp(i, j + 1) + vec2dztemp(i, j - 1))
  5853.     NEXT
  5854. 'bottom edge
  5855. FOR i = 2 TO xrange - 1
  5856.     FOR j = yrdamp TO 2 STEP -1
  5857.         vec2dz(i, j) = (1 / 4) * (vec2dztemp(i, j) + vec2dztemp(i, j + 1) + vec2dztemp(i + 1, j) + vec2dztemp(i - 1, j))
  5858.     NEXT
  5859. 'top edge
  5860. FOR i = 2 TO xrange - 1
  5861.     FOR j = (yrange - yrdamp) TO (yrange - 1)
  5862.         vec2dz(i, j) = (1 / 4) * (vec2dztemp(i, j) + vec2dztemp(i, j - 1) + vec2dztemp(i + 1, j) + vec2dztemp(i - 1, j))
  5863.     NEXT
  5864. 'adjust for error caused by boundary conditions
  5865. nrbcerr = 0
  5866. FOR j = 1 TO yrange
  5867.     nrbcerr = nrbcerr + vec2dz(xrange - 1, j)
  5868.     nrbcerr = nrbcerr + vec2dz(2, j)
  5869. FOR i = 1 TO xrange
  5870.     nrbcerr = nrbcerr + vec2dz(i, yrange - 1)
  5871.     nrbcerr = nrbcerr + vec2dz(i, 2)
  5872. nrbcerr = nrbcerr / (2 * xrange + 2 * yrange)
  5873. 'start post-propagation special movements
  5874. 'IF t < pi THEN 'wave middle just once
  5875. '   i = xrange / 2
  5876. '   j = yrange / 2
  5877. '   vec2dz(i, j) = -4.5 * SIN(t)
  5878. 'END IF
  5879. 'IF t < pi THEN 'wave some place
  5880. FOR j = 1 + 2.5 * yrdamp TO yrange - 2.5 * yrdamp
  5881.     i = xrdamp + 1
  5882.     vec2dz(i, j) = .75 * SIN(.5 * T)
  5883. 'END IF
  5884. 'relinearize and correct for nonreflecting boundary condition error
  5885. pcountparticleorig = 0
  5886. FOR i = 1 TO xrange
  5887.     FOR j = 1 TO yrange
  5888.         pcountparticleorig = pcountparticleorig + 1
  5889.         vec2dzprev(i, j) = vec2dztemp(i, j) - nrbcerr
  5890.         vec2dztemp(i, j) = vec2dz(i, j) - nrbcerr
  5891.         IF vec2dzfixed(i, j) = -1 THEN vec(pcountparticleorig, 3) = vec2dz(i, j) - nrbcerr
  5892.         IF vec2dzfixed(i, j) = -1 AND i >= xrdamp AND i <= xrange - xrdamp AND j >= yrdamp AND j <= yrange - yrdamp THEN
  5893.             IF vec2dz(i, j) > .2 THEN vec(pcountparticleorig, 4) = 9 ELSE vec(pcountparticleorig, 4) = 1
  5894.         END IF
  5895.     NEXT
  5896.  
  5897. genscheme.bacteria.init:
  5898. gridxhalfsize = 50
  5899. gridyhalfsize = 50
  5900. gridzhalfsize = 50
  5901. gridxstep = 2
  5902. gridystep = 2
  5903. gridzstep = 2
  5904. numcreatures1 = numcreatures
  5905. numcreatures2 = 0
  5906. numcreatures3 = 0
  5907. creatureinitrad = 0.5
  5908. pcountparticleorig = 0
  5909. FOR i = 1 TO numcreatures
  5910.     pcountparticleorig = pcountparticleorig + 1
  5911.     vec(pcountparticleorig, 5) = .15 'step constant
  5912.     vec(pcountparticleorig, 6) = creatureinitrad 'creature radius
  5913.     vec(pcountparticleorig, 7) = vec(pcountparticleorig, 6) 'old creature radius
  5914.     IF RND > .5 THEN 'determine gender of species 1
  5915.         vec(pcountparticleorig, 4) = 9
  5916.         vec(pcountparticleorig, 8) = 1 'species 1 male
  5917.     ELSE
  5918.         vec(pcountparticleorig, 4) = 13
  5919.         vec(pcountparticleorig, 8) = 2 'species 1 female
  5920.     END IF
  5921.     placecreature:
  5922.     vec(pcountparticleorig, 1) = RND * (2 * gridxhalfsize) - gridxhalfsize 'x position
  5923.     vec(pcountparticleorig, 2) = RND * (2 * gridyhalfsize) - gridyhalfsize 'y position
  5924.     vec(pcountparticleorig, 3) = RND * (2 * gridzhalfsize) - gridzhalfsize 'z position
  5925.     FOR j = 1 TO i 'initial overlap prevention
  5926.         IF i <> j THEN
  5927.             deltax = vec(i, 1) - vec(j, 1)
  5928.             deltay = vec(i, 2) - vec(j, 2)
  5929.             deltaz = vec(i, 3) - vec(j, 3)
  5930.             deltar = SQR(deltax ^ 2 + deltay ^ 2 + deltaz ^ 2)
  5931.             IF deltar < (vec(i, 6) + vec(j, 6)) THEN GOTO placecreature
  5932.         END IF
  5933.     NEXT
  5934.  
  5935. genscheme.bacteria.timeanimate:
  5936. FOR i = 1 TO numcreatures
  5937.     'store old creature radius
  5938.     vec(i, 7) = vec(i, 6)
  5939.     'determine if creature grows in radius
  5940.     IF RND > .66 THEN
  5941.         vec(i, 6) = vec(i, 6) * (1 + RND * 0.001)
  5942.     END IF
  5943.     'creature is too large and explodes
  5944.     IF vec(i, 6) > 8 * creatureinitrad THEN
  5945.         vec(i, 6) = creatureinitrad
  5946.         SELECT CASE vec(i, 8) 'erase creature count of particular species
  5947.             CASE 1: numcreatures1 = numcreatures1 - 1
  5948.             CASE 2: numcreatures1 = numcreatures1 - 1
  5949.             CASE 3: numcreatures2 = numcreatures2 - 1
  5950.             CASE 4: numcreatures2 = numcreatures2 - 1
  5951.             CASE 5: numcreatures3 = numcreatures3 - 1
  5952.             CASE 6: numcreatures3 = numcreatures3 - 1
  5953.         END SELECT
  5954.         'perform weighted average over species for replacement creature
  5955.         j1 = RND * numcreatures1
  5956.         j2 = RND * numcreatures2
  5957.         j3 = RND * numcreatures3
  5958.         IF j1 > j2 AND j1 > j3 THEN
  5959.             numcreatures1 = numcreatures1 + 1
  5960.             IF RND > .5 THEN
  5961.                 vec(i, 4) = 9
  5962.                 vec(i, 8) = 1 'species 1 male
  5963.             ELSE
  5964.                 vec(i, 4) = 13
  5965.                 vec(i, 8) = 2 'species 1 female
  5966.             END IF
  5967.         END IF
  5968.         IF j2 > j1 AND j2 > j3 THEN
  5969.             numcreatures2 = numcreatures2 + 1
  5970.             IF RND > .5 THEN
  5971.                 vec(i, 4) = 14
  5972.                 vec(i, 8) = 3 'species 2 male
  5973.             ELSE
  5974.                 vec(i, 4) = 15
  5975.                 vec(i, 8) = 4 'species 2 female
  5976.             END IF
  5977.         END IF
  5978.         IF j3 > j1 AND j3 > j2 THEN
  5979.             numcreatures3 = numcreatures3 + 1
  5980.             IF RND > .99 THEN
  5981.                 IF RND > .5 THEN
  5982.                     vec(i, 4) = 11
  5983.                     vec(i, 8) = 5 'species 3 male
  5984.                 ELSE
  5985.                     vec(i, 4) = 11
  5986.                     vec(i, 8) = 6 'species 3 female
  5987.                 END IF
  5988.             END IF
  5989.         END IF
  5990.     END IF
  5991.     'move creature in random direction (to fix)
  5992.     creaturexstep = (RND - .5)
  5993.     creatureystep = (RND - .5)
  5994.     creaturezstep = (RND - .5)
  5995.     stepmag = SQR(creaturexstep ^ 2 + creatureystep ^ 2 + creaturezstep ^ 2)
  5996.     creaturexstep = creaturexstep / stepmag
  5997.     creatureystep = creatureystep / stepmag
  5998.     creaturezstep = creaturezstep / stepmag
  5999.     vec(i, 1) = vec(i, 1) + creaturexstep * vec(i, 5) * (1 + 1.5 / vec(i, 6))
  6000.     vec(i, 2) = vec(i, 2) + creatureystep * vec(i, 5) * (1 + 1.5 / vec(i, 6))
  6001.     vec(i, 3) = vec(i, 3) + creaturezstep * vec(i, 5) * (1 + 1.5 / vec(i, 6))
  6002.     'collision with wall
  6003.     IF vec(i, 1) >= gridxhalfsize THEN vec(i, 1) = vec(i, 1) - creaturexstep
  6004.     IF vec(i, 1) <= -gridxhalfsize THEN vec(i, 1) = vec(i, 1) - creaturexstep
  6005.     IF vec(i, 2) >= gridyhalfsize THEN vec(i, 2) = vec(i, 2) - creatureystep
  6006.     IF vec(i, 2) <= -gridyhalfsize THEN vec(i, 2) = vec(i, 2) - creatureystep
  6007.     IF vec(i, 3) >= gridzhalfsize THEN vec(i, 3) = vec(i, 3) - creaturezstep
  6008.     IF vec(i, 3) <= -gridzhalfsize THEN vec(i, 3) = vec(i, 3) - creaturezstep
  6009.     'ckeck for collision with another creature
  6010.     FOR j = 1 TO numcreatures
  6011.         IF i <> j THEN
  6012.             deltax = vec(i, 1) - vec(j, 1)
  6013.             deltay = vec(i, 2) - vec(j, 2)
  6014.             deltaz = vec(i, 3) - vec(j, 3)
  6015.             deltar = SQR(deltax ^ 2 + deltay ^ 2 + deltaz ^ 2)
  6016.             'collision between mature creatures
  6017.             IF deltar < (vec(i, 6) + vec(j, 6)) AND vec(i, 6) > 1.5 * creatureinitrad AND vec(j, 6) > 1.5 * creatureinitrad THEN
  6018.                 IF vec(i, 8) <> vec(j, 8) THEN 'collision between opposing genders
  6019.                     vec(i, 1) = vec(i, 1) - creaturexstep
  6020.                     vec(i, 2) = vec(i, 2) - creatureystep
  6021.                     vec(i, 3) = vec(i, 3) - creaturezstep
  6022.                     'species 1 mating
  6023.                     IF vec(i, 8) >= 1 AND vec(i, 8) <= 2 AND vec(j, 8) >= 1 AND vec(j, 8) <= 2 THEN
  6024.                         IF RND > .95 THEN 'determine if offspring is mutates to species 2
  6025.                             numcreatures1 = numcreatures1 - 1
  6026.                             numcreatures2 = numcreatures2 + 1
  6027.                             IF RND > .5 THEN 'determine gender of species 2
  6028.                                 vec(i, 4) = 14
  6029.                                 vec(i, 8) = 3 'species 2 male
  6030.                             ELSE
  6031.                                 vec(i, 4) = 15
  6032.                                 vec(i, 8) = 4 'species 2 female
  6033.                             END IF
  6034.                         END IF
  6035.                         GOTO donemating
  6036.                     END IF
  6037.                     'species 2 mating
  6038.                     IF vec(i, 8) >= 3 AND vec(i, 8) <= 4 AND vec(j, 8) >= 3 AND vec(j, 8) <= 4 THEN
  6039.                         IF RND > .95 THEN 'determine if offspring is mutates to species 3
  6040.                             numcreatures2 = numcreatures2 - 1
  6041.                             numcreatures3 = numcreatures3 + 1
  6042.                             IF RND > .5 THEN 'determine gender of species 3
  6043.                                 vec(i, 4) = 11
  6044.                                 vec(i, 8) = 5 'species 3 male
  6045.                             ELSE
  6046.                                 vec(i, 4) = 11
  6047.                                 vec(i, 8) = 6 'species 3 female
  6048.                             END IF
  6049.                         END IF
  6050.                         GOTO donemating
  6051.                     END IF
  6052.                     donemating:
  6053.                     vec(i, 6) = creatureinitrad
  6054.                 END IF
  6055.             END IF
  6056.         END IF
  6057.     NEXT
  6058.  
  6059. genscheme.neuron.init:
  6060. numneuralnodes = 75
  6061. brainsize = 350
  6062. pcountparticleorig = 0
  6063. FOR i = 1 TO numneuralnodes
  6064.     pcountparticleorig = pcountparticleorig + 1
  6065.     vec(pcountparticleorig, 1) = brainsize * (RND - .5)
  6066.     vec(pcountparticleorig, 2) = brainsize * (RND - .5)
  6067.     vec(pcountparticleorig, 3) = brainsize * (RND - .5) / 5
  6068.     vec(pcountparticleorig, 4) = 14
  6069.     vec(pcountparticleorig, 5) = i 'node index
  6070.     vec(pcountparticleorig, 6) = -1 'stimulation index (-1 for no stimulation)
  6071.     vec(pcountparticleorig, 7) = 0 'dead time counter
  6072. FOR i = 1 TO numneuralnodes
  6073.     FOR j = 2 TO 21
  6074.         pcountparticleorig = pcountparticleorig + 1
  6075.         neuronxstep = (RND - .5)
  6076.         neuronystep = (RND - .5)
  6077.         neuronzstep = (RND - .5)
  6078.         stepmag = SQR(neuronxstep ^ 2 + neuronystep ^ 2 + neuronzstep ^ 2)
  6079.         neuronxstep = neuronxstep / stepmag
  6080.         neuronystep = neuronystep / stepmag
  6081.         neuronzstep = neuronzstep / stepmag
  6082.         vec(pcountparticleorig, 1) = vec(i, 1) + .25 * neuronxstep * (brainsize * RND)
  6083.         vec(pcountparticleorig, 2) = vec(i, 2) + .25 * neuronystep * (brainsize * RND)
  6084.         vec(pcountparticleorig, 3) = vec(i, 3) + .25 * neuronzstep * (brainsize * RND) / 3
  6085.         vec(pcountparticleorig, 4) = 7
  6086.         vec(pcountparticleorig, 5) = i
  6087.         vec(pcountparticleorig, 6) = -1
  6088.         vec(pcountparticleorig, 7) = 0
  6089.     NEXT
  6090. randomneuron = INT(RND * (pcountparticleorig - numneuralnodes)) + numneuralnodes
  6091. vec(randomneuron, 4) = 14
  6092. vec(randomneuron, 6) = 1
  6093.  
  6094. 'Things to check:
  6095. 'Question: is nhat.old a necessary construction?
  6096. 'Question: is work.nhat a necessary construction?
  6097. 'Unify snipworkpcount nomenclature
  6098. 'There is an overall minus sign problem somewhere:
  6099. '   doublets and particles clip differenetly for nearplane.
  6100. '       This may have been solved. See comment below, too.
  6101. ' The triplet snipping broke after I started playing with
  6102. ' the normal vector. The temporary patch is the two calls of
  6103. ' the function reverse.uvnhat. Triplet viewplane clipping has
  6104. ' not been retested.
  6105. 'The 'file' input mode for particle world has not been re-
  6106. ' tested since the simple time animation setup, June 2013.
  6107.  
  6108. genscheme.neuron.timeanimate:
  6109. FOR i = 1 TO numparticleorig
  6110.     vecpuvsrev(i, 1) = vec(i, 1)
  6111.     vecpuvsrev(i, 2) = vec(i, 2)
  6112.     vecpuvsrev(i, 3) = vec(i, 3)
  6113.     vecpuvsrev(i, 4) = vec(i, 4)
  6114.     vecpuvsrev(i, 5) = vec(i, 5)
  6115.     vecpuvsrev(i, 6) = vec(i, 6)
  6116.     vecpuvsrev(i, 7) = vec(i, 7)
  6117. FOR i = numneuralnodes + 1 TO numparticleorig
  6118.     'single neuron activates whole cluster if cluster is ready
  6119.     IF vecpuvsrev(i, 6) = 1 AND vecpuvsrev(vecpuvsrev(i, 5), 6) = -1 AND vecpuvsrev(vecpuvsrev(i, 5), 7) = 0 THEN
  6120.         vec(vec(i, 5), 6) = 1
  6121.         vec(vec(i, 5), 7) = 3000
  6122.         FOR j = numneuralnodes + 1 TO numparticleorig
  6123.             IF vecpuvsrev(i, 5) = vecpuvsrev(j, 5) THEN
  6124.                 vec(j, 4) = 4
  6125.                 vec(j, 6) = 1
  6126.             END IF
  6127.         NEXT
  6128.     END IF
  6129.     'cluster is fully active: probe neighbors and then become inactive
  6130.     IF vecpuvsrev(i, 6) = 1 AND vecpuvsrev(vecpuvsrev(i, 5), 6) = 1 THEN
  6131.         vec(i, 4) = 7
  6132.         vec(i, 6) = -1
  6133.         vec(vec(i, 5), 6) = -1
  6134.         FOR j = numneuralnodes + 1 TO numparticleorig
  6135.             IF vecpuvsrev(i, 5) <> vecpuvsrev(j, 5) THEN
  6136.                 vecsep = SQR((vecpuvsrev(j, 1) - vecpuvsrev(i, 1)) ^ 2 + (vecpuvsrev(j, 2) - vecpuvsrev(i, 2)) ^ 2 + (vecpuvsrev(j, 3) - vecpuvsrev(i, 3)) ^ 2)
  6137.                 IF vecsep < 7 AND vecpuvsrev(j, 6) = -1 THEN
  6138.                     vec(j, 4) = 7
  6139.                     vec(j, 6) = 1
  6140.                 END IF
  6141.             END IF
  6142.         NEXT
  6143.     END IF
  6144.     IF vec(vec(i, 5), 7) > 0 THEN vec(vec(i, 5), 7) = vec(vec(i, 5), 7) - 1
  6145.  
  6146. '*'
« Last Edit: February 12, 2019, 07:40:40 pm by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
Re: Sanctum: Open world 3D engine using CIRCLE and LINE
« Reply #22 on: February 12, 2019, 09:36:22 pm »
Must be nap time at the forums! I'm breaking radio silence to properly bump this topic with a code update on the first page. I recommend entering the world, and then simply holding "n" to start crumbing everything in sight (is that even a verb?). I'm still pretty happy with how the explosions work. Walk around and destroy anything and watch those same particles fly everywhere. This isn't your ordinary video game explosion where they just superimpose fire and debris over a disappearing object. The trash stays around.

Of course, you can always press "b" to create cubes, "n", to blow things up, or "k" to delete outright. Everything is vulnerable to your explosive wrath: the ground, the sky, the sun and moon, even the stars themselves. The screenshot below really does no justice - I tried to capture the clock blowing up - but give it a run for full effect.

boom.png
« Last Edit: February 12, 2019, 10:55:43 pm by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
Re: Sanctum: Open world 3D engine using CIRCLE and LINE
« Reply #23 on: February 17, 2019, 01:44:29 pm »
Hi guys
it seems that STxAxTIC can stimulate your brains...

Very cool 3D engine STxAxTIC!!!
It seems to be adaptable to other way to create images on the screen, just thinking to th Pete's version in ASCII.

Thanks to share!
Programming isn't difficult, only it's  consuming time and coffee