DRAW - sub-dialeto Shape



O sub-dialeto Shape permite criar formas (desenhos, shapes) como blocos.

Alguns aspectos me lembram de "gráficos de tartaruga" ("turtle-graphics"). Você pode mover a caneta sem desenhar e as coordenadas podem ser absolutas (em relação à face) ou relativas (em relação à última posição).


O sub-dialeto shape também "fecha" as formas para você, permitido o uso de  fill-pen para adicionar cores e padrões.


Você pode usar  fill-pen , pen , line-width , line-join e line-cap como comandos no bloco de shape, mas apenas o último comando vai ser usado para toda a forma.


O sub-dialeto Shape é baseado em gráficos SVG. Eu achei os links abaixo úteis para entender alguns conceitos:


https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths


http://www.w3.org/TR/SVG11/paths.html



line


O exemplo mais básico:


Red [needs: view]


myshape: [line 10x10 70x70]


view compose/deep/only [

       base draw [

           shape (myshape)

       ]

]




Note o compose/deep/only e os parentesis ao redor do nome da shape. Pelo que eu sei, você precisa usá-los quando trabalha com Shapes.


Fechamento automático


No exemplo abaixo, apenas duas linhas são, de fato, desenhadas. A terceira linha, de fechamento, é automática. Eu adicionei o fill-pen para ilustrar o conceito melhor:


Red [needs: view]


myshape: [

       line 10x70 40x10 70x70 ;só duas linhas

]

view compose/deep/only [base draw [ fill-pen blue shape (myshape)]]




move


Exemplo mais basico:


Red [needs: view]


myshape: [

       line 10x10 70x70 ;linha de 10x10 para 70x70

       move 10x70 ;move a pen sem desenhar para 10x70

       line 10x10 ;desenha uma linha da posição corrente (10x70) até 10x10

]


view compose/deep/only [base draw [shape (myshape)]]



posições relativas


