basicapple-ii

In my 3D Renderer in Apple 2, one of the vertices is at the wrong position


I have been trying to make a 3D renderer in the Apple ii using Applesoft Basic. The renderer uses the Weak Perspective Projection. However when I try rendering a cube, one of the vertices, specifically the second one I draw is way above where it should be and I can't seem to find out why. The code isn't very well commented but hopefully you can find what is wrong.

5     hgr : hgr2
7     SC = 0
8     gosub 2000
9     ANGLE = 0
10    FOCAL = 10
20    X = -10
30    Y = -10
35    Y2 = Y
40    Z = 1
45    gosub 2100
50    rem function to get projected values
60    gosub 1000
80    hplot XP, YP
90    X1 = XP : Y1 = YP
100   X = 10
101   Y = -10
102   Y2 = Y
103   Z = 1
104   gosub 2100
130   rem getProjected
140   gosub 1000
160   X2 = XP : Y2 = YP
165   hplot X2, Y2
170   X = 10
180   Y = 10
185   Y2 = Y
190   Z = 1
195   gosub 2100
200   gosub 1000
210   X3 = XP : Y3 = YP
215   hplot X3, Y3
220   X = -10
230   Y = 10
235   Y2 = Y
240   Z = 1
245   gosub 2100
250   gosub 1000
260   X4 = XP : Y4 = YP
270   hplot X4, Y4
280   X = -10
290   Y = -10
295   Y2 = Y
300   Z = -10
305   gosub 2100
310   gosub 1000
330   X5 = XP : Y5 = YP
340   hplot X5, Y5
350   X = 30
360   Y = -10
365   Y2 = Y
370   Z = -10
375   gosub 2100
380   gosub 1000
390   X6 = XP : Y6 = YP
400   hplot X6, Y6
410   X = 10
420   Y = 10
425   Y2 = Y
435   gosub 2100
440   gosub 1000
450   X7 = XP : Y7 = YP
460   hplot X7, Y7
470   X = -30
480   Y = 10
485   Y2 = Y
490   Z = 10
495   gosub 2100
500   gosub 1000
510   X8 = XP : Y8 = YP
520   hplot X8, Y8
900   hplot X1, Y1 to X2, Y2
910   hplot X2, Y2 to X3, Y3
920   hplot X3, Y3 to X4, Y4
930   hplot X4, Y4 to X1, Y1
940   hplot X1, Y1 to X5, Y5
950   hplot X2, Y2 to X6, Y6
960   hplot X3, Y3 to X7, Y7
970   hplot X4, Y4 to X8, Y8
980   hplot X5, Y5 to X6, Y6
990   hplot X6, Y6 to X7, Y7
991   hplot X7, Y7 to X8, Y8
992   hplot X8, Y8 to X5, Y5
993   SC = 1
994   gosub 2000
995   goto 5000
1000  rem function get projected
1010  XP = FOCAL * X / FOCAL + Z
1020  YP = FOCAL * Y / FOCAL + Z
1030  XP = XP + 140 : YP = YP + 80
1040  if XP > 280 then XP = XP - 140
1050  if YP > 160 then YP = YP - 80
1060  return
2000  rem change screen buffer
2010  poke 49236 + not SC, 0
2020  poke 230, 32 + 32 * SC
2030  call 62450
2040  return
2099  rem get x rotated values
2100  Y = Y * COS( ANGLE ) - Z * SIN( ANGLE )
2110  Z = Y2 * SIN( ANGLE ) + Z * COS( ANGLE )
2120  return
5000  call 62450

The Cube I am trying to render

I have tried messing around with the code for a bit and changing the position of the vertices, however the same vertex still stays in the same place no matter what.


Solution

  • The code is missing a line 430 with setup for Z

    The gosub 2100 at line 375 has changed Z to some value unsuitable for the next invokation of the subroutine at line 435.

    370   Z = -10
    375   gosub 2100         : rem -> Y, Z
    380   gosub 1000         : rem -> XP, YP
    390   X6 = XP : Y6 = YP
    400   hplot X6, Y6
    410   X = 10
    420   Y = 10
    425   Y2 = Y
    430                       <<<< Z = 10
    435   gosub 2100
    440   gosub 1000
    

    The other reason why it fails

    Because ANGLE=0, the lines

    2100  Y = Y * COS( ANGLE ) - Z * SIN( ANGLE )
    2110  Z = Y2 * SIN( ANGLE ) + Z * COS( ANGLE )
    

    don't change Y nor Z. Therefore the lines

    1010  XP = FOCAL * X / FOCAL + Z
    1020  YP = FOCAL * Y / FOCAL + Z
    1030  XP = XP + 140 : YP = YP + 80
    

    make XP = X + Z + 140 and YP = Y + Z + 80.
    This produces next points:

    P1(131,71)
    P2(151,71)
    P3(151,91)
    P4(131,91)
    P5(120,60)
    P6(160,60)
    P7(160,100)
    P8(120,100)
    

    Looking at the picture, it is P2 that is incorrect.
    And then we return to the code that saves P2 in its variables X2 and Y2 only to discover that you are using Y2 for another purpose at the same time! You are using it as the backup for Y (as needed in the subroutine at 2100).

    The solution would be to rename that backup variable. Might I suggest something like YY or YB. To be applied on 9 different spots in the program...