Processing

Introdução

Você deseja criar imagens, sons e experiências digitais interativas? Deseja dominar os princípios da programação e entender o que é um algoritmo? Tratar montanhas de dados brutos e dar algum sentido visual para eles? E, mais importante, quer apenas se divertir com programação na frente de um computador ou celular? Então este livro foi escrito para você. Aqui, de maneira rápida, prática e segura, você aprenderá os elementos fundamentais da programação em Processing.

Em verdade, este último propósito, a diversão, foi o que nos motivou a escrever. Poucas coisas são tão divertidas quanto programar, e poucas coisas são tão educativas quanto programar arte algorítmica e interativa. Criar programas que respondem a seus comandos, às suas ações com o mouse, com toques na tela do seu celular, com o teclado do computador e até mesmo através de sua webcam é uma experiência empolgante.

Apenas em favor de sua edificação pessoal, vejamos antes com mais clareza o que é Processing, como surgiu e por que foi criada, e também o que significa trabalhar com sua implementação p5.js.

O que é Processing?

Processing é uma linguagem de programação livre concebida e implementada pela primeira vez em 2001 por Ben Fry e Casey Reas, pesquisadores do MediaLab (Laboratório de Mídia) do Massachusetts Institute of Technology (MIT).

Ao criar a Processing, Fry e Reas tinham a intenção construir uma linguagem simples e poderosa para ensinar os fundamentos de programação a artistas plásticos e designers sem as complicações de linguagens como C++ e Java. Para atingir esse objetivo, eles seguiram o caminho aberto por John Maeda com a linguagem Design by Numbers (DBN), da qual a Processing herdou boa parte dos conceitos. Com o tempo, a Processing passou a ser empregada em áreas muito além da criação de arte digital, como robótica, tratamento de dados, visão por computador, educação científica e até criação de apps para celulares.

A Processing está disponível gratuitamente no site processing.org para as plataformas Windows, Linux e Mac OS, com ampla e detalhada documentação. Sua implementação p5.js, disponível no site p5js.org, procura vencer as limitações das plataformas mencionadas servindo como uma biblioteca Javascript leve e facilmente incorporada em páginas da web.

Usos

Existem dezenas de softwares no mercado para trabalhar com os mesmo elementos para os quais a Processing foi criada. Mas algumas de suas características a fazem distinta de alternativas similares.

Nas seções a seguir, vamos tratar com um pouco mais de atenção cada uma das grandes vocações dessa linguagem, esperando que você se convença de sua utilidade e adequação a vários tipos de usuários.

Educação informática

Frequentemente, o professor de programação deve encarar uma dificuldade inicial em sua prática de ensino: a escolha da linguagem adequada a iniciantes.

As opções variam de pseudolinguagens, como Portugol, a linguagens acadêmicas ou profissionais, como Pascal, Scheme, C, Java, Python e Haskell, utilizadas com diversos graus de sucesso. A compreensão dos elementos fundamentais da prática computacional, no entanto, como entrada e saída de dados, escolha entre alternativas, repetição de instruções, criação e manipulação de classes e objetos, uso da recursão e manejo de diversas estruturas de dados constituem uma barreira cognitiva de difícil transposição para a maioria dos alunos.

Em apoio à superação dessas dificuldades, a Processing apresenta-se como uma alternativa simples e viável, mantendo o foco nos gráficos e na interatividade. É um linguagem completa, com forte vocação didática e capaz de criar programas reais voltados à solução de problemas concretos. Seu diferencial está na rapidez com que os programas são criados e testados — em outras palavras, prototipados — com resultados visuais que confirmam ou refutam conjeturas feitas pelo programador. Com isso, a Processing pretende trazer de volta a simplicidade da linguagem BASIC e a interatividade e o prazer da linguagem LOGO.

Educação científica

Educadores nas áreas de ciências e matemática podem se beneficiar da Processing em seus ambientes de ensino, fazendo com que alunos apliquem de forma contextualizada os conceitos aprendidos nas aulas de ciências e matemática. A Processing, assim como no passado a linguagem Logo, age como uma interlocutora do estudante, ao trazer o resultado de suas conjeturas em forma gráfica, levando-o à reflexão sobre as consequências de seus pensamentos. E nada melhor do que poder testar e experimentar em um ambiente amigável e sem perigos, como o que a Processing oferece.

Tratamento de dados

Existem profissionais que lidam diariamente com uma massa enorme de dados. Em geral, eles tentam domá-los através de planilhas que geram gráficos em forma de pizza ou em barras. Mas nem sempre as relações entre as diversas variáveis ficam claras, e a compreensão sobre a influência de cada uma no fenômeno em questão permanece obscura.

Os dados em si não dizem nada. É preciso organizá-los, relacioná-los uns com os outros, descobrir suas interdependências. Um aspecto importante, no entanto, costuma ser negligenciado pelos profissionais que lidam com eles: a comunicação dos dados e de suas relações à equipe de trabalho ou ao público em questão. Existe uma maneira visual de promover a compreensão de um universo de dados melhor do que os tradicionais gráficos de barras?

Essa é uma das questões que determinaram a criação da Processing, exibindo seu lado prático de ferramenta estatística e comunicativa. Criar gráficos de diversos tipos, para além dos gráficos padronizados costumeiros oferecidos por planilhas eletrônicas, é uma das grandes vocações da Processing.

Arte digital

Artistas plásticos, escultores, arquitetos e músicos têm utilizado o computador como um instrumento auxiliar na criação de suas obras desde os primórdios da computação moderna, na década de 1960. Logo de início, esses profissionais viram no computador algo mais do que um mero coadjuvante do processo de criação. Computadores são agentes eficazes na produção de obras de execução difícil ou mesmo impossível sem sua intervenção.

Fractais, animações e efeitos especiais em filmes são hoje um elemento comum da cultura popular e erudita. O uso de computadores na criação de arte é generalizado e em muitos casos indispensável. Esse uso traz também à ordem do dia a interatividade entre criador e espectador, proporcionando uma melhor fruição artística e compreensão da obra e dos conceitos envolvidos.

A Processing promove de forma ativa a criação de arte digital por uma ampla gama de usuários. Artistas profissionais, amadores e hobbistas de computação tem na Processing uma linguagem e um ambiente riquíssimos para a expressão de suas ideias artísticas.

Criação de aplicativos para Android

Recentemente, com a plataforma Android se tornando o sistema operacional mais utilizado no mundo, as linguagens de programação modernas tem sido renovadas para atender às demandas por softwares voltados para esse sistema.

A Processing, por ser programada em Java, a linguagem nativa das aplicações Android, se destaca nesse campo de maneira natural. Aplicações para Android, das mais simples às complexas, podem ser programas diretamente no celular e lá mesmo instaladas sem a menor dificuldade.

Sites de interesse

Há muitos sites na internet já dedicados à Processing. A maioria – ou quase todos – estão em inglês. As sugestões abaixo servem como um ótimo começo:

  • http://www.processing.org — Site oficial da linguagem. Downloads, extensa coleção de tutoriais e links.
  • https://p5js.org — A p5.js é uma biblioteca de funções escritas na linguagem Javascript para incorporação e execução de programas escritos em Processing em páginas da internet. Esta é a versão da linguagem que utilizaremos neste livro.
  • http://www.openprocessing.org — Site dedicado à divulgação de obras criadas com Processing, com código-fonte disponível e possibilidade de utilização da p5.js para a criação online de programas.
  • http://www.creativeapplications.net/category/processing/ — O Creative Applications é um site dedicado à arte digital em geral. Muitos artistas lá utilizam a Processing em suas aplicações.

Agora, vamos aprender como programá-la.

O editor

O trabalho de programação com a Processing, assim como com toda linguagem de programação, requer ferramentas adequadas. Para nossa sorte, a equipe de desenvolvimento da biblioteca p5.js pensou nisso e criou um editor muito bom, simples, gratuito e disponível online.

Digite o endereço editor.p5js.org em seu navegador de internet e aguarde. Você deve ver a seguinte imagem na tela de seu computador:

Fig. 1: O editor

Esse é o editor que utilizaremos. Na metade esquerda da tela, escrevemos os programas. Na metade direita, vemos o resultado.

Vejamos agora como escrever nosso primeiro programa.

O primeiro programa

Seu primeiro programa será muito simples. Em verdade, ele já está escrito dentro do editor:

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

function draw() {
background(220);
}

Iremos detalhar a função de cada palavra nesse programa mais adiante. Por ora, você precisa saber apenas como executá-lo, ou seja, fazê-lo funcionar e ver o resultado.

Para isso, existem dois botões no canto superior esquerdo do editor:

Fig. 2: Os botões play e stop

Você conhece esses botões. O primeiro, com um triângulo no meio, é o play, e o outro, o stop. O primeiro executa os programas e o segundo os interrompe. Logo ao lado, há um quadradinho de seleção chamado Auto-refresh que, se marcado, fará com que as modificações de seu programa se reflitam imediatamente em sua execução. Deixe-o marcado, para simplificar o nosso trabalho futuro.

Sua única tarefa agora consiste em clicar com o mouse no botão play e ver o que acontece. Faça isso agora.

O resultado não é nada excitante: um quadrado cinza surgiu do lado direito do editor.

Fig. 3: O primeiro programa

Vamos analisar agora cuidadosamente o significado de cada palavra desse programa no próximo capítulo.

Análise

Seu primeiro programa já estava escrito no editor:

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

Já sabemos o que ele faz: cria um quadrado na cor cinza. Mas como?

Todo programa em p5.js tem dois blocos onde as coisas acontecem. O primeiro deles, o bloco de configurações iniciais, é responsável por criar um ambiente onde tudo o mais acontecerá:

function setup() {

}

Observe as palavras function e  setup. Elas estarão no início de todos os programas. Se você quiser programar em p5.js, acostume-se a escrever essas palavras, seguidas dos parênteses e das chaves como mostrado acima.

A palavra function é uma herança dos tempos em que apenas matemáticos programavam computadores. Em verdade, eles criaram a maioria das linguagens de programação fazendo uso principalmente do conceito de função, que tem um significado bem preciso para os profissionais. Para nós, é melhor imaginarmos uma função como uma máquina composta de pequenas partes, como engrenagens ou máquina menores, que vai realizar alguma tarefa específica. Assim, podemos ler esse primeiro bloco como uma função (ou máquina) de nome setup que vai fazer alguma coisa.

A palavra setup pode ser traduzida como configuração. Ela diz que o que vier entre as chaves “{” e “}” conta como elemento do ambiente onde tudo o mais acontecerá. É como se, antes de iniciar o trabalho, arrumássemos nosso espaço de maneira adequada para a realização da tarefa.

Em nosso caso, precisamos criar uma tela, chamada de canvas, sobre a qual iremos desenhar, como um pintor que coloca uma tela em branco sobre um cavalete. Fazemos isso com outra função:

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

A função createCanvas(400, 400) cria uma tela com o tamanho de 400 pixels de largura e 400 pixels de altura. Um pixel é um quadradinho muito pequeno. A tela de seu computador é formada de milhões de pixels, como um imenso mosaico, onde cada quadradinho tem uma cor. A maioria dos pixels desta tela em que você está lendo tem a cor branca. Você nem os percebe. Quando ganham outras cores, aparecem letras e desenhos que você reconhece. Assim, quando escrevemos createCanvas (400, 400) estamos criando uma tela de 400 por 400 pixels para nossos desenhos.

Observe que colocamos um ponto-e-vírgula no final da função createCanvas:

   createCanvas(400, 400);

Isso é muito importante. O ponto-e-vírgula indica o fim de um comando, que é o jargão usado pelos programadores para se referirem a funções. Em verdade, programadores profissionais estão acostumados a dar ordens para as máquinas, e seu conjunto de ordens é costumeiramente chamado de programa. Tecnicamente, há outras maneiras de se programar um computador além de empilhar centenas de ordens umas sobre as outras. No entanto, a maioria dos nossos programas será isso mesmo: uma série de ordens que o computador deve executar para realizar uma tarefa. No fim de cada ordem, ou no fim de cada comando, deve haver um ponto-e-vírgula. Não se esqueça dele!

Altere os números dentro dos parênteses para (200, 400) ou (500, 100) e reexecute o programa. O que aconteceu?

Criada uma tela onde desenharemos, vamos para o segundo bloco obrigatório de nossos programas:

function draw() {

}

Esse bloco é formado por uma segunda função, chamada draw. Significa que é o bloco de desenho, onde efetivamente começaremos a pintar em nossa tela criada anteriormente.

Por enquanto, apenas pintamos a tela de cinza com o comando background(220), seguido de um ponto-e-vírgula:

function draw() {
background(220);
}

A palavra background significa fundo. Ou melhor, a cor da tela. O número entre os parênteses é 220. É um número que varia entre 0 e 255, inclusive. O que acontece se o alterarmos dentro desses limites?

Altere o número dentro dos parênteses para qualquer número inteiro entre 0 e 255, inclusive. O que aconteceu quando você mudou para 0? E quando o número foi 255? Anote os resultados.

Vamos agora estudar o sistema de coordenadas da p5.js para podermos de fato desenhar alguma coisa.

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