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
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.
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
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...