02 – O sistema de coordenadas

A tela em que pintamos nossos desenhos é uma malha quadriculada composta de pequenos quadradinhos chamados de pixels.

Vamos supor agora que fizemos um zoom com uma lente poderosa bem no canto superior esquerdo de nossa tela. A imagem que veríamos seria uma malha quadriculada como a seguinte:

Fig. 4: A malha quadriculada

Podemos “acender” cada quadrado dessa malha e colori-lo com alguma cor. Todas as imagens que você vê na tela de seu computador são feitas assim, com pixels coloridos de cores diferentes, compondo um mosaico que formam as mais diversas imagens.

Como descobrimos o “endereço” de cada pixel desses? A solução tradicional é enumerar cada um deles, da esquerda para a direita, começando do zero, e depois de cima para baixo, também começando do zero. Dessa maneira, temos o seguinte sistema de coordenadas:

Fig. 5: O sistema de coordenadas

Dessa maneira, podemos determinar, com apenas 2 números, qual é o endereço de cada pixel da tela. Por exemplo, o pixel que está colorido de preto na figura seguinte está na coordenada 5, da esquerda para a direita, e na coordenada 2, de cima para baixo. Dizemos que ele está nas coordenadas (5, 2):

Fig. 6: O pixel (5, 2)

Já na figura seguinte, temos colorido de preto o pixel de coordenadas (3, 7):

Fig. 7: O pixel (3, 7)

Você é capaz de apontar com o dedo onde estão os pixels (8, 1), (2, 3) e (6, 9)? Tome cuidado: é muito fácil confundir as coordenadas! Lembre-se que o primeiro número indica onde o pixel está da esquerda para a direita, e o segundo, de cima para baixo.

Como fazemos para “acender” um pixel em particular?

Pontos

Agora sabemos como funciona o sistema de coordenadas da Processing. Podemos, então, começar do começo e aprender como “acender” um pixel da tela, ou seja, como graficamente desenhamos um ponto.

Retomemos o programa original, aquele que já vem pronto no editor e façamos algumas pequenas modificações:

function setup() {
createCanvas(400, 100);
}
function draw() {
background(255);
}

Observe que agora nossa tela tem um quarto de sua altura original, ou seja, é um retângulo com 400 pixels de largura e com apenas 100 pixels de altura, o que foi feito com o comando createCanvas(400, 100).

Você está se lembrando de colocar o ponto-e-vírgula no final de cada comando?

Outra modificação que fizemos foi ter colocado um fundo branco em nossa tela de pintura, o que conseguimos com o comando background(255). Lembre-se que podemos fazer o fundo variar de 0 (preto) a 255 (branco), e que os valores intermediários correspondem a tons de cinza.

Com esse novo código, vamos inserir um ponto no meio da nossa pequena tela. Dentro da função draw, escreva point (200, 50):

function draw() {
background(255);
point(200, 50);
}

O resultado é algo quase imperceptível: um minúsculo ponto no meio da tela, como tenta nos mostrar a figura seguinte:

Fig. 8: Um ponto quase imperceptível no centro

Você deve ter precisado de uma lente de aumento para ver o pequeno ponto na tela. Esse é um pixel que colorimos de preto. Para tornar mais evidente onde fica o centro da tela, vamos colorir de preto três outros pontos ao redor do anterior com o seguinte código:

function setup() {
createCanvas(400, 100);
}
function draw() {
background(255);
point(200,50);
point(201,50);
point(201,51);
point(200,51);

}

São, ao todo, quatro pontos no centro, o que deve ter gerado a seguinte imagem:

Fig. 9: Quatro pontos no centro

Se seu computador ou celular tem uma boa resolução, agora você deve estar vendo com mais clareza um ponto preto no centro da tela.

Quais são os limites da tela de pintura? Se ela tem 400 pixels de largura e 100 pixels de altura, quais são as coordenadas dos quatro pontos que delimitam as extremidades desse espaço? Lembre-se que a contagem começa em 0 (zero), e daí que o canto esquerdo superior tem coordenadas (0, 0). E os demais? Dê uma boa olhada na figura seguinte e veja se você consegue ver um ponto em cada um dos cantos da tela de pintura:

Fig. 10: Quatro pontos no centro e um ponto em cada canto

Conseguiu ver? Quais são as coordenadas desses pontos?

