В моем 3D-рендерере в Apple 2 одна из вершин находится в неправильном положении.
Я пытался создать 3D-рендерер в Apple ii, используя Applesoft Basic. Рендерер использует проекцию слабой перспективы. Однако, когда я пытаюсь визуализировать куб, одна из вершин, особенно вторая, которую я рисую, находится намного выше того места, где она должна быть, и я не могу понять, почему. Код не очень хорошо прокомментирован, но, надеюсь, вы сможете найти, что не так.
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
Я попробовал немного повозиться с кодом и изменить положение вершин, однако одна и та же вершина все равно остается на том же месте, несмотря ни на что.
1 ответ
В коде отсутствует строка 430 с настройкой для Z.
The gosub 2100
в строке 375 изменил Z на какое-то значение, непригодное для следующего вызова подпрограммы в строке 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
Другая причина, почему это не удается
Поскольку ANGLE=0, линии
2100 Y = Y * COS( ANGLE ) - Z * SIN( ANGLE ) 2110 Z = Y2 * SIN( ANGLE ) + Z * COS( ANGLE )
не меняйте ни Y, ни Z. Поэтому строки
1010 XP = FOCAL * X / FOCAL + Z 1020 YP = FOCAL * Y / FOCAL + Z 1030 XP = XP + 140 : YP = YP + 80
делатьXP = X + Z + 140
иYP = Y + Z + 80
.
Это приводит к следующим пунктам:
P1(131,71)
P2(151,71)
P3(151,91)
P4(131,91)
P5(120,60)
P6(160,60)
P7(160,100)
P8(120,100)
Судя по картинке, неверно именно P2.
А затем мы возвращаемся к коду, который сохраняет P2 в своих переменных X2 и Y2, только чтобы обнаружить, что вы одновременно используете Y2 для другой цели! Вы используете его в качестве резервной копии для Y (по мере необходимости в подпрограмме на 2100).
Решением было бы переименовать эту резервную переменную. Могу ли я предложить что-то вроде YY или YB. Применяется в 9 различных местах программы...