Hex tile

 

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


Комментарии