Pense: se o primeiro ponto começa em zero, o quadrigentésimo (400º) ponto à direita, no canto superior direito, deve ter coordenadas (399, 0). E os demais? Escreva o código da figura anterior.

Se você foi perspicaz, o código que você escreveu para os quatro pontos dos cantos deve ter sido o seguinte:

function draw() {
background(255);
point(200,50);
point(201,50);
point(201,51);
point(200,51);

point(0,0);
point(399,0);
point(399,99);
point(0,99);

}

Os quatro últimos pontos do código acima representam os pontos dos cantos. Observe essas coordenadas e altere-as para outros valores. Por exemplo, tente criar um ponto em (400, 100). Será que ele aparece na tela?

Pontos são bons para treinarmos nosso sentido de orientação e para nos aguçarmos no uso das coordenadas da tela. Vamos para algo ligeiramente mais complicado: como traçar linhas?

Linhas

Como traçar uma linha que vai do ponto (2, 3) até o ponto (7, 3)? A Processing tem um comando específico para isso. Basta escrever, dentro da função draw, o seguinte:

function draw() {
background(255);
line(2, 3, 7, 3);
}

Observe que o comando line(2, 3, 7, 3) colocou dentro de um par de parênteses as coordenadas dos dois pontos em questão, o ponto (2, 3) e o ponto (7, 3). E não se esqueça do ponto-e-vírgula no final!

Com um grande zoom lá no canto superior esquerdo, onde a pequena linha foi traçada, veríamos o seguinte:

Fig. 11: Linha de (2, 3) até (7, 3)

Os pixels entre as coordenadas (2, 3) e (7, 3) foram todos coloridos de preto. O resultado, como é óbvio, é uma linha entre esses dois extremos.

Agora tente desenhar uma linha vertical que vai do ponto (3, 1) até o ponto (3, 9), gerando o seguinte desenho que aparece em zoom aqui:

Fig. 12: Linha de (3, 1) até (3, 9)

Antes de continuar, responda: qual o comando você usou para isso?

Se você respondeu line(3,1,3,9), você já está pegando o jeito da coisa!

E como seria uma linha traçada na diagonal? A figura seguinte mostra um zoom de uma pequena linha entre duas coordenadas:

Fig. 13: Linha de (1, 1) até (7, 7)

Quais coordenadas são essas e qual é o comando utilizado para traçar a linha?

A Processing tenta fazer o seu melhor para colorir os pixels entre as duas coordenadas do início e do fim da linha. Nem sempre as coisas saem como pretendíamos, e a linha acaba com um aspecto serrilhado bastante evidente. Uma linha traçada entre os pontos (1, 3) e (8, 6), por exemplo, fatalmente vai se parecer com uma escada:

Fig. 14: Linha de (1, 3) até (8, 6)

É preciso notar, no entanto, que quanto menor o tamanho do pixel da tela, menos evidentes serão os serrilhados. Existem maneiras de suavizar o efeito de serrilhamento, colorindo de cinza alguns pontos ao redor da linha, de maneira que a transição entre o preto da linha e o branco do fundo seja menos aguda aos nossos olhos. Esse efeito é chamado de anti-aliasing, bastante usado na indústria.

Um retângulo é formado por quatro linhas. Você conseguiria desenhar um retângulo ao redor da tela de desenho? Você consegue traçar as duas diagonais desse retângulo? Tente agora!

Se você deseja desenhar retângulos sem precisar desenhar 4 linhas, leia o próximo parágrafo!

Retângulos

Melhor do que traçar 4 linhas para desenhar um retângulo é usar um só comando que faça todo o serviço. É bem fácil: basta dizer quais são as coordenadas do vértice superior esquerdo e a largura e a altura do retângulo. Por exemplo, um retângulo que tem o vértice superior esquerdo em (1, 2) e tem 8 pontos de largura por 5 pontos de altura seria escrito com o comando rect(1, 2, 8, 5):

function draw() {
background(255);
rect(1, 2, 8, 5);
}

Um zoom na figura nos mostraria o seguinte:

Fig. 15: Retângulo de lados 8 e 5

Observe que os dois primeiros números entre os parênteses nos dão as coordenadas do vértice superior esquerdo. Os dois outros números nos dão a largura e a altura, nessa ordem, em pontos (ou pixels, como preferir!).

A figura a seguir é um desafio: você consegue escrever o comando que que desenha o retângulo?

Fig. 16: Retângulo de lados 3 e 7

Se você escreveu rect(4, 2, 3, 7), então você acertou!

Existe uma outra maneira de você fazer a mesma coisa. Você pode especificar dois pontos, o vértice superior esquerdo e o vértice inferior direito para desenhar um retângulo entre eles. Para isso, precisa, antes, escrever o comando rectMode(CORNERS) e depois o comando rect com as coordenadas dos vértices. Por exemplo, o retângulo anterior pode ser desenhado da seguinte maneira:

function draw() {
background(255);
rectMode(CORNERS);
rect(1, 2, 6, 8);
}

Você conseguiu, observando a figura, que seu vértice superior esquerdo é (1, 2), e o inferior direito é (6, 8)? Muito bem!

Algo que você não deve deixar de observar é como as letras maiúsculas e minúsculas são empregadas nos comandos. Se você já se viu emperrado em algum desenho e não soube o que fazer, provavelmente é porque você não está respeitando a capitalização das letras. Em outras palavras, a Processing exige que você respeite as maiúsculas e as minúsculas e as digite exatamente como fizemos em nossos trechos de programas. Assim, como o ponto-e-vírgula no fim de cada comando, a capitalização das letras deve ser seguida rigorosamente. Cuidado!

Qual é o comando que você deve usar para criar uma moldura ao redor de toda sua tela de 400 por 100 pixels? E se você deseja desenhar quatro quadrados, um do lado do outro, ocupando toda a tela? Faça alguns experimentos e brinque um pouco com essa forma!

Vamos aprender agora a desenhar círculos e elipses.

Círculos e elipses

Agora que entendemos bem como funciona o processo de “acender” pixels em nossa tela, vamos desenhar uma circunferência simples, deixando bem marcado o seu centro.

Digite no editor o seguinte programa (que depois analisaremos):

function setup() {
   createCanvas(400, 100);
 }
 function draw() {
   background(255);
   ellipse(200, 50, 100, 100);
   point(200, 50);
 }

Executado, o código acima produz a seguinte figura:

Fig. 17: Circunferência com centro

A figura, como vemos, é uma circunferência com um ponto no centro. Essa circunferência foi gerada com o código:

ellipse(200, 50, 100, 100);

O comando ellipse, que gera elipses e circunferências, possui quatro parâmetros. Os dois primeiros indicam o centro da elipse ou da circunferência, (200, 50), que marcamos bem com o comando point(200, 50). Os dois últimos números, 100 e 100, são os dois diâmetros que uma elipse pode ter: um diâmetro que corre paralelo ao eixo x, que chamaremos de diâmetro x, e o diâmetro y, que você já adivinhou ser paralelo ao eixo y. Ambos, como vemos, têm tamanho de 100 pixels. Isso, naturalmente, nos dá uma circunferência.

E se quisermos que o diâmetro x seja de apenas 50 pixels? Basta alteramos o terceiro parâmetro:

ellipse(200, 50, 50, 100);

Isso produz a seguinte imagem:

Fig. 18: Elipse de diâmetro x igual a 50

Se queremos que ele seja de 200 pixels, fazemos

ellipse(200, 50, 200, 100);

e vemos o resultado:

Fig. 19: Elipse de diâmetro x igual a 200

E se quisermos que a elipse ocupe toda a área, com diâmetro x que vai de um lado a outro? E se quisermos que a elipse tenha apenas 30 pixels de diâmetro y?

Agora observe bem a figura seguinte:

Fig. 20: Elipses

Desenhamos 7 elipses, começando da esquerda para a direita. Observe que elas vão ficando com altura menor à medida que avançamos para a direita. Ou seja, seu diâmetro y foi diminuindo gradativamente. Observe como elas se sobrepõem, o que nos indica que as figuras, em p5js, são opacas, como se feitas de cartolina e sobrepostas umas às outras.

Você consegue reproduzir a figura acima? Tente!

Estamos com um bom número de comandos na mão, mas tudo ainda está em preto e branco. Como adicionar cores (e vida) às nossas produções?

Cores (I)

Cores bem escolhidas são a alma das ilustrações. Seria possível continuarmos com nossas formas (há mais algumas delas), mas preferimos iniciar logo o uso de cores, com alterações no nosso tradicional fundo branco.

O sistema de cores mais utilizado em computação, embora muito pouco intuitivo, é o chamado sistema RGB. Essa sigla é composta das letras iniciais das palavras inglesas Red, Green e Blue, que significam vermelho, verde e azul, respectivamente. Esse sistema é extremamente comum e nos permite criar todas as cores que você vê na tela de seu computador com uma mistura dessas três cores básicas, ainda que de maneira bastante estranha.

Vamos a um exemplo prático e depois a mais explicações. Digite no seu editor o seguinte programa:

function setup() {
  createCanvas(400, 100);
}

function draw() {
  background(255, 0, 0);
}

Observe que o comando para o fundo, background, agora tem três números. O primeiro deles é 255 e os demais são 0.

Executado, esse programa gera apenas o seguinte:

Fig. 21: Fundo vermelho

Os três números dentro dos parênteses indicam, numa escala que vai de 0 a 255, a quantidade de vermelho, de verde e de azul que uma determinada cor tem. Em nosso caso, o primeiro número, correspondendo ao vermelho, tinha o valor 255, ou seja, o máximo de vermelho que uma imagem pode ter. Os outros dois números, correspondentes ao verde e ao azul, são 0, e isso indica que não há nem uma gota de verde ou azul em nosso fundo.

Se alteramos os valores, fazendo o segundo número ser 255 e os outros dois valendo 0, o que teremos?

function draw() {
  background(0, 255, 0);
}

Executado, o programa nos dá:

Fig. 22: Fundo verde

Não poderíamos esperar outra coisa. O segundo número mostra a quantidade de verde que uma imagem tem. Se o valor aqui é 255 e os demais números são 0, temos um fundo completamente verde.

Finalmente, o máximo de azul que nosso fundo pode ter é dado pelo seguinte código:

function draw() {
  background(0, 0, 255);
} 

O que nos gera o seguinte:

Fig. 23: Fundo azul

Experimente colocar valores diferente nos três números. Por exemplo, (255, 0, 255) ou (100, 255, 50) ou ainda (50, 100, 200). Tente descobrir que cores as combinações de vermelho e verde, vermelho e azul e verde e azul geram.

Por fim, e se tudo for zero?

function draw() {
  background(0, 0, 0);
} 

Certamente você gerará o fundo preto:

Fig. 24: Fundo preto

Triângulos

Um forma elementar é o triângulo. Pode ser desenhado com o seguinte comando:

triangle(a1, a2, b1, b2, c1, c2);

Os valores (a1, a2) correspondem às coordenadas de um vértice, os valores (b1, b2) correspondem às coordenadas do segundo vértice e os valores (c1, c2) correspondem às coordenadas do terceiro vértice. Na figura a seguir, desenharemos um triângulo e o preencheremos de verde. Mas… como preencher uma figura com uma determinada cor?

Preenchimento

O comando fill faz a mágica de preencher e colorir, com a cor indicada, uma figura fechada. Se antes da figura escrevemos fill(255, 0, 0), sabemos que o interior das figura a seguir terá a cor… qual mesmo?

O comando fill continua em ação até encontrar outro comando fill que indique outra cor de preenchimento. No exemplo a seguir, usaremos fill três vezes, com cores diferentes, para preencher um quadrado, um triângulo e um círculo:

function draw() {
  background(255);
  fill(255, 0, 0);
  rect(30, 0, 100, 100);
  fill(0, 255, 0);
  triangle(150, 100, 250, 100, 200, 0);
  fill(0, 0, 255);
  ellipse(310, 50, 100, 100);
}

Executado, o programa gera:

Fig. 25: Quadrado, triângulo, círculo

Para se familiarizar com a forma triângulo, substitua o quadrado e a circunferência por dois triângulos. Crie uma outra figura com triângulos diversos.

Vamos fazer uma homenagem à mais famosa escola de artes e design do mundo, a Bauhaus, fundada em 1919 na Alemanha pelo arquiteto Walter Gropius (1883 -1969). Entre seus ensinamentos, a Bauhaus identificava no quadrado, no triângulo e no círculo as formas elementares sobre as quais todo o design moderno deveria se inspirar.

Um dos testes a que um candidato a estudante da Bauhaus deveria ser submetido era saber que cor é mais adequada a qual forma. Se você respondesse como a seguir, estaria a um passo de ser aluno da escola:

function draw() {
  background(255);
  fill(255, 0, 0);
  rect(30, 0, 100, 100);
  fill(255, 255, 0);
  triangle(150, 100, 250, 100, 200, 0);
  fill(0, 0, 255);
  ellipse(310, 50, 100, 100);
} 

O programa gera a seguinte imagem:

Fig. 26: Com triângulo amarelo

Vamos criar agora uma transição em degradê de um retângulo completamente vermelho a um retângulo completamente azul, passando por 12 retângulos de cores intermediárias. Há uma maneira mais fácil de se fazer isso, mas optamos pela solução “braçal”, desenhando cada um dos 14 retângulos da figura e alterando manualmente suas coordenadas e suas cores. Veremos mais adiante como fazer isso com apenas três linhas de código, o que facilitará demais nossos trabalho.

O programa a seguir é completo, com a função setup no começo. Observe que alteramos um pouco o tamanho do nosso canvas por questões puramente estéticas.

function setup() {
   createCanvas(411, 101);
}

function draw() {
  background(255);
  fill(255, 0, 0);
  rect(0, 0, 20, 100);
  fill(240, 0, 20);
  rect(30, 0, 20, 100);
  fill(220, 0, 40);
  rect(60, 0, 20, 100);
  fill(200, 0, 60);
  rect(90, 0, 20, 100);
  fill(180, 0, 80);
  rect(120, 0, 20, 100);
  fill(160, 0, 100);
  rect(150, 0, 20, 100);
  fill(140, 0, 120);
  rect(180, 0, 20, 100);
  fill(120, 0, 140);
  rect(210, 0, 20, 100);
  fill(100, 0, 160);
  rect(240, 0, 20, 100);
  fill(80, 0, 180);
  rect(270, 0, 20, 100);
  fill(60, 0, 200);
  rect(300, 0, 20, 100);
  fill(40, 0, 220);
  rect(330, 0, 20, 100);
  fill(20, 0, 240);
  rect(360, 0, 20, 100);
  fill(0, 0, 250);
  rect(390, 0, 20, 100);
}

Executado, temos:

Fig. 27: Do vermelho ao azul

☞ Como você faria uma transição do verde ao amarelo? E do preto ao branco?

Interação (I)

Temos elementos suficientes para fazer programas mais interessantes, programas que pressupõem uma interação direta do usuário com o desenho, através do mouse, do teclado e também com os dedos em telas sensíveis ao toque, como nos celulares. Comecemos pelo mouse.

Mouse

A Processing, como toda linguagem de programação, mantém uma série de variáveis para registrar valores. Vamos lidar com o conceito de variável com mais profundidade mais à frente, mas, por ora, basta saber que os números que você escreve dentro dos comandos são interpretados pela linguagem e que alguns deles têm nomes específicos.

Um desses valores é a posição do mouse sobre a área de desenho, sobre o canvas onde criamos nossas imagens. Por exemplo, se você posiciona seu mouse bem no centro de uma área de desenho de 400 pixels de largura por 200 pixels de altura, a Processing vai saber que a ponta do seu cursor (a setinha) está no ponto (200, 100), ou seja, bem no meio da área. Essas coordenadas são guardadas pela Processing e recebem nomes: a coordenada da posição x da ponta do cursor recebe o nome de mouseX, e a coordenada y, de mouseY.

Observe a grafia: as letras X e Y são maiúsculas, e isso é fundamental em todos os comandos. A Processing distingue maiúsculas de minúsculas, ou seja, ela é uma linguagem sensível ao caso (se uma letra é maiúscula ou minúscula), ou case-sensitive.

Vejamos como isso funciona. Vamos criar um canvas e desenhar uma circunferência. Mas essa circunferência tem a variável mouseX no lugar da coordenada x do centro da circunferência.

function setup() {
  createCanvas(400, 200);
}
function draw() {
  background(230);
  ellipse(mouseX, 100, 50, 50);
}

Passe o mouse sobre a área de desenho. O que acontece quando você mexe de um lado para o outro?

Fig. 28: Uma circunferência que se move com o mouse.

Se o programa funcionou corretamente, a circunferência acompanha o mouse de um lado para o outro, no centro da área de desenho.

Mas a circunferência ainda não sobe e desce. Para isso, vamos introduzir a variável mouseY na coordenada y do centro da circunferência:

function draw() {
  background(230);
  ellipse(mouseX, mouseY, 50, 50);
}

Agora, sim:

Fig. 29: Uma circunferência que se move por toda a área.

☞ Você não é obrigado a colocar a variável mouseX na coordenada x, ou a mouseY na coordenada y. E se você inverter as duas? Tente também colocar, por exemplo, mouseY no lugar dos números que controlam o tamanho da circunferência/elipse.

Comentários

Programar nem sempre é tarefa simples. Para facilitar, a quase totalidade de linguagens de programação nos permite escrever anotações no próprio código, nos lembrando do que trata aquele trecho em especial. Por exemplo, observe a anotação simples que fizemos no seguinte programa:

 function draw() {
  // Um fundo ligeiramente cinza
  background(230);
} 

A frase “Um fundo ligeiramente cinza” é um comentário no programa. Observe que foi antecedida de duas barras inclinadas: //. Essas duas barras indicam para a Processing que tudo o que vier depois, até o fim da linha, deve ser ignorado. Ou seja, a Processing não vai interpretar o que vier escrito após as barras.

Isso e uma coisa muito boa, pois além de indicar o que cada parte do programa faz, as barras podem ser usadas também para neutralizar trechos do programa. USamo isso quando queremos observar como o programa funciona sem aquele comando particular. Em vez de apagá-lo e reescrevê-lo novamente, é melhor comentá-lo, inserindo duas barras antes.

Como exemplo, comente a linha background(230) do programa da circunferência que seguia a ponta do mouse:

function draw() {
  //background(230);
  ellipse(mouseX, mouseY, 50, 50);
}

Agora passe o mouse sobre a área de desenho:

Fig. 30: Circunferências por todos os lados!

É interessante perceber que, quando comentamos o comando background, ficamos com um programa de desenho em que nosso mouse funciona como uma caneta com uma ponta gigantesca, desenhando círculos por onde passa. Por que isso acontece?

A área de desenho, nosso canvas, em verdade “pisca” a uma taxa de 60 vezes por segundo. Tudo ali é desenhado, apagado e redesenhado 60 vezes por segundo! O comando background é responsável por limpar a tela com a cor de fundo especificada. Se o retiramos dali, a tela continua “piscando”, mas não é limpa com a cor do fundo. Por isso, os desenhos anteriores ficam lá e os novos desenhos são feitos uns por cima dos outros.

☞ Mude os dois últimos números do comando ellipse para 1 e 1. Agora você pode desenhar com o mouse sobre a tela, com uma ponta bem mais “afiada”.

Esse comportamento será melhor estudado em breve. Novos comandos serão vistos para controlar essa taxa de refresh (refrescamento), que é o número de vezes que a tela é desenhada por segundo. Por ora, saiba apenas que é o comando background o responsável por limpar a tela antes de um novo desenho.

E se nossas circunferências tiverem cores que depende das coordenadas do mouse? Podemos experimentar à vontade usando o comando fill, já visto na seção de cores. Faça o seguinte:

function draw() {
  background(230);
  fill(mouseX, mouseY, 0);
  ellipse(mouseX, mouseY, 50, 50);
}

Agora passe o mouse na área de desenho:

Fig. 31: Cor varia com coordenadas do mouse!

Interessante, não? Podemos fazer o fundo variar ao mesmo tempo. Coloque a variável mouseY (ou mouseX, caso prefira), dentro do comando background.

 function draw() {
   background(mouseY);
   fill(mouseX, mouseY, 0);
   ellipse(mouseX, mouseY, 50, 50);
 }

Agora teste:

Fig. 32: Círculos e fundo variam com as coordenadas do mouse

Muito mais pode ser feito com o mouse, como ainda veremos. As possibilidades criativas que a Processing nos oferece estão apenas começando.

☞ Onde mais você pode usar as variáveis mouseX e mouseY? Que tal criar retângulos, triângulos e mesmo linhas simples com essas variáveis em algum lugar nas coordenadas dos objetos? Você pode também usar operações aritméticas como se essas variáveis fossem números que são somados, subtraídos, multiplicados e divididos por outros.

Condições (I)

Se isto, então aquilo. Está no cerne de nosso pensamento, mesmo que não expressa com essas palavras, a noção de que uma ação causa outra. A partir de nossa vivência, da concretude do dia a dia, aprendemos a formular hipóteses sobre o funcionamento do mundo. Muitas delas têm a forma se eu fizer isso, então consigo aquilo.

Algum comando para a relação do tipo “causa e efeito” existe em praticamente todas as linguagens de computação. Na Processing também, de uma maneira bem simples e manipulável.

Vamos escrever um programa elementar para causar o seguinte efeito: se eu clicar com o mouse sobre a área de desenho, a cor do fundo se altera de cinza para preto. Só isso.

function setup() {
  createCanvas(400, 200);
}

function draw() {
  background(245);
  if (mouseIsPressed) {
    background(0);
  }
}

Quando executado, o programa tem o seguinte comportamento (clique dentro do retângulo cinza):

Fig. 33: Condição simples

As três linhas principais do código são:

  if (mouseIsPressed) {
    background(0);
  } 

Apenas traduzindo o inglês, essas linhas dizem: “Se o mouse é apertado, o fundo é 0”. Ou seja, se você clica, o fundo muda para preto. Mas como essas três linhas funcionam? O que significam if e mouseIsPressed?

A estrutura de uma condicional é a seguinte:

 se ( isto acontece ) { então isto acontece }

Essa estrutura se divide em duas partes: a primeira, entre parênteses, é a condição; a segunda, entre chaves, é a consequência. Se a condição for verdadeira, então a consequência é executada; se a condição é falsa, a consequência não é executada. No código em inglês, trocamos se por if.

Dentro de nossa condição está o comando mouseIsPressed, que significa “mouse é clicado”. Ele aguarda o clique do mouse e avisa para a Processing que a condição é verdadeira, e então a Processing executa o código entre as chaves. Se o mouse não é apertado, a consequência não é executada.

Se você desejar, pode escrever todas as três linhas da seguinte maneira:

if (mouseIsPressed) {background(0);}

Não há problema nenhum em você escrever do seu jeito. Apenas atente para o fato de que você talvez tenha que ler o próprio código no futuro, em projetos longos, e pode ser que você não se lembre mais o que cada parte significa. Use comentários para deixar dicas para si mesmo e escreva um código mais “arejado”.

☞ Como fazer para que fundo fique azul quando clicamos nele? E como fazer para que uma circunferência verde de raio 50 seja desenhada com centro bem onde o mouse foi clicado?

Variáveis

Variáveis são, de longe, o instrumento conceitual mais importante de qualquer linguagem de programação. É um conceito simples e extremamente flexível que usaremos extensamente a partir de agora. Por isso, veremos com calma o que significa e como é aplicado.

Comecemos com o mais simples programa que vimos até agora:

function setup() {
  createCanvas(400, 200);
}
 
function draw() {
  background(220);
}

Este programa não faz mais nada, como vimos bem, além de criar uma área de desenho com 400 x 200 pixels na cor cinza. Por motivos que veremos em breve, podemos (e até devemos) “dar nomes” aos números do programa. Esse processo de “dar nomes” aos números é chamado de criação de variável, e o nome em si é chamado de variável. Vejamos como isso funciona na prática.

Observe o valor 220 dentro do comando background. Vamos dar um nome a esse valor. Como ele é obviamente uma cor, vamos nomeá-lo simplesmente de cor. Usamos o comando let para dar um nome a um número:

  let cor = 220;

Dizemos que o comando let criou a variável cor e atribuiu a ela o valor 220. Agora, em todo lugar do programa que escrevermos cor, a Processing se encarregará de substituir esse nome pelo seu valor, ou seja, por 220. Nosso programa pode ser escrito assim:

function draw() {
  let cor = 220;
  background(cor);
} 

O que esse programa diz? Primeiro, criamos a variável cor com o valor 220. Depois, usamos essa variável dentro do comando background. Ao ser executado, o efeito é exatamente o mesmo. E então perguntamos: o que ganhamos com isso?

Vamos retomar um programa velho conhecido, que desenha um quadrado, um triângulo e um círculo:

function draw() {
  background(255);
  fill(255, 0, 0);  
  rect(30, 0, 100, 100);
  fill(255, 255, 0);
  triangle(150, 100, 250, 100, 200, 0);  
  fill(0, 0, 255);
  ellipse(310, 50, 100, 100);
}

Observe que o valor 255 está presente em 5 lugares. Vamos, dar um nome a esse valor, simplesmente o chamando de a:

  let a = 255;

Agora, vamos substituir todas as instâncias do valor 255 pela variável a:

function draw() {
  let a = 255;
  background(a);
  fill(a, 0, 0);  
  rect(30, 0, 100, 100);
  fill(a, a, 0);
  triangle(150, 100, 250, 100, 200, 0);  
  fill(0, 0, a);
  ellipse(310, 50, 100, 100);
}

Executado, o programa gerará os mesma figuras, com as mesmas cores. No entanto, experimente agora trocar apenas o valor de a. Suponhamos que você queira que a valha 130. Mude apenas a seguinte linha:

  let a = 130;

Antes de executar, observe que você está mudando muita coisa ao mesmo tempo, apenas de estar alterando apenas um único número. Qual será o resultado?

Fig. 34: Tudo escureceu!

Porque reduzimos o parâmetro que dá a intensidade tanto a cor de fundo quanto de uma das componentes vermelha, verde e azul das figuras, de 255 para 130, vemos que temos tudo mais escurecido. Alteramos tudo ao mesmo tempo.

☞ Altere o valor de a para 100 e depois 50. Tudo ficará ainda mais escuro. Agora, retire a do comando background e troque-o por 255, deixando o fundo branco, mas não mexa no restante do programa. Assim você verá mais claramente o impacto da alteração do valor de uma variável em todos os lugares onde ela parece.

Uma variável, como vimos, nos faz economizar tempo. Com uma só mudança, temos muitas alterações acontecendo. Vamos a mais um exemplo para tornar ainda mais clara a ideia de variável e de suas múltiplas aplicações.

No editor, digite e execute o seguinte programa:

function setup() {
  createCanvas(400, 102);
}

function draw() {
  background(255);
  let a = 30;
  rect(a, 1, 100, 100);
}

O que você deve ter visto é o seguinte:

Fig. 35: Um simples quadrado

Agora preste atenção no programa. Observe que a primeira coordenada do quadrado – o canto superior esquerdo – foi substituída por uma variável, que por simplicidade chamamos de a. Essa coordenada foi criada com a linha let a = 30, logo depois de background.

Agora vamos criar mais dois quadrados ao lado desse. Vamos aproveitar o código do quadrado original e apenas somar um valor à variável a para criar cada um dos outros quadrados:

function draw() {
  background(255);
  let a = 30;
  rect(a, 1, 100, 100);
  rect(a+120, 1, 100, 100);
  rect(a+240, 1, 100, 100);
 }

Assim, temos a imagem:

Fig. 36: Três quadrados

Qual é a vantagem disso? Primeiro, evita que façamos contas; segundo, nos possibilita deslocar todos os três quadrados com apenas uma mudança em a.

☞ Faça isso agora. Altere o valor de a para 0, execute o programa, e depois altere para 100, executando novamente o programa. No editor online, você deve ter percebido que os quadrados se deslocaram todos ao mesmo tempo para a esquerda e depois para a direita, inclusive saindo da área de desenho.

Apenas arranhamos a superfície da imensa utilidade das variáveis. O uso de variáveis é um caminho sem volta: depois que as conhecemos, nunca mais programamos sem elas.

Cores (II)

Há muitos mais sobre cores do que vimos até agora. Antes de passar a novos comandos, vamos nos lembrar daquele programa elementar que fizemos quando estudamos condições: se você clica na área de desenho, o fundo muda de cor. O programa era o seguinte:

function setup() {
  createCanvas(400, 200);
}

function draw() {
  background(245);
  if (mouseIsPressed) {
    background(0);
}

Vamos alterar um pouco o código dentro da função draw para treinarmos um pouco mais o conceito de variáveis:

function draw() {
  let c = color (255, 200, 0);
  background(245);
  if (mouseIsPressed) {
    background(c);
  }
} 

Execute e clique sobre a área de desenho:

Fig. 37: Revendo um velho conhecido

Olhando o programa, vemos que a única novidade é que atribuímos uma cor à variável c, que foi posteriormente usada dentro do comando background. A atribuição foi feita com o comando color(), preenchido com os valores 255, 240 e 0, correspondendo à quantidade de vermelho, verde e azul de nossa cor. Como vemos, esses valores geram um amarelo escuro.

  • usar stroke(), noStroke e strokeWeight()
  • usar frameCount