Tutorial Processing – Transformações | Processing São Paulo
Tutorial Processing – Transformações
By navax On 30/09/2011
As funções de transformações podem modificar a geometria dos objetos. Veremos alguns recursos para as transformações bidimensionais.
rotaciona os sistema de coordenadas fazendo com que as formas sejam desenhadas num angulo específico.
rotate (angulo)
O angulo de rotação toma radianos como unidade para rotacionar as formas em torno do ponto (0,0) do sketch. O processo de rotação é cumulativo, isto é, se aplicarmos duas rotações de PI/4 teremos um angulação final de PI/2.
Veja a correspondência entre ângulos registrados em radianos e graus:
No Processing, o angulo de rotação deve ser especificado em radianos. Para facilitar, existe uma função matemática radians( ) que converte valores especificados em graus para radianos. Neste exemplo, primeiro convertemos o valor da variável angulo (igual a 45) para seu equivalente em radianos e logo após realizamos a rotação.
int angulo=radians(45);
rotate (angulo);
Vejamos como funciona o esquema de rotação no Processing. Planejamos rotacionar em 45 graus um quadrado de 40 pixels de lado, posicionado na coordenada (40,40):
rect (40,40,40,40);
rotate (radians(45));
Este seria o resultado do sketch:
Note que desenhamos dois quadrados, o primeiro (cinza) sem rotação e o segundo (preto) na mesma posição , porém rotacionado 45 graus. Para entender melhor, veja este gráfico desenhado por J. David Eisenberg:
Gráfico criado por J David Eisenberg - http://www.processing.org/learning/transform2d/
Perceba que o segundo quadrado não rotacionou em torno do seu próprio centro de registro. A função rotate() rotaciona todo o plano das coordenadas e , desta forma, o quadrado se desloca para a esquerda, pois gira junto com o plano cujo o centro é o ponto (0,0). Existe uma forma "correta" de rotacionar uma figura em torno de um ponto que corresponda ao seu próprio centro; veremos isto após o estudo da transformação de translação.
A translação é uma transformação ou deslocamento do plano das coordenadas. Assim como a rotação, não deslocamos as formas em si, mas sim o plano ou "papel" onde foram desenhadas. Veja o gráfico:
Neste esquema, apesar da translação, perceba que o quadrado permanece na posição (20,20), relativa ao grid. A função de movimento deve ser escrita da seguinte forma:
Os parâmetros x e y são as coordenadas para onde o novo ponto de registro (0,0) do plano de desenho foi deslocado. Veja o código:
Primeiro o quadrado cinza foi desenhado normalmente na posição (0,0). Depois, mudamos a cor de preenchimento para preto e realizamos um movimento de translação, deslocando a origem do plano de desenho para a posição (100,00). Finalmente desenhamos o segundo quadrado, mas veja que agora ele está na posição deslocada, mesmo que seja desenhado exatamente igual ao primeiro. Apesar dos parâmetros de posicionamento da segunda figura estarem indicados como (0,0) em rect(0,0,20,20), o desenho foi para o centro do sketch devido ao deslocamento anterior efetuado no plano desenho com translate(100,100).
Talvez seja mais fácil apenas alterar a posição do quadrado inicial, porém a função translate( ) torna-se útil quando necessitamos deslocar várias figuras ao mesmo tempo.
Como vimos no exemplo da rotação, as figuras giram em torno do ponto de origem (0,0) do plano sobre o qual foram desenhadas. Com a combinação da translação e rotação, podemos coincidir este ponto com as coordenadas de registro das próprias figura. Veja o exemplo:
O quadrado mais claro foi desenhado sem rotação no ponto (100,100) , ou centro do sketch. Adotamos este ponto como centro de rotação dos outros dois quadrados. Para que isso ocorra, precisamos primeiro fazer uma translação do plano para esta coordenada (100,100). Na sequencia aplicamos funções de rotação logo antes de desenhar cada uma das figuras. Veja o código:
rect(100,100,50,50); // o ponto (100,100) é o ponto de origem do primeiro quadrado
translate(100,100); // desloca o plano para o ponto (100,100)
rotate(radians(30)); // rotaciona o plano trinta graus em torno desta nova posição
rect(0,0,50,50); // desenhamos o segundo quadrado no ponto (0,0) deslocado
rotate(radians(30)); // rotaciona novamente o plano em 30 graus
rect(0,0,50,50); // o quadrado preto sofre o efeito acumulativo das 2 rotações
Como no exemplo anterior, perceba que os quadrados cinza-escuro e preto foram desenhados na coordenada (0,0). Mas agora eles também estão no ponto (100,100), pois o plano foi antecipadamente deslocado com translate (100,100). A transformação de deslocamento alterou o centro de rotação das figuras que a agora coincidem com o centro do primeiro quadrado desenhado.
Vamos utilizar o poder da animação para visualizar estas combinações de uma forma mais dinâmica:
angulo+=5;
rect (250,250,20,20);
line (0,0,250,250);
Pode não parecer, mas nesta animação o quadrado está sendo desenhado sempre na posição (250,250)! Mas note que ele se desloca sempre em relação ao ponto (0,0) do sketch (desenhamos a linha aqui apenas para reforçar a visualização deste conceito). Na verdade o que está sendo rotacionado é a própria "folha do desenho" com a função rotate(radians(angulo)).
Veja que a variável angulo está sendo incrementada em 5 unidades constantemente dentro do looping na linha angulo+=5. Com a repetição estabelecida dentro de draw(), o valor armazenado em angulo aumenta gradativamente, resultando na acumulação de rotações para o plano. A linha é igualmente rotacionada, apesar das coordenadas fixas de desenho (0,0,250,250).
Na próxima animação experimentamos uma combinação de transformações:
angulo+=10; // aumentamos a velocidade angular
translate (250,250); // deslocamos o plano das coordenadas
rect (150,150,20,20);
line (0,0,150,150);
Aqui fizemos pequenas mas expressivas alterações. A função translate (250,250) desloca o plano para o centro do sketch. Logo, o quadrado deve girar em torno deste novo pivot, mas sempre mantendo a posição ou distancia relativa 150 com rect (150,150,20,20). A linha parte também deste novo centro, por isso conservamos seu ponto inicial em (0,0) e o final na mesma posição do quadrado (150,150).
Finalmente, vejamos a combinação de translate e rotate para a rotação do quadrado em torno de seu próprio centro:
angulo+=10;
translate (250,250);
stroke(247,226,32);
rect (0,0,50,50); // aumentamos o tamanho do quadrado e centro
line (50,50,135,135); // eixo da linha deslocado 50 pixels
ellipse(150,150,30,30); // elipse próxima ao final da linha
Além do aspecto colorido, a principal mudança aqui foi o posicionamento do quadrado. Após a translação (idêntica ao exemplo anterior), o centro de rotação da figura coincide agora com o registro (0,0) do plano com rect(0,0,50,50). O ponto inicial da linha foi levemente deslocado com relação a este centro , 50 pixels com line (50,50,135,135). Acrescentamos o desenho de uma elipse cujo centro fica próximo ao ponto final da linha (150,150).
A transformação de escala amplia o sistema de coordenadas fazendo com que as figuras sejam desenhadas maiores. A função pode ser descrita em dois formatos:
scale (tamanho)
scale (tamanho x, tamanho y);
No primeiro modo a escala é alterada em todas dimensões, e no segundo modo as escalas do eixo x e y são alteradas separadamente. Os parâmetros de escala são definidos em termos de porcentagem representadas em decimais. Por exemplo 200% corresponde a 2.0, 0.7 equivale a 70%. Utilizando o exemplo anterior, vamos reduzir a escala da animação a metade do tamanho original:
scale(0.5); // altera a escala após transformações
rect (0,0,50,50);
line (50,50,135,135);
ellipse(150,150,30,30);
Quando utilizamos combinações de transformações é importante verificar a ordem de aplicação. Neste exemplo, a transformação de escala foi aplicada logo após rotate(). A inversão da ordem deve gerar outros resultados visuais, pois alteramos as coordenadas e orientações do plano. Um efeito interessante de "zoom in" pode ser criado apenas pelo incremento do parametro de scale():
float zoom; // declara variável zoom
zoom=0; // inicializa variável zoom
zoom+=0.001; // zoom é incrementada no looping
scale(zoom); // o parâmetro recebe valor atualizado de zoom
Criamos uma variável zoom cujo valor será incrementado gradativamente (+ 0.001) a cada repetição da função draw(). A escala aumenta conforme o incremento de zoom em scale(zoom).
Ainda é possível o controle de transformações agrupadas por figuras individuais. No próximo tópico estudaremos esta possibilidade com o uso da Matriz de transformação.