4 месяца назад увидел эту программу и собирался переделать код. Я уже писал, что BBC Basic это вынос мозга и сегодня убедился в этом. Оригинал программы:
https://bbcmic.ro/?t=dBGeD
MODE1
V%=56
DIMX%(11),Y%(11),U%(11),V%(11):S=PI/3
W%=V%*SQR3:D%=V%*3/2
FORL%=1TO11:X%(L%)=SIN(L%*S)*V%:Y%(L%)=COS(L%*S)*V%
U%(L%)=(X%(L%)+X%(L%-1))/2:V%(L%)=(Y%(L%)+Y%(L%-1))/2
NEXT
FORY%=0TOD%+1024-W%STEPD%
O%=O%EOR1
FORX%=O%*W%/2TO1280+W%/2STEPW%
VDU29,X%;Y%;
GCOL0,1:MOVEX%(5),Y%(5):FORL%=6TO8:DRAWX%(L%),Y%(L%):NEXT
M%=-NOTRND(6)
GCOL0,2
MOVEX%(M%),Y%(M%):MOVEU%(M%),V%(M%)
PLOT&A5,X%(M%+1),Y%(M%+1)
FORL%=M%-1TOM%
MOVEU%(4+L%)*2,V%(4+L%)*2:MOVEU%(3+L%),V%(3+L%)
PLOT&A5,X%(4+L%),Y%(4+L%)
NEXT,,
PRINT"One Hexagonal tile";
VDU5,1
Первое, что непонятно - выражение M%=-NOTRND(6). Google подсказал, что происходит. Проверю:
Ух, уже легче. Дальше сложнее, потому что используется PLOT&A5 - это рисование дуги, я давно споткнулся на этом алгоритме. Чтение доков подсказало, что для вызова рисования задаются координаты начальной и конечной точек. Попытался написать - нифига не вышло. Google сегодня стал любезен и после запроса подсказал алгоритм:
DEF PROCarc(xc, yc, x1, y1, x2, y2, r)
LOCAL a1, a2, da, steps, a, px, py
REM Calculate start and end angles
a1 = ATN(y1 - yc, x1 - xc)
a2 = ATN(y2 - yc, x2 - xc)
REM Adjust for direction if crossing zero/2*PI
IF a2 < a1 THEN a2 = a2 + 2 * PI
steps = 20 : REM Number of line segments approximating the arc
da = (a2 - a1) / steps
MOVE x1, y1
FOR a = a1 + da TO a2 STEP da
px = xc + r * COS(a)
py = yc + r * SIN(a)
PLOT 5, px, py : REM Draw relative/absolute line segments
NEXT a
ENDPROC
На экране получилась каша. Оказалось, что я не учел вызов VDU29, который задает начальное происхождение для экрана. Исправил - теперь часть дуги рисуется как половина. Добавил код - заработало! Остался еще один замудреный код и я не знаю, когда возьмусь за эту расшифровку.
Исходник программы:
; https://bbcmic.ro/?t=dBGeD
v=56
Dim X(11)
Dim Y(11)
Dim U(11)
Dim V(11)
S.f=#PI/3
W=V*Sqr(3)
D=V*3/2
RandomSeed(1234)
Procedure arc(xc, yc, x1, y1, x2, y2);centre point,starting point,ending point
; REM Calculate start And End angles
a1.f = ATan2(x1 - xc,y1 - yc)
a2.f = ATan2(x2 - xc,y2 - yc)
;REM Adjust For direction If crossing zero/2*PI
If a2 < a1
a2 = a2 + 2 * #PI
EndIf
steps = 50; : REM Number of line segments approximating the arc
da.f = (a2 - a1) / steps
a.f=a1
r.f=Sqr((x1-xc)*(x1-xc)+(y1-yc)*(y1-yc))
While a<a2;For a = a1 + da To a2 Step da
px = xc + r * Cos(a)
py = yc + r * Sin(a)
;PLOT 5, px, py : REM Draw relative/absolute line segments
Box(px,py,1,1,RGB(255,255,0))
a=a+da
Wend;Next a
EndProcedure
If OpenWindow(0, 0, 0, 320,320, "Hex tile", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 320,320)
If StartDrawing(CanvasOutput(0))
Box(0,0,GadgetWidth(0),GadgetHeight(0),0)
X(0)=Sin(0*S)*V
Y(0)=Cos(0*S)*V
For L=1 To 11
X(L)=Sin(L*S)*V
Y(L)=Cos(L*S)*V
U(L)=(X(L)+X(L-1))/2
V(L)=(Y(L)+Y(L-1))/2
Next L
O=0
Y=0
While Y<D+320;-W
O=O!1
x=o*w/2
While x<320+w/2
xo=x
yo=y
xp=x(5)
yp=y(5)
For L=6 To 8
LineXY(xo+xp,yo+yp,x(l)+xo,y(l)+yo,255)
xp=x(l)
yp=y(l)
Next L
m=Random(6,1)
arc(xo+x(m),yo+y(m),xo+u(m),yo+v(m),xo+x(m+1),yo+y(m+1))
For L=M-1 To M
arc(xo+U(4+L)*2,yo+V(4+L)*2,xo+U(3+L),yo+V(3+L),xo+X(4+L),yo+Y(4+L))
Next l
x=x+w
Wend
y=y+d
Wend
StopDrawing()
EndIf
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf



Комментарии
Отправить комментарий