Curso de Basic
Desenhando Estrelas com o Draw


Você está em: MarMSX >> Cursos >> BASIC   O programa que desenha estrelas apresentado nos capítulos 4 e 12, é flexível e bem pequeno. Entretanto, é bem mais lento para desenhar as estrelas do que através do comando LINE.
  Isto se deve ao fato de que em cada iteração (volta do laço FOR) são feitas 8 contas envolvendo senos e cossenos, que levam um tempo considerável para serem realizadas através de um processador Z-80 de 3,58 MHz.

  A proposta agora é utilizar o comando DRAW para desenhar a estrela, que será bem mais rápido do que o algoritmo atual.

  O comando DRAW somente desenha linhas em ângulos de 45 ou 90 graus. Como a estrela de 5 pontos possui ângulos diferentes desses, teremos que utilizar o comando "m" do DRAW com deslocamentos para conseguir desenhá-la.
  Por quê utilizar deslocamentos? Porque assim poderemos desenhar a estrela em qualquer lugar da tela, baseado apenas em uma coordenada de orientação. Caso fosse utilizado o "m" fixo, a estrela seria sempre desenhada no mesmo local, ou, então, teríamos que calcular sempre as coordenadas de todos os pontos.
  O programa da estrela será útil para calcular as coordenadas das linhas e encontrar os deslocamentos entre cada linha traçada.

  Modificando o programa para:   Temos:
10 SCREEN 0
20 X=128:Y=85:R=20:RI=10:CB=15:CP=4:GOSUB 100
50 GOTO 50
100 '
110 ' Desenha estrela
120 '
130 PI=3.14159:AN=PI*2/5
140 FOR A=PI/2 TO (2*PI-.1) + PI/2 STEP AN
150 X1= INT(X+R*COS(A)) : Y1= INT(Y-R*SIN(A))
160 X2= INT(X+RI*COS(A-AN/2)) : Y2= INT(Y-RI*SIN(A-AN/2))
170 X3= INT(X+R*COS(A)) : Y3= INT(Y-R*SIN(A))
180 X4= INT(X+RI*COS(A+AN/2)) : Y4= INT(Y-RI*SIN(A+AN/2))
190 D1 = X1-X2: D2 = Y1-Y2
200 D3 = X4-X3: D4 = Y4-Y3
210 PRINT "(";X1;",";Y1;")-(";X2;",";Y2;")"
220 PRINT "(";D1;",";D2;")"
230 PRINT "(";X3;",";Y3;")-(";X4;",";Y4;")"
240 PRINT "(";D3;","D4;")"
250 NEXT A
260 RETURN
  Saída:
  ( 128 , 65 )-( 133 , 76 )
  (-5 ,-11 )
  ( 128 , 65 )-( 122 , 76 )
  (-6 , 11 )
  ( 108 , 78 )-( 122 , 76 )
  (-14 , 2 )
  ( 108 , 78 )-( 118 , 88 )
  ( 10 , 10 )
  ( 116 , 101 )-( 118 , 88 )
  (-2 , 13 )
  ( 116 , 101 )-( 127 , 94 )
  ( 11 ,-7 )
  ( 139 , 101 )-( 127 , 94 )
  ( 12 , 7 )
  ( 139 , 101 )-( 137 , 88 )
  (-2 ,-13 )
  ( 147 , 78 )-( 137 , 88 )
  ( 10 ,-10 )
  ( 147 , 78 )-( 133 , 76 )
  (-14 ,-2 )

  A cada iteração, o algoritmo desenha uma ponta da estrela, sempre de A para B e de A para C.
      A
      +
      /\
     /  \
  ↙ /    \ ↘
   /      \
B +        + C
  Para formar um caminho, temos que considerar o desenho de C para A e de A para B. É isso que foi feito nas linhas 190 e 200.

  O programa pode ser mais útil ainda, se escrever para a gente o código do DRAW. Vejamos como:
10 SCREEN 0
15 DEF FN CS$(N) = RIGHT$(STR$(N), LEN(STR$(N))-1)
16 DEF FN FS$(N) = CHR$(43-(N<0)*2) + FN CS$(N)
20 X=128:Y=85:R=20:RI=10:CB=15:CP=4:GOSUB 100
50 GOTO 50
100 '
110 ' Desenha estrela
120 '
130 PI=3.14159:AN=PI*2/5
140 FOR A=PI/2 TO (2*PI-.1) + PI/2 STEP AN
150 X1= INT(X+R*COS(A)) : Y1= INT(Y-R*SIN(A))
160 X2= INT(X+RI*COS(A-AN/2)) : Y2= INT(Y-RI*SIN(A-AN/2))
170 X3= INT(X+R*COS(A)) : Y3= INT(Y-R*SIN(A))
180 X4= INT(X+RI*COS(A+AN/2)) : Y4= INT(Y-RI*SIN(A+AN/2))
190 D1 = X1-X2: D2 = Y1-Y2
200 D3 = X4-X3: D4 = Y4-Y3
210 PRINT "m" + FN FS$(D1) + "," + FN FS$(D2);
220 PRINT "m" + FN FS$(D3) + "," + FN FS$(D4);
230 NEXT A
240 RETURN
  Saída:
  m-5,-11m-6,+11m-14,+2m+10,+10m-2,+13m+11,-7
  m+12,+7m-2,-13m+10,-10m-14,-2

  O programa a seguir desenha uma estrela, baseado nos comandos do DRAW calculados.
10 SCREEN 2
20 PRESET(128,95)
30 COLOR 15
40 DRAW"bu20m-6,11m-14,2m+10,10m-2,13m+11,-7
m+12,7m-2,-13m+10,-10m-14,-2m-5,-11"
50 GOTO 50

  Obs:
  O programa a seguir irá fazer uma animação, onde a estrela sofre modificação na escala, dando a impressão de aproximar da tela.
10 SCREEN 5
15 SET PAGE 0,1
16 FOR F=1 TO 8
17 CLS
20 PRESET(128,95)
30 COLOR 15
35 DRAW"s"+STR$(F*2)
40 DRAW"bu20m-6,11m-14,2m+10,10m-2,13m+11,-7
m+12,7m-2,-13m+10,-10m-14,-2m-5,-11"
43 PAINT(128,95),12,15
44 COPY(0,0)-(255,211),1 TO (0,0),0
45 NEXT F
50 GOTO 50
  O comando "s" do DRAW (linha 35) é responsável pela escala da estrela.


  Considerações finais

  Foi visto no capítulo 4 uma solução para melhorar o código para desenhar estrelas na tela do MSX. Essa melhoria trouxe um código mais limpo e mais flexível, pois ele era capaz de desenhar uma estrela de qualquer tamanho e em qualquer lugar da tela. Entretanto, esse código possui um desempenho bem inferior ao código que utiliza o comando LINE.
  Resumindo, o código de LINE para subrotina proporcionou:   Ficou evidente que esse código era mais lento que o anterior. Então, seria necessário encontrar uma solução para otimizar esse processo.
  O comando DRAW seria a solução para otimizar o desempenho, mas ele necessita de informações do formato genérico da estrela para atingir esse objetivo.
  Como o programa da estrela que utiliza subrotinas calcula as coordenadas de uma estrela, ele serviu de subsídio para calcular o formato genérico da estrela. Esse processo de calcular a forma genérica da estrela é necessário apenas uma vez e, quando pronto, o resultado pode ser aplicado quantas vezes o necessário. A esse processo chamamos de "pré-processamento de dados".
  O pré-processamento de dados não faz parte da rotina final que será executada. Dessa forma, não importa se ele é muito lento para processar, pois o que interessa para nós é o resultado por ele produzido.

  Ao final, a evolução do código no sentido "LINE → subrotina de senos e cossenos → DRAW" proporcionou:

<< Anterior Basic Próxima >>