Fractal para quem precisa de fractal

À guisa de (falei bonito agora, hein?) continuação do post sobre cartões SMS em mainframes, Ken Shirriff ficou sabendo que havia um IBM 1401 funcional no Computer History Museum e lá foi-se ele pra brincar com a criança. Brincar do que? Ora, de fazer um programa para imprimir o Conjunto de Mandelbrot. Em que linguagem? Assembler em cartões perfurados, claro, porque linguagem de alto nível, monitor e teclado são para os fracos.

mandelbrot-1401-and-printer

Mas calma que a história não acaba por aí…

Na discussão que se seguiu no Ycombinator, o usuário de codinome fractallyte narra uma aventura mandelbrótica similar, agora com um Commodore 64 e uma impressora matricial Epson RX80, ocorrida em 1986. E o/a camarada ainda tem os printouts!

Mandelbrot-C64

Outro fractaleiro militante e juramentado, Dave LeCompte, também entrou na festa com uma rotina em Assembler 6502 para o Apple II:

MandelbrotAppleII

E a festa não tem hora pra acabar. Só não vale dançar homem com homem nem mulher com m… peraí, o que estou dizendo, estamos no século XXI, vale isso também! Vai te catar, Tim Maia.

Contribuição, digo, contribuições de última hora do Giovanni

A primeira contribuição é um código bem singelo e divertido para o MSX2 e posteriores:

10 COLOR 15,0,0:SCREEN 8-4*(PEEK(&H2D)>1)
15 _TURBOON
20 FOR X%=0 TO 255
25 FOR Y%=0 TO 211
30 CA!=X%^3
35 CB!=Y%^2*X%
40 CC!=CA!+CB!
45 A%=(CC!/500)AND&HF8
50 PSET (X%,Y%),A%
55 NEXT Y%,X%
60 _TURBOOFF
65 GOTO 65

Em computadores MSX2 ele utilizará o modo de 256 cores (SCREEN 8) e nos posteriores apenas os 32 tons de cinza do modo de 12 mil cores (SCREEN 12).

msx

E não se esqueçam de carregar o MSX Turbo BASIC (ou comente as linhas 15 e 60 e depois nos conte quanto tempo demora para finalizar). Este programa é uma adaptação dos códigos para desenhar fractais disponíveis na página do emulador Hi65, do Commodore 65.

A outra é para destruir de vez a produtividade das pessoas com exemplos de código em Applesoft BASIC, assembly de Z80 e até mesmo MySQL!

Mais uma contribuição de última hora!

É que eu queria colocar um de Mandelbrot, caramba! Mas os códigos que eu achava estavam se comportando de forma estranha, daí fundi a versão em Applesoft BASIC com a paleta da versão do C65 e pronto!

100 COLOR 15,0,0:SCREEN 5
105 FOR I%=1 TO 15:READ R%,G%,B%:COLOR=(I%,R%,G%,B%):NEXT I%
110 _TURBO ON
115 XC=-.5:YC=0:S=2:XR=S*4/3:YR=S
120 X0=XC-(XR/2):X1=XC+(XR/2)
125 Y0=YX-(YR/2):Y1=YX-(YR/2)
130 XM=XR/255:YM=YR/211:IT%=20
135 FOR YS%=0 TO 211:FOR XS%=0 TO 255
140 X=XS%*XM+X0:Y=YS%*YM+Y0
145 ZX=0:ZY=0:XX=0:YY=0:I%=0
150 I%=I%+1:IF I%>IT% THEN 170
155 ZY=2*ZX*ZY+Y:ZX=XX-YY+X
160 XX=ZX^2:YY=ZY^2:C%=IT%-I%
165 IF XX+YY>=4 GOTO 170 ELSE 150
170 C%=C% AND 15:PSET(XS%,YS%),C%
175 NEXT XS%,YS%
180 _TURBO OFF
185 BEEP
190 GOTO 190
195 DATA 1,0,1,2,0,2,4,0,4,5,0,5,7,0,7,7,0,6,7,0,5,7,0,3
200 DATA 7,0,2,7,0,0,7,1,0,7,2,0,7,4,0,7,5,0,7,7,0

Esta versão é em 16 cores, o do C65 usava 48 cores (como fiz? Média Aritmética!) e o resultado é assim:

mandelClaro, após 5 minuto de iterações (num Turbo R com Turbo BASIC e em modo R800).

Sobre Juan Castro

Juan Castro é uma das mentes em baixa resolução que compõem o Governo de Retrópolis – a única cujo Micro Formador não foi o MSX (e sim o TRS-80). Idealizador, arquiteto e voz do Repórter Retro. Com exceção do nome, que foi ideia do Cesar.

0 pensou em “Fractal para quem precisa de fractal

    1. Quer algo pra testar num MSX1?

      100 COLOR 15,0,0:SCREEN 2
      105 _TURBO ON
      110 XC=-.5:YC=0:S=2:XR=S*4/3:YR=S
      115 X0=XC-(XR/2):X1=XC+(XR/2)
      120 Y0=YX-(YR/2):Y1=YX-(YR/2)
      125 XM=XR/127:YM=YR/95:IT%=20
      130 FOR YS%=0 TO 95:FOR XS%=0 TO 127
      135 X=XS%*XM+X0:Y=YS%*YM+Y0
      140 ZX=0:ZY=0:XX=0:YY=0:I%=0
      145 I%=I%+1:IF I%>IT% THEN 165
      150 ZY=2*ZX*ZY+Y:ZX=XX-YY+X
      155 XX=ZX^2:YY=ZY^2:C%=IT%-I%
      160 IF XX+YY>=4 GOTO 165 ELSE 145
      165 C%=C% AND 3
      170 IF C%=1 THEN PSET(2*XS%,2*YS%),15
      175 IF C%=2 THEN LINE(2*XS%,2*YS%)-STEP(1,1),15
      180 IF C%=3 THEN LINE(2*XS%,2*YS%)-STEP(1,1),15,BF
      185 NEXT XS%,YS%
      190 _TURBO OFF
      195 BEEP
      200 GOTO 200

  1. Acrescentei o Mandelbrot para MSX e quem quiser rodar o programa em um MSX2/MSX2+ em modo Z80 e aconselho uma leve subversão:

    135 FOR YS%=0 TO 105:FOR XS%=0 TO 255
    170 C%=C% AND 15:PSET(XS%,YS%),C%:PSET(XS%,211-YS%),C%

    Como o fractal é horizontalmente simétrico basta desenhar só a primeira metade e copiar na parte de baixo. 🙂

    1. Publique assim mesmo, formas diferentes de fazer a mesma coisa são sempre bem vindas

    2. Confesso que eu queria mesmo era fazer o Mandelbrot em SCR7 com entrelaçado, deixando o treco em 512×424@16c — Atualização… Eu fiz 🙂

      1. Pois, finalmente depois de dez mil anos, fiz um Mandelbrot. Não tem nada otimizado porque nem sei por onde começar, fiz o programa baseado no algoritmo JavaScript do Rosetta Code (principalmente porque as cores ficam bonitas). Bem, para ser honesto eu poderia fazer a simetria vertical, mas deu preguiça. =P Depois vou tentar fazer uma versão usando interlace. 😉 Cadê o seu Mandelbrot em SCREEN 7 com interlace? =D

        10 COLOR,0,0:SCREEN 8
        20 _TURBO ON
        30 W=255:H=211:XL=-2:XH=1:YL=-1:YH=1:IT=1000
        40 FOR IX=0 TO W:FOR IY=0 TO H
        50 X=XL+(XH-XL)*IX/W:Y=YL+(YH-YL)*IY/H
        60 CX=X:CY=Y:MI=IT
        70 MX=0:MY=0:XX=0:YY=0:XY=0
        80 I=0
        90 XY=MX*MY:XX=MX*MX:YY=MY*MY
        100 MX=XX-YY+CX:MY=XY+XY+CY
        110 I=I+1
        120 IF I<MI AND XX+YY<=4 GOTO 90
        130 IF I=IT THEN CR=0:CG=0:CB=0:GOTO 180
        140 C=3*LOG(I)/LOG(IT-1)
        150 IF C<1 THEN CG=INT(7*C)*4:CR=0:CB=0
        160 IF C=1 THEN CG=28:CR=INT(7*(C-1))*32:CB=0
        170 IF C>=2 THEN CG=224:CR=28:CB=INT(3*(C-2))
        180 PSET(IX,IY),CR+CG+CB
        190 NEXT IY:NEXT IX
        200 _TURBO OFF
        210 GOTO 210

        1. Pronto, fiz uma nova versão do Mandelbrot, e desta vez roda muito mais rápido e funciona na SCREEN 7 com interlace. No início você escolhe um entre quatro presets para ver áreas diferentes do fractal. Não usa o truque da simetria porque nem todas as visualizações são centradas no eixo Y. Apesar de estar na SCREEN 7 que tem menos cores do que a SCREEN 8, refiz o cálculo de cor e ele acaba mostrando mais cores do que o algoritmo anterior. Depois que o gráfico fica pronto ele carrega uma das paletas, e você pode pressionar uma tecla para alternar entre qualquer uma das três paletas disponíveis. É facílimo modificar para colocar mais paletas. Também é fácil criar mais presets:

          200 CLEAR 200,&HD800:COLOR15,1,1:SCREEN 0:CLS
          205 PRINT”Pressione uma tecla de 1 a 4″
          210 I$=INPUT$(1)
          215 OP=VAL(I$)
          220 IF OP4 GOTO 210
          225 POKE&HD800,OP
          230 COLOR,0,0:SCREEN 7,,,,,3:SET PAGE 1,1:CLS
          235 _TURBO ON
          240 W=511:H=423:IT=50:OP=PEEK(&HD800)
          245 IF OP=1 THEN XL=-2:XH=1:YL=-1:YH=1
          250 IF OP=2 THEN XL=-2:XH=-.5:YL=-.5:YH=.5
          255 IF OP=3 THEN XL=-1.4:XH=-.9:YL=-.5:YH=-.16
          260 IF OP=4 THEN XL=-.4:XH=.1:YL=.8:YH=1.13
          265 FOR IX=0 TO W:FOR IY=0 TO H:SET PAGE 1,IY MOD 2
          270 X=XL+(XH-XL)*IX/W:Y=YL+(YH-YL)*IY/H
          275 CX=X:CY=Y:MI=IT
          280 MX=0:MY=0:XX=0:YY=0:XY=0:I=0
          285 XY=MX*MY:XX=MX*MX:YY=MY*MY
          290 MX=XX-YY+CX:MY=XY+XY+CY
          295 I=I+1
          300 IF I<MI AND XX+YY<=4 GOTO 285
          305 IF I=IT THEN C=0:GOTO 315
          310 C=INT(16*LOG(I)/LOG(IT-1))-1
          315 PSET(IX,IY2),C
          320 NEXT IY:NEXT IX
          325 _TURBO OFF
          330 NP=2
          335 DIM R(NP,15):DIM G(NP,15):DIM B(NP,15)
          340 FOR P=0 TO NP:FOR C=0 TO 15
          345 READ R(P,C),G(P,C),B(P,C)
          350 NEXT C,P
          355 FOR P=0 TO NP:FOR C=0 TO 15
          360 COLOR=(C,R(P,C),G(P,C),B(P,C))
          365 NEXT C:I$=INPUT$(1):NEXT P
          370 GOTO 355
          375 'FIRE
          380 DATA 0,0,0,1,0,0,2,0,0,3,0,0,4,0,0,5,0,0,6,0,0,7,0,0
          385 DATA 7,1,0,7,2,0,7,3,0,7,4,0,7,5,0,7,6,0,7,7,0,7,7,7
          390 'WIND
          395 DATA 0,0,0,0,0,1,0,0,2,0,0,3,0,0,4,0,0,5,0,0,6,0,0,7
          400 DATA 0,1,7,0,2,7,0,3,7,0,4,7,0,5,7,0,6,7,0,7,7,7,7,7
          405 'EARTH
          410 DATA 0,0,0,0,1,0,0,2,0,0,3,0,0,4,0,0,5,0,0,6,0,0,7,0
          415 DATA 1,7,0,2,7,0,3,7,0,4,7,0,5,7,0,6,7,0,7,7,0,7,7,7

  2. porque aquele fractal para MSX2 (o segundo) usa 32 tons de cinza e não “50 tons de cinza” ?? desculpem-me pela piadinha infame mas não consegui resistir….rsrsr

    1. E ainda faltam 14 tons de cinza já que o olho humano só enxerga 64 variações desta cor :-). Mas a explicação é simples a SCREEN12 dos MSX2+ codifica as cores num padrão chamado YJK (resumidamente é intensidade luminosa e variações de cores) e que fica armazenado em blocos de 4 pixels assim: Y0+Ja / Y1+Jb / Y2+Ka / Y3 + Kb ; cada ponto tem sua informação de intensidade luminosa armazenada individualmente (5-bit) e compartilham os dados de crominância J (Ja+Jb) e K (Ka+Kb), de 6-bit cada. Como eu jogo a informação de cor fora só me restam os 2^5 tons de cinza, ou seja, 32 pra ficar na tela 😀

      1. Agradeço muito a explicação (aula!)! Pelo que entendi esse formato faz uma certa “compactação” da imagem ao usar menos memória para a informação de cromância do que de luminância de forma similar ao que ocorre na transmissão da televisão colorida analógica. Sendo assim imagino que este modo de tela deva ser similar ao modo “HAM” que era nativo na linha Commodore Amiga e permitIa mostrar telas com milhares de cores simultâneas mas também imagino que assim como ocorria no modo HAM do Amiga, este modo do MSX2+ também deva ser praticamente inviável para atividades que requeram modificação dinâmica e em tempo real da imagem (jogos e manipulação da imagem em tempo real) justamente pelo interdependência de cada pixel com seus vizinhos. É isso mesmo? Abraço!