As coordenadas se tornam relativas se você adicionar um apóstrofe (') antes do comando:


Red [needs: view]


myshape: [

       line 10x40 40x40 ;linha horizontal no meio

       'move 0x-10 ;nova posição corrente RELATIVA à antiga (acima do meio)

       'line 20x0 ;desenha uma pequena linha horizontal RELATIVA a posição corrente

]


view compose/deep/only [base draw [shape (myshape)]]




hline e vline

Desenham linhas horizontais ou verticais a partir da posição corrente.

Red [needs: view]


myshape: [

       move 10x10 ; coloca a caneta em 10x10

       hline 30 ;linha horizontal X =30

       vline 30 ;linha vertical Y = 30

       'hline 30 ;linha horizontal de 30 pixels (maior que a hline acima)

       'vline 30 ;linha vertical de 30 pixels

       'hline -20 ; só para mostrar o uso de distâncias negativas RELATIVAS

       ; o dialeto shape vai fechar a forma agora.

]


view compose/deep/only [base draw [shape (myshape)]]




arc


Da Documentação oficial do Red (com eventuais pequenas mudanças):

Sintaxe

arc <end> <radius-x> <radius-y> <angle> sweep large (absolute)
'arc <end> <radius-x> <radius-y> <angle> sweep large (relative)

<end> : arc's end point (pair!).
<radius-x> : radius of the circle along x axis (integer! float!).
<radius-y> : radius of the circle along y axis (integer! float!).
<angle> : angle between the starting and ending points of the arc in degrees (integer! float!).
sweep : (optional) draw the arc in the positive angle direction.
large : (optional) produces an inflated arc (goes with 'sweep option).

Descrição

Desenha o arco de um círculo entre a posição atual da caneta e o ponto final, usando valores de raio. O arco é definido por um valor de ângulo



Aqui está uma explicação sobre como o arco funciona. Como você define sua linha (dois pontos) e sua elipse (raio-x, raio-y e ângulo), existem apenas duas posições para a elipse que fazem de sua linha um acorde para ela. As opções sweep, large e sweep large definem qual arco dessas elipses aparecerá em seu desenho. Observe que na ilustração abaixo, o ângulo da elipse é zero.




In the arc definition you only inform the arc's end position. That is because the start position is the current pen position. So, if arc is your first command in a shape, you must first move to the position you want to start at.

Na definição do arc, você só informa a posição final do arco. Isso porque a posição inicial é a posição atual da caneta. Então, se arc é seu primeiro comando em uma forma, você deve primeiro ir para a posição onde deseja começar.


Red [needs: view]


myshape_1: [

   move 35x50

   arc  55x70 15 30 0

]

myshape_2: [

   move 35x50

   arc  55x70 15 30 0 large sweep

]

myshape_3: [

   move 35x50

   arc  55x70 15 30 0 sweep

]

myshape_4: [

   move 35x50

   arc  55x70 15 30 0 large

]

view compose/deep/only [

       base 100x120 draw [fill-pen blue shape (myshape_1)]

       base 100x120 draw [fill-pen blue shape (myshape_2)]

       base 100x120 draw [fill-pen blue shape (myshape_3)]

       base 100x120 draw [fill-pen blue shape (myshape_4)]

]





Com um ângulo:


Red [needs: view]


myshape_1: [

   move 35x50

   arc  55x70 15 30 30

]

myshape_2: [

   move 35x50

   arc  55x70 15 30 30 large sweep

]


view compose/deep/only [

       base 100x120 draw [fill-pen blue shape (myshape_1)]

       base 100x120 draw [fill-pen blue shape (myshape_2)]

]



Um círculo:

Red [needs: view]

myshape_1: [

   move 56x40

   arc  56x41 16 16 0 large

]

view compose/deep/only [base  draw [fill-pen blue shape (myshape_1)]]




qcurve


Da Documentação oficial do Red (com eventuais pequenas mudanças):

Sintaxe

qcurve <point> <point> ... (absolute)
'qcurve <point> <point> ... (relative)

<point> : coordinates of a point (pair!).

Descrição

Desenha uma curva quadrática de Bézier a partir de uma sequência de pontos, a partir da posição atual da caneta. Pelo menos 2 pontos são necessários para produzir uma curva (o primeiro ponto é o ponto de partida implícito).



Desenha uma curva Bezier quadrática a partir de uma sequência de 3 pontos. O script a seguir desenha duas curvas uasndo <ponto de partida>  <ponto de controle > <ponto de chegada/ponto de partidat> <ponto de controle > <ponto de chegada>. Permite cordenadas apsolutas ou relativas  (para relativas usar 'qcurve) .


Red [needs: view]

myshape: [

   move 5x40

   qcurve  20x20 40x76 60x20 76x40

]

view compose/deep/only [

       base  draw [

               pen blue

               circle 5x40 2 ;mostra ponto de partida 1

               circle 40x76 2 ;mostra ponto de chegada 1/ponto de partida 2

               circle 76x40 2 ;mostra ponto de chegada 2

               pen green

               circle 20x20 2 ;mostra ponto de controle 1

               circle 60x20 2 ;mostra ponto de controle 2

               pen yellow

               shape (myshape)

               ]

]



Eu adicionei a localização aproximada dos pontos fixos (azul) e os pontos de controle (verde) na imagem abaixo. Eles não são gerados pelo programa, eu editei a imagem.



curve


Da Documentação oficial do Red (com eventuais pequenas mudanças):

Sintaxe

curve <point> <point> <point> ... (absolute)
'curve <point> <point> <point> ... (relative)

<point> : coordinates of a point (pair!).

Descrição

Desenha uma curva cúbica de Bezier a partir de uma sequência de pontos, a partir da posição atual da caneta. Pelo menos 3 pontos são necessários para produzir uma curva (o primeiro ponto é o ponto de partida implícito).


Desenha uma curva Bezier cúbica usando <ponto de partida (posição corrente)> <ponto de controle 1 (argumento)> <controlponto de controle 2 (argument0)> <ponto de chegada (argumento)> . Permite coordenadas absolutas ou relativas (para relativa 'curve).


Red [needs: view]


myshape_1: [

       move 10x70 ; ponto de partida

       curve 30x20 50x20 70x70 ; ponto de controle; ponto de controle; ponto de chegada

]

view compose/deep/only [base draw [ pen yellow shape (myshape_1)]]


Eu adicionei a localização aproximada dos pontos fixos (azul) e os pontos de controle (verde) nas imagens abaixo. Eles não são gerados pelo programa, eu os editei.




Você pode adicionar mais pontos ao comando curve eles vão criar uma nova curva independente:


Red [needs: view]

myshape_1: [

       move 10x70 ; ponto de partida

       curve        30x20 ;primeiro ponto de controle

                       50x20 ;segundo ponto de controle

                       70x70 ;ponto de chegada da primeira curva/ponto de partida da segunda curva

                       90x40 ;primeiro ponto de controle da segunda curva

                       110x100 ;segundo ponto de controle da segunda curva

                       130x70 ponto de chegada da segunda curva

]

view compose/deep/only [base 150x100 draw [ pen yellow shape(myshape_1)]]




qcurv


Sintaxe

qcurv <point> (absolute)
'qcurv <point> (relative)

<point> : coordenadas do ponto de chegada (pair!).



qcurv desenha um Bezier quadrático suave da posição atual da caneta até o ponto especificado.

Você não precisa fornecer o ponto de controle entre o ponto de partida e o ponto final, qcurv cria esses pontos de controle como um reflexo do último ponto de controle dado no bloco de shape, portanto, você deve ter um comando que use um ponto de controle antes de usar o qcurv.


Red [needs: view]


myshape_1: [

       move 30x60 ;ponto de partida da qcurve

       qcurve 50x30 70x60 ;ponto de controle; ponto de chegada da qcurve

       qcurv 110x60 ; ponto de chegada da qcurv

]

view compose/deep/only [

       base 300x240 draw [

               scale 2 2 ; só aumenta a escala para visualisar melhor

               pen yellow

               shape (myshape_1)

               ]

]




Pelo menos até abril de 2018, qcurv só funciona com um ponto de chegada como argumento.




curv


Desenha uma curva Bezier cúbica suave a partir de uma sequência de pontos.


Assim como o qcurv, o curv cria pontos de controle refletidos em relação ao último ponto de controle no bloco de forma. Mas como os Béziers cúbicos requerem 2 pontos de controle, você deve fornecer o segundo para cada segmento. Este segundo ponto de controle será refletido como o primeiro ponto de controle do próximo segmento.



Da Documentação oficial do Red (com eventuais pequenas mudanças):

Sintaxe

curv <point> <point> ... (absolute)
'curv <point> <point> ... (relative)

<point> : coordinates of a point (pair!).

Descrição

Desenha uma curva Bezier cúbica suave a partir de uma sequência de pontos, a partir da posição atual da caneta. Pelo menos 2 pontos são necessários para produzir uma curva (o primeiro ponto é o ponto de partida implícito).

"O primeiro ponto de controle é considerado o reflexo do segundo ponto de controle no comando anterior em relação ao ponto atual. (Se não houver um comando de curva anterior, o primeiro ponto de controle será o ponto atual.)"


Então, curv desenha uma Bezier usando <posição corrente como ponto de partida >< ponto de controle 1 criado automaticamente><ponto de controle 2> <ponto de chegada>.


Assim, os argumentos que você efetivamente passa para curv são só:  <ponto de controle 2> <ponto de chegada>[...]


Red [needs: view]


myshape_1: [

       move 30x60 ;ponto de partida da qcurve

       qcurve 50x30 70x60 ;ponto de controle; ponto de chegada

       curv 100x40 110x60 ; segundo ponto de controle da curv e ponto de chegada

]

view compose/deep/only [

       base 300x240 draw [

               scale 2 2 ; aumentando só para visualização

               pen yellow

               shape (myshape_1)

               ]

]






curv pode usar muitos pontos de controle e pontos consecutivos:


Red [needs: view]


       ;segundo ponto de controle    ponto


myshape_1: [

       move 10x40

       qcurve 30x10 50x40

       curv  70x10 90x40 110x10 130x40 150x10 170x40

       move 10x40

]

view compose/deep/only [base 200x80 draw [ pen yellow shape (myshape_1)]

]