Skip navigation

temos estado a analisar comandos gráficos à base das primitivas 2d que vêem com o processing: rect, ellipse, line, point, triangle... hoje introduzimos o paradigma beginShape() / vertex() / endShape(), bem como as transformações às matrizes geométricas, dadas pelas funções translate, scale, rotate e finalmente o par pushMatrix e popMatrix, que permite encapsular os comandos geométricos.

 

estas noções  permitem criar comandos gráficos mais avançados, agrupamos vértices definidos em coordenadas locais (o zero vai ser muito importante, pois é o ponto em torno do qual se roda e que é movido…), e temos várias maneiras de unir os vértices; a mesma data pode ser unida através de pontos, linhas, tiras de linhas, quads, tiras de quads, triangles, triangle_strip, triangle_fan, etc. estas funções e parâmetros são inspiradas no sistema gráfico OPENGL. (o opengl vai ser o sistema gráfico 2d/3d mais avançado, vejam a referência no redbook http://fly.cc.fer.hr/~unreal/theredbook/ ).mantém-se um estado de transformações geométricas, com o mesmo sistema de vértices definidos, e roda-se, move-se, escala-se, desenha-se de diferentes formas este sistema de vértices. 

 

os parâmetros que podem ser enviados à função beginShape correspondem aos parâmetros de opengl que podem ser enviados à função glBegin, sem o prefixo GL_*. comparem esta imagem (http://fly.cc.fer.hr/~unreal/theredbook/figures/fig2-6.gif ) que ilustra todos os parâmetros à função glBegin com a referência do comando beginShape do processing.

 

assim, criamos uma forma gráfica ao usar a função beginShape, seguida de listas de vértices, e fechamos a forma com a função endShape. antes dos comandos da forma, podemos aplicar transformações geométricas (translate, rotate, scale) que modificam o sistema de coordenadas e representam a forma em determinada posição dada pela função translate, e rodam-na x radianos, transformação dada pela função rotate.

 

o pushMatrix e popMatrix são sempre usados aos pares, armazenando informações sobre as transformações geométricas e comandos gráficos de formas através do beginShape / vertex / closeShape, e, mais importante, fazendo um reset às transformações geométricas. 

 

há um estado geométrico mantido na tela, que lembra sempre o sistema de coordenadas em vigor. esse estado pode ser alterado através das transformações geométricas, como o translate, rotate e scale. se aplicamos o translate, movemos o centro do sistema de coordenadas para os parâmetros enviados através da função. se aplicamos o rotate, o sistema geométrico é todo ele rodado, e todos os vértices que se encontrarem nesse nível das transformações são rodados x radianos. o par push/popMatrix permite lembrar o estado anterior, e criar um novo estado, repondo a origem no sítio habitual. quando fazemos pushMatrix (o equivalente glPushMatrix();) estamos a dizer ao sistema gráfico para criar um novo nível de transformações geométricas, onde agora logo a seguir ao pushMatrix, esse nivel está iniciado a zeros, nas coordenadas originais. fazemos translates e rotates, desenhamos a forma, e logo a seguir aplicamos um popMatrix(), para regressar ao estado gráfico anterior. é muito importante que os níveis abertos com o pushMatrix sejam fechados com o popMatrix, para regressar a cabeça gráfica ao estado geométrico anterior.

 

como exemplo, pegámos no sketch do triângulo de som que vimos na sessão anterior, e mudamos a maneira de criar a geometria gráfica. na sessão anterior, mantemos a existência do triângulo apenas com as variáveis centro px e py e uma variável para o ângulo. calculamos de seguida as coordenadas dos pontos que fazem parte do triângulo estando a determinado raio e ângulo do ponto central. 

relembro aqui o código que faz isso:

 

 // um triângulo são 3 pontos

  // neste caso, cada ponto está à mesma distância do centro

 

  float pt1x,pt1y;

  float pt2x,pt2y;

  float pt3x,pt3y;

  float a; // um angulo

 

  rad = map (audio_energy, 0. , 0.2 , 50, 250);

  angulo += 0.01;

 

  a = HALF_PI + angulo;

  pt1x = cos(a)*rad + px; 

  pt1y = sin(a)*rad + py; 

 

  a = PI + PI/4 + angulo;

  pt2x = cos(a)*rad + px; 

  pt2y = sin(a)*rad + py; 

 

  a = TWO_PI – PI/4 + angulo;

  pt3x = cos(a)*rad + px; 

  pt3y = sin(a)*rad + py; 

 

 fill(255,100);

 stroke(0,150);

 

 triangle(pt1x,pt1y, pt2x,pt2y, pt3x, pt3y);

 

 

hoje vamos desenhar um triângulo, recorrendo ao novo paradigma gráfico que aqui introduzimos, e que vai simplificar bastante a criação de novas formas. 

 

para tal, primeiro temos de pensar que queremos rodar o triângulo em torno do centro, e não de um dos vértices. isto implica que o nosso sistema de coordenadas local da forma gráfica a desenhar tem de ficar com a origem(o ponto 0,0) exactamente no sítio em que queremo que o triângulo rode.

 

assim, vamos definir os vértices do triângulo em função deste ponto original. o ponto A estará na posição 0X e -radY, pois o eixo dos y no processing cresce para baixo. o ponto B estará na posição rad/2, rad, ou seja, metade do raio para a direita da origem, e raio para baixo no sentido y. o ponto C vai para a posição -rad/2, e rad para baixo. isto faz um sistema de vértices definido desta maneira:

 

 

    beginShape();

    vertex(0, -rad);

    vertex(rad/2, rad);

    vertex(-rad/2, rad);

    endShape(CLOSE);    

 

depois, completamos o nosso draw do triângulo, ao inserir as transformações geométricas que aplicamos, translacção para as coordenadas do centro px e py do triangulo e rotação angulo radianos. finalmente, temos de encapsular estas transformações geométricas dentro de pares push/pop, para permitir que outras formas que sejam desenhadas a seguir tenham a origem da tela como referência, e não estados geométricos anteriores deixados por outras formas gráficas.

 

 

  void draw(){

 

    pushMatrix();

    translate(px,py);

    rotate(angulo);

 

    beginShape();

    vertex(0, -rad);

    vertex(rad/2, rad);

    vertex(-rad/2, rad);

    endShape(CLOSE);    

 

    popMatrix();

 

  }

 

estas modificações são importantes, simplificam, e permitem outros níveis de complexidade, e estão mais próximas de comandos gráficos tri-dimensionais do que os comandos de primitivas gráficas que vimos anteriormente.

 

 

1. máquinas de desenhar (à base de som), parte 3

 

com a mudança de sistema geométrico, começamos a complexificar introduzindo máquinas de desenhar à base de som. como na sessão anterior, vamos ter um valor único e global (que pode ser acedido em qualquer parte do nosso sketch processing) que se chama audio_energy e que corresponde ao rms dos samples de som nos buffers capturados em tempo-real pelos microfones com um filtro lowpass para suavizar as transições.

 

primeiro 10 triângulos a reagirem de maneira igual ao som, depois 50 triângulos já com respostas diferentes, depois 100 triângulos a andarem com orientações dependentes da presença sonora.

 

os triângulos que reagem de maneira igual, têm os mesmos valores no construtor, e as funções que mapeiam os valores de audio têm os mesmos máximos e mínimos de destino. varia apenas o valor de velocidade que faz com que uns andem mais depressa e outros mais devagar.

sndtri1-002066

os triângulos que têm respostas distintas ao mesmo valor de som, têem novas variáveis que determinam estas diferenças nas respostas. nos campos da classe, adicionamos variáveis que servem como mínimos e máximos de variação de raio, variação de ângulo e variação de velocidade. o construtor instancia valores aleatórios para cada um desses valores. e esses valores são aplicados nos destinos das funções que mapeiam a audio_energy para o raio, o angulo e velocidade actual do triângulo em questão. como todos os triângulos têm valores distintos, as respostas ao mesmo parâmetro vão ser diferentes. além disso, há uns triângulos pretos que vão apagando o que os triângulos brancos acumulam na frame.

sndtri1-007122

sndtri1-011252

sndtri1-018892

os 100 triângulos a andarem com direcções e velocidades diferentes, vêem do mini-jogo à base de som que desenvolvemos na sessão anterior, onde se o som passar um parâmetro mínimo, andamos em frente na direcção angulo actual. se o som estiver próximo de silêncio, o triângulo altera a direcção e fica no mesmo sítio.

sndtri4-002573

sndtri4-0027751

 

aprendemos também a correr os sketches em fullscreen, com o modo present, e colocando o tamanho da tela com as dimensões do ecrã, passando as variáveis screen.width e screen.height como parâmetros para a função size.  

sndtri5-001231

sndtri5-190374

 

as imagens exemplos da sessão 4 são exemplos gráficos que vocês desenvolveram na aula, criando máquinas de desenhar à base de som, usando este novo sistema gráfico.

 

finalmente, aplicamos o último comportamento dos triângulos, substituindo a forma gráfica por imagens de homens e mulheres vistos de cima, criando uma multidão que se desloca em função do som. a multidão é a classe dos triângulos onde agora o comando gráfico são imagens com máscaras.

 

 

  void draw(){

 

    pushMatrix();

 

    translate(px,py);

    rotate(angulo);

 

    tint(255,150);

    image(img, -rad/2, -rad/2, rad, rad);

 

    popMatrix();

 

  }

 

 

sndhumans-000733

sndhumans-0021071

na última parte da aula ainda vimos o princípio de detecção de colisão, onde se as distâncias entre os triângulos ou os humanos eram inferiores a 100px, desenhamos uma linha entre eles. isso está desenvolvido na função principal que desenha todos os triângulos aqui:

 

   // renderizar todos os triangulos

 

   for(int i=0; i<tris.length;i++){

     tris[i].update();

     tris[i].draw(); 

 

     // check distance & line if < thresh

      for(int j=i+1; j<tris.length;j++){

       float d = abs(tris[i].px-tris[j].px) + abs(tris[i].py-tris[j].py); 

       if(d < 100){

        stroke(tris[i].cfill,12);

        line(tris[i].px,tris[i].py,tris[j].px,tris[j].py);

       }

      }

  }

 

sndtri5-018676

 

mesmo no fim, vimos alguns sketches simples que tentam abstrair a questão de encontrar o ângulo de qualquer ponto do espaço para o ponto representado pelo rato, e vimos os sketches setas.

 

o comportamento destes é sempre representado pela função update, onde vamos encontrar o ângulo entre dois pontos através da função atan2, como já vimos quando falámos de sistemas polares e sistemas cartesianos.

 

void updateSeta(){

  //ver o angulo da seta até ao rato (rato – seta)

  float dx = mouseX – px; 

  float dy = mouseY – py; 

  ang = atan2(dy,dx);

}

 

 

a função que desenha a seta é baseada neste novo paradigma gráfico que hoje introduzimos, e desenhamos uma linha horizontal, e depois mais duas linhas, de maneira a fazer uma seta a apontar para este (0 graus corresponde a oriente).

 

void desenhaSeta(){

  pushMatrix();

  translate(px,py);    //move a posição para o centro px, py

  rotate(ang);         //roda na pos actual ang radianos

  stroke(255);         // cor a branco

  rect(0,0,2,2);      // quadrado no centro da seta (reparem q a pos é 0,0 pois já estamos no centro)

  line(-len/2,0,len/2,0);  //corpo da seta

  line(len/3,10,len/2,0);  //braço1 da seta

  line(len/3,-10,len/2,0); //braço2 da seta

  popMatrix();

}

 

 

começamos com uma seta, depois N setas em cena, e finalmente as setas dispostas numa matriz todas a apontar para o rato.

setas1-00226

setas1-01358

 

com estas noções, concluímos a introdução ao novo sistema gráfico, que tanto permite que se trabalhe em 2d, como 3d, e já temos as ferramentas para começar a fazer sketches gráficos mais avançados.

Anúncios

One Trackback/Pingback

  1. By sessão 17 « O Som do Pensamento on 27 Maio 2009 at 11:54 am

    […] depois fomos analisar o tipo de dados pimage e a biblioteca video do processing, que é um tipo de dados que armazena imagens. começamos com os sketches que acedem à informação de cor de cada pixel — criando travelers que oscilam com base nessa cor –, depois ler e scrubbing de video, gravar video e aceder a câmaras. terminamos com acessos mais elaborados à array dos pixels de cada pimage, modificando-os ou lendo-os directamente. (sessão 4) […]

Deixe uma Resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

Logótipo da WordPress.com

Está a comentar usando a sua conta WordPress.com Terminar Sessão / Alterar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Terminar Sessão / Alterar )

Facebook photo

Está a comentar usando a sua conta Facebook Terminar Sessão / Alterar )

Google+ photo

Está a comentar usando a sua conta Google+ Terminar Sessão / Alterar )

Connecting to %s

%d bloggers like this: