Podemos fazer uma analogia entre o sistema de transformações do Processing  e as transformações aplicadas nas  camadas (layers) utilizadas em  pacotes gráficos como o Photoshop . Quando uma transformação é aplicada sobre uma camada , todos os objetos desenhados nesta camada são afetados pela transformação. Felizmente, existe um artifício  que facilita a aplicação  de alterações em camadas isoladas pelo código.

Na álgebra,  a matriz (matrix) é a  entidade matemática utilizada no cálculo  das transformações geométricas como  a rotação ou translação. No Processing,   podemos considerar uma matriz  enquanto uma  camada (layer) , ou área transformativa gerenciada por duas funções:

 

pushMatrix ( )

popMatrix ( )

 

Continuando a analogia das camadas, a função pushMatrix( ) é responsável pela adição de uma nova matriz e popMatrix( ) pela remoção da última camada criada na pilha (stack)  de camadas. Assim como nas camadas, as transformações somente afetarão os objetos desenhados sobre a última matriz adicionada. Veja o exemplo:

 

Push pop matrix

 

size (200,200);
pushMatrix();        // adiciona nova “camada”  para transformação
   translate(50,0);
   rect (0,0,30,30);
popMatrix();          // remove “camada” de transformação
fill(0);
rect(0,30,30,30);

 

Neste sketch, a transformação translate(50,0) afetou apenas o quadrado desenhado entre as funções pushMatrix( ) e popMatrix( ). Se retirarmos estas duas funções, o segundo quadrado (preto) também será deslocado 50 pixels no eixo x, pois pertence a mesma camada geral de transformações.

Resumindo,  podemos dizer que pushMatrix “reserva” uma área para transformações, enquanto popMatrix( ) remove esta área.  Uma  regra importante para o  uso  destas funções é a seguinte: a função pushMatrix( ) não pode ser usada sem popMatrix() e vice versa.

 

Veja o código:
size (500,500);
noStroke();
fill (255,0,0);
pushMatrix();                              // insere primeira camada de transformação
    translate(250,50);
    rect (0,0,200,100);
pushMatrix();                              // insere segunda camada de transformação
    fill(0);
    rotate (radians(30));
    rect (0,0,200,100);
    fill(255);
    ellipse (50,50,20,20);
    ellipse (150,50,20,20);
popMatrix();                               // remove segunda camada de transforma;áo
    rect (0,250,200,100);
popMatrix();                              // remove primeira camada de tranformação
fill(120);
rect (0,250,200,100);

 

Push  matrix()

 

A primeira função pushMatrix( ) , assinalada em verde, adiciona uma camada para a transformação do deslocamento translate (250,0).  Logo depois, temos a adição de uma segunda área para a rotação com outra  pushMatrix( ), assinalada em laranja, seguida de rotate(radians(30)).

O código isolado entre pushMatrix() e popMatrix(), assinalados em laranja desenha um retângulo preto e duas elipses. Percebem que estas figuras sofrem as transformações inseridas tanto pela primeira função (verde) quanto da segunda (laranja).

O retângulo vermelho, construído  por rect  (0,0200,200), sofre apenas o deslocamento, visto que é desenhado logo após a adição da primeira matriz (verde). O retângulo branco ainda está  dentro da primeira camada  (verde) , antes do último  popMatrix() e, portanto, sofre a  transformação exercida por translate (250,0).

O último retângulo (cinza) não sofre nenhuma transformação, pois esta fora das áreas reservadas pelas funções.

Veja a animação:
int angulo=0;

void setup() {
size (500,500);
background(0);
noFill();
smooth();
strokeWeight(3);
stroke(255);
angulo=0;
}

void draw() {
angulo+=1;
background(0);
pushMatrix();
   translate(250,250);
   ellipse(0,0,50,50);
pushMatrix();
    rotate (radians(angulo));
    ellipse(150,150,20,20);
popMatrix();
    rect(-10,-10,20,20);
popMatrix();
}

 

 

Com o auxílio de push e popMatrix (laranja), criamos a camada de rotação apenas para a figura ellipse(150,150,20,20). Todas as figuras sofrem a ação de translate (250,250), pois estão inseridas na área criada por pop/pushMatrix (verde). Veja que a coordenada do quadrado central é (-10,-10) , dez pixels a esquerda e acima do ponto inicial (0,0)  da camada  - deslocada 250 pixels para a direita e para baixo por translate (250,250).

Tagged with: