Introdução à Programação Gráfica

usando Processing

DESENHO

Apresentar o que é uma linguagem de programação

Conhecer a ferramenta Processing que é voltada a  programação de

Entender a sintaxe básica de uma instrução  na linguagem

Aprender a desenhar usando o Processing

O Processing na aula de hoje

Ou seja, trabalharemos com o Processing como se ele fosse um programa como o Paint ou PhotoShop. Mas, programar não significa fazer desenhos! Nos capítulos seguintes, veremos que o Processing não se limita ao desenho, sendo uma ferramenta completa de desenvolvimento que apresenta uma série de poderosas estruturas de programação.

Só hoje

Visualizar, modificar e brincar com  exemplos básicos de código  na linguagem

Imagem retirada de: http://www.flickr.com/photos/strocchi/238573299/

Licença de uso: http://creativecommons.org/licenses/by-sa/2.0/deed.en

Brinque, Experimente

Misture

Diversos exemplos vem disponíveis por padrão com o Processing.

O site OpenProcessing funciona como um Flickr para compartilhamento de sketches feitos em Processing.

Conhecer nossa abordagem de desenvolvimento

Baseado na frase de Kent Beck, ver:

http://www.c2.com/cgi/wiki?MakeItWorkMakeItRightMakeItFast

Faça funcionar

Faça certo

Faça rápido

Entender que Programar pode ser para qualquer pessoa

Programar é construir algoritmos usando estruturas de controle, para manipular informações.

Um algoritmo é uma sequência de passos destinada a resolver um problema e é formado, principalmente, por estruturas de controle as quais serão discutidas posteriormente com mais detalhes.

Programas devem ser feitos para seres humanos

  • Fonte: http://www.ime.usp.br/~pf/algoritmos/aulas/footnotes/epigraphs.html
  • "Programming is best regarded as the process of creating works of literature, which are meant to be read."  [Donald E. Knuth, Literate Programming]

    "A atividade de programação deve ser encarada como um processo de criação de obras de literatura, escritas para serem lidas."

  • "Let us change our traditional attitude to the construction of programs. Instead of imagining that our main task is to instruct a computer what to do, let us imagine that our main task is to explain to human beings what we want a computer to do."  [Donald E. Knuth, Literate Programming]

    "Devemos mudar nossa atitude tradicional em relação à construção de programas. Em vez de imaginar que nossa principal tarefa é instruir o computador sobre o que ele deve fazer, vamos imaginar que nossa principal tarefa é explicar a seres humanos o que queremos que o computador faça."

Vamos imaginar o seguinte problema: criar um esboço da bandeira do Brasil colado em uma cartolina branca.  Além da cartolina, você tem um conjunto de pedaços de papel de diferentes cores: verde, amarelo e azul. Também tem tesoura, cola e uma régua. Em Português coloquial, uma resolução possível deste problema simples é bastante óbvia:

  1. Recortar um retângulo verde;
  2. Colar o retângulo verde na cartolina;
  3. Recortar um losango amarelo;
  4. Colar o losango amarelo;
  5. Recortar um círculo de cor azul;
  6. Cole, por fim, o círculo azul.

Seguimos uma sequencia de ações linear na qual cada ação é executada uma linha após a outra, de cima para baixo. Executando em uma ordem diferente, o resultado pode não ser o esperado. Colando primeiro o losango amarelo na cartolina, por exemplo, invalidaria a construção da bandeira.

Desta forma, em um algoritmo, cada linha corresponde a uma instrução e deve ser lida e interpretada de maneira independente da anterior como se estivéssemos trabalhando com uma receita culinária. Esta sequencia lógica de execução do algoritmo passo a passo é a estrutura sequencial ou sequenciação. Ou seja, a ordem do código escrito importa na ordem de execução.

Embora pareça completa e simples a lista de instruções acima, há algumas questões em aberto. Por exemplo, o retângulo verde é de que tamanho? Ele é maior ou menor que o losango amarelo? O ser humano responde estas questões de maneira intuituiva. Na programação de computadores não há espaço para ambiguidade. Se criássemos um programa para desenhar a bandeira do Brasil, deveríamos definir exatamente quais são as dimensões e posição de qualquer um dos componentes do objeto sendo desenhado. Além disso, não podemos usar a língua portuguesa para especificar comandos para a linguagem. Faz-se necessária a utilização de instruções da linguagem de programação. Para que possamos escrever o algoritmo anterior no Processing será necessário compreender que escrever um programa de computador é muito diferente de escrever um email ou um texto qualquer e a sintaxe deve ser conhecida e respeitada.

Por exemplo, no Processing, o desenho de um retângulo se dá através da  instrução rect. Uma instrução guarda certa semelhança com uma frase na língua portuguesa. Assim, a frase: “Desenhar um retângulo de 80 por 50 na posição 120, 130.”, no Processing deve ser escrito com o código abaixo.

rect(120, 130, 80, 50);

Constata-se que este código apresenta 4 informações numéricas constantes: 120, 130, 80 e 50. Estas informações numéricas são processadas pela função rect, responsável por construir o retângulo. Isto posto, da mesma forma como uma frase da língua humana, há uma série de componentes no código-fonte acima. Pode-se, até mesmo, fazer a analogia com os sujeitos, predicados e objetos de uma oração.

Receita de bolo

Origem da foto: http://www.flickr.com/photos/kankan/256116792/

Indica a ordem de execução de um algoritmo. Cada passo deve ser realizado necessariamente após o outro.

Código desenvolvido no Scratch

Permite a escolha de um conjunto de passos em detrimento do outro conforme uma certa condição seja satisfeita.

Código no Scratch

No Processing

Dá o poder de controlar a quantidade de vezes que um conjunto de passos pode ser executado em um algoritmo

Exemplo no Scratch

Exemplo no Processing

Material que o algoritmo manipula

O material que o algoritmo manipula, ou seja, cada dado, fato ou valor que pode ser trabalhado na memória do computador é uma informação.

Existem diversos formatos que uma informação pode ser armazenada e estes formatos são os chamados tipos primitivos de informação.

Ingredientes do bolo

Número pertencente ao conjunto dos números inteiros, pode ser negativo se acompanhado do sinal “-”. Exemplos: 130, -10, 2700, idade em anos, número de páginas de um livro, posição do mouse no eixo x, posição do mouse no eixo y;

Número pertencente ao conjunto dos números de ponto flutuante. É formado por parte inteira e parte decimal, as quais são separadas através do “.” Exemplos: 1.73, 12.23, PI, salário.

Texto formado por um caractere. Delimitado através do sinal de apóstrofo ('). Exemplos: 'a', 'b', 'Z', '1', '2', tecla pressionada.

texto formado por um conjunto de um ou mais caracteres. Deve ser delimitado por um sinal de aspas (""). Exemplos: "Processing", "Bruno",  "A", seu nome.

O tipo lógico pode assumir dois valores: verdadeiro ou falso. O valor verdadeiro é representado pela palavra true e o valor falso por false. No Processing, o true também pode ser associado ao valor 1 e o false ao valor 0. Exemplos: true, false, interruptor de luz, estado do botão do mouse (pressionado ou não).

println("Oi, Processing");

println("Oi, Processing");

rect(10,20,80,70);

Aprender linguagem de programação é aprender um novo idioma

Aprender uma linguagem de programação é como aprender um novo idioma. Antes da fluência na linguagem, devemos, portanto, conhecer sua sintaxe. Diferente de um idioma, no qual o ser humano interpreta e perdoa os erros do iniciante, em uma linguagem de programação o erro de sintaxe implica em um programa que não funciona. Um programa básico no Processing é formado pelos seguintes componentes: comentários, funções, instruções, expressões e espaços em branco.

Comentários são fragmentos do código que o computador ignora. Sua importância está em escrever recados no programa sobre o que ele faz e comentários em geral sobre o funcionamento de um conjunto de instruções. Bons programadores comentam seu código de maneira que não apenas eles mas também outras pessoas possam entender o que acontece. Outra utilidade do comentário é ocultar pedaços do código que estão incompletos ou com algum problema e que devem ser consertados em outro momento.

No exemplo abaixo, todas as linhas marcadas com // são comentários de código.

// A função size configura a largura e a altura da tela do programa.
// No exemplo abaixo, a tela possui 300 pixels de altura e 200 de largura.
size(300, 200);
// A função background altera a cor de fundo da tela.
// No exemplo abaixo, a tela é pintada na cor branca.
background(255);
// A linha abaixo, embora seja um comando válido, não será executada pois o sinal de comentário está colocado antes do comando
// rect(120, 130, 80, 50);

Outra maneira de criar um comentário é utilizando o conjunto /* e */. Este é o chamado comentário multilinha. Neste caso, o comentário inicia-se com o sinal /* e pode ser estendido a diversas linhas. O comentário é fechado com o sinal */.

/* O programa abaixo é um exemplo simples de como podemos desenhar uma linha no Processing.
Atenção: este programa se preocupa em colorir a linha com a cor vermelha usando a função stroke.
*/
size(300, 200);
background(255);
stroke(255, 0, 0);
line(0, 0, 100, 100);
/* as linhas seguintes estão comentadas, ou seja, não são executadas
stroke(255, 0, 0);
line(100, 100, 200, 200);
*/

O comentário de código (doc comment), por sua vez, é útil para a geração de uma documentação explicativa sobre o programa como um todo. Esta documentação é inserida no documento HTML gerado quando é feita a exportação do código em Processing para o formato applet, o qual permite sua publicação na Web. Após a exportação, todo o texto colocado entre os sinais /** e */ é colocado no arquivo “index.html”. Para exportar um programa em Processing, use o menu File > Export ou tecle CTRL + E.

/**
Exemplo simples de como podemos desenhar uma linha vermelha no Processing.
Atenção: este programa se preocupa em colorir a linha com a cor vermelha usando a função stroke.
*/
size(300, 200);
background(255);
stroke(255, 0, 0);
line(0, 0, 100, 100);
/* As linhas seguintes estão comentadas, ou seja, não são executadas
Estas linhas não serão copiadas no arquivo index.html.
stroke(255, 0, 0);
line(100, 100, 200, 200);
*/

Observa-se que no Processing o comentário é exibido com uma cor diferente em relação ao resto do código.

A documentação é inserida no documento HTML gerado quando é feita a exportação do código em Processing para o formato applet, o qual permite sua publicação na Web. Após a exportação, todo o texto colocado entre os sinais /** e */ é colocado no arquivo “index.html”.

Permitem dar ordens ao programa

Funções (também chamados de módulos ou procedimentos) permitem a transmissão de ordens do programador para o computador. Servem como comandos sendo passados para desenhar, alterar cores, realizar cálculos, executar ações quaisquer, etc. O nome de uma função é geralmente em letra minúscula. Quando uma função é chamada, seu nome deve ser seguido por parênteses. Quando o nome da função é composto por duas palavras, a segunda palavra é conectada na primeira e sua primeira letra é colocada em maiúsculo. Esta não é uma regra obrigatória, mas é uma boa prática para ser seguida quando você cria suas próprias funções. Portanto, além dos procedimentos disponíveis por padrão no Processing é possível definir novas funções para compartimentalizar e organizar o seu código.

No código abaixo, temos exemplos de chamadas às funções linefill, noFill e rect.

// A função size (300, 200) configura a tela para 300 pixels de largura por 200 pixels de altura
size(300, 200);
// A função fill habilita o preenchimento das formas sendo desenhadas a seguir.
// A cor escolhida é uma tonalidade intermediária de cinza
fill(128);
// A função rect desenha uma retângulo de 50 pixels por 30 pixels a partir do ponto (0, 0 )
rect(0, 0, 50, 30);
// A função noFill desabilita o preenchimento das formas.
noFill();
// A função rect desenha um retângulo de 50 pixels por 30 pixels a partir do ponto (10, 10)
// Observe que o retângulo não está preenchido devido à chamada a noFill feita anteriormente.
rect(10, 10, 50, 30);

Funções podem receber parâmetros para alterar ou configurar seu comportamente. Algumas funções, como a noFill, não recebem parâmetros. Outras, como a fill, recebem um parâmetro apenas. As demais funções como a rect podem utilizar mais de um parâmetro e estes parâmetros são separados através de vírgulas.

Importante acrescentar que as funções em Processing são sensíveis ao contexto. Deste modo, as chamadas às funções devem se preocupar com a letras maiúsculas e minúsculas. Por exemplo, a função rect não pode ser chamada escrevendo Rect e nem RECT. Assim, o código abaixo está errado e gera o erro “The function Size(int, int) does not exist.”

Erro ao colocar uma função com o nome errado

Através da combinação de operadores consegue-se a geração de expressões. Existem expressões de diversos tipos: expressões aritméticas, expressões lógicas e expressões relacionais.  Expressões sempre tem como resultado um valor. Exemplos de expressões:

  • 5+6 corresponde ao valor 11;
  • 120.23 – 0.23 corresponde ao valor 120;
  • “Bruno ” + ” Campagnolo” corresponde ao valor “Bruno Campagnolo”;
  • ((3*5)+4) corresponde ao valor 19;
  • 5 > 3 corresponde ao valor true, pois 5 é maior que 3;
  • 52 == 52 corresponde ao valor true, pois 52 é igual a 52;
  • 51 < 41 corresponde ao valor false, pois 51 não é menor que 41.

As expressões podem ser usadas diretamente como parâmetro de uma função:

// A função rect chamada abaixo desenha um retângulo de 50 pixels por 30 pixels a partir do ponto (20, 30).
// Observe que 10+10 corresponde a 20 e 3 * 10 dá o resultado da multiplicação de 3 por 10.
rect(10+10, 3*10, 50, 30);

Assim, um conjunto de expressões e funções define uma instrução, a qual deve ser sempre finalizada pelo sinal “;”. Muito cuidado deve ser dedicado à utilização deste sinal, pois quando você esquece de colocar um ponto e vírgula em um programa, o Processing reclama com o erro “Syntax error, maybe a missing semicolon?”.

Existem diferentes tipos de instrução. Por enquanto, conhecemos apenas as instruções úteis para a chamada de funções.

O programador não precisa se preocupar com a quantidade de espaços em branco que usa entre os elementos de seu programa. Por espaços em branco leia-se: quebras de linha, tabulações e espaços normais. Deve-se preferir, porém, a representação de cada instrução em apenas uma linha e reservar os espaços  para situações onde algum esclarecimento é necessário.

size
(300     ,
200          );
background(                   200)
;

Quando se faz um desenho na tela do computador é necessária, primeiramente, a especificação do tamanho da área útil de desenho. Esta área é formada por pequenos pontos de luz chamados pixels.

Cada pixel é identificado por uma cor e por uma posição. Em relação a posição de um ponto, utiliza-se um sistema de coordenadas cartesianas semelhante ao da matemática. Ou seja,  uma primitiva é caracterizada por um valor de posicionamento no eixo x e outro no eixo y. No Processing, a origem dos eixos está na lateral superior esquerda da tela. Assim, o eixo x tem seus valores crescendo da esquerda para a direita e o eixo y inicia-se em cima e cresce até a parte de baixo da tela. A notação de um ponto se dá através do valor de x, seguido pelo valor de y e separados por uma vírgula.

Assim, quando se fala em uma tela com resolução 800×600, isso significa que a tela contém uma matriz de 800 pixels de largura por 600 pixels de altura. Isso significa 480 mil pontos de luz na tela. Embora este valor possa parecer elevado, o olho humano é bastante exigente e outro fator que influencia na qualidade de uma imagem é o número de pontos que estão contidos em uma unidade de área. Uma unidade comumente utilizada é o pontos por polegada quadrada (dots per inch – dpi). Bons monitores tem resoluções de 100 dpi. Este valor nem chega perto da resolução de algumas impressoras modernas.

Os programas em Processing, portanto, além de configurarem o tamanho do conjunto de pixels que será utilizado como área de desenho devem também se preocupar com a melhor maneira de preencher estes pixels para melhorar a visualização do ser humano em relação à baixa resolução da tela do computador. Um zoom na tela do computador mostra esse problema em detalhe.

Pixels são pontos na tela

Eixo invertido em relação à matemática

  • (0, 0): Origem padrão do eixo, ponto superior esquerdo;
  • (99,0): Pixel na superior direita;
  • (0, 99): Pixel na inferior esquerda;
  • (99, 99): Pixel na inferior direita.

O eixo pode ser em 3d.

Fonte: http://www.processing.org/learning/drawing/

O eixo pode ser transformado

A cor de fundo desta janela por padrão é cinza claro. Para alterar esse valor, a função background é usada para modificar a cor de desenho do fundo da tela. Esta função pode receber um ou mais parâmetros. Não é escopo deste capítulo os diferentes sistemas de representação de cores na tela do computador configurados por estes parâmetros. Futuramente, trataremos destes sistemas, mas, por enquanto, através do menu Tools > Color Selector é possível obter o código de cor referente a uma cor. Se, simplesmente um número entre 0 e 255 for fornecido, a cor de fundo será configurada entre o preto (valor 0) e o branco, com tons intermediários de cinza entre estes dois valores. O valor cinza claro, por exemplo, corresponde ao valor 204.

Duas outras funções para lidar com as cores são a função stroke e a função fill, respectivamente, permitindo alteração da cor das linhas e bordas e a cor de preenchimento das formas básicas. Outras duas funções auxiliares a estas são a função noStroke e a função noFill, as quais desabilitam as linhas e bordas e o preenchimento das formas. Na próxima seção trataremos destas formas, mostrando o que acontece quando se combina a chamada destas quatro funções.

http://www.processing.org/learning/color/

http://www.processing.org/learning/trig/

A função rotate permite a rotação do eixo

Rotações também podem ser feitas em relação aos eixos

Rotações devem ser em radianos

Funções que trabalham com formas primitivas retas

Dezenas de funções de desenho

Valores que não mudam no código

Constantes não variam com o tempo durante a execução de um programa

No exemplo, há 10 valores constantes

Anteriormente, verificou-se que o Processing trabalha com os tipos de dados: inteiro, ponto flutuante, caractere, string e lógico. Tais tipos de dados em nossos programas até agora foram representados de maneira constante. Por exemplo, no programa abaixo, que desenha duas linhas que dividem a tela, os valores 300, 200, 100, 0 e 200 não variam durante a execução do programa.

Tais valores são constantes. Assim, para criar um novo programa que divida novamente a tela em 3 partes será necessária a atualização de diversas constantes dentro do programa. Variáveis resolvem este problema e permitem que se organize o código e se crie dependência de parâmetros em relação a outros. Na memória do computador, variáveis são containers para armazenar informações, permitindo que um dado mude de valor e seja reutilizado diversas vezes em um programa. Na utilização do ambiente do Processing, existem variáveis que já existem durante a execução e variáveis que o programador pode definir.

size(300, 200);
line(100, 0, 100, 200);
line(200, 0, 200, 200);

Podem ser alteradas em algum instante da execução

Armazenadas na memória do computador

Cada variável é uma gaveta com um rótulo

Variáveis podem ser reutilizadas infinitas vezes

Memória do computador 

Armário cheio de gavetas

Declaração de variáveis

tipo nome;

Para que se possa criar essas gavetas no armário, ou melhor, declarar as variáveis na memória é necessário configurar qual é o tipo de informação que pode ser armazenado em cada variável. Este processo de declaração é formado por três partes: tipo da variável, nome da variável e, opcionalmente, o valor inicial da variável após o comando de atribução (”=”).

tipo nome = valor;

Tipo de objetos que "cabem na gaveta"

Não pode mudar durante a execução

int a = 13.3; // Erro!
float a = 1;
int b = a + 12.4; // Erro!

Também não é possível misturar tipos que não sejam conversíveis. Por exemplo, o tipo ponto flutuante não “serve” dentro do tipo inteiro. A mensagem de erro dada é:  “cannot convert from float to int”.

O que está no "rótulo da gaveta"

Em relação aos nomes de variáveis, os exemplos mostrados até agora caracterizaram-se por usar apenas uma letra para dar nome à variável. Embora esta seja uma prática válida, é altamente recomendável a escolha de nomes significativos para descrever cada variável. Por exemplo, para representar uma variável que indica a cor do fundo de um programa algumas opções interessantes ao invés de “f” ou “c” seriam:

  • fundo
  • corFundo
  • corDeFundo

Nomes como “CORDEFUNDO”, “CorDeFundo” e “cordefundo” embora sejam válidos para a linguagem de programação, fogem de uma certa convenção de nomenclatura recomendável para facilitar a leitura de seus programas. Esta convenção depende de cada linguagem. No Processing, utiliza-se o chamado CamelCase, recomendando-se que:

  • O nome de todas as variáveis seja iniciado com letra minúscula e nunca por um número;
  • Se o nome da variável for composto por mais de uma palavra, as palavras seguintes devem ter sua primeira letra maiúscula;
  • Variáveis que nunca mudam de valor durante a execução de um programa, ou, na prática, constantes são nomeadas de maneira diferente e todas as letras devem ser capitalizadas. Por exemplo: CORNER, CENTER, indicam valores constantes.

Também se deve salientar que alguns caracteres não podem ser usados para dar nome às variáveis. Neste conjunto se incluem os espaços, caracteres especiais ($, %, &, * , -, etc) e caracteres acentuados. Além disso, as variáveis também não podem ser nomeadas com as palavras-reservadas da linguagem Processing. E, embora seja possível, é altamente não recomendável utilizar  o nome de funções já existentes para dar nome.  Ou seja, “rect” e “ellipse” são nomes que devem ser evitados e “int” e “float” são inválidos.

Deve ser único

Após uma variável ser criada com um tipo de dado ele não pode ser trocado ou redefinido.

// Código com erro

float a= 12;

int a = 13;

// a começa com valor 1

int a = 1;

// b começa com valor 2

int b = 2;

// c começa com valor 3

int c = a + b;

// d tem valor desconhecido.

int d;

// s começa com valor "Bruno"

String s = "Bruno";

Para serem usadas variáveis devem possuir primeiro um valor

int a = 1; // a começa com valor 1
int b = 2; // b começa com valor 2
int c = a + b; // c começa com valor 3
int d; // d tem valor desconhecido
int e = d * 2; // e é igual ao dobro de d, esta linha levanta um erro!

Observe que o valor da variável chamada d é desconhecido até a execução da última linha. Qualquer tentativa em utilizar a variável d levantará um erro de execução.

Atribuição de valor em uma variável

=

A inicialização da variável não necessariamente precisa ser feita durante a linha de declaração. O sinal de recebe (=) deve ser usado para atribuir um valor a uma variável.

Leitura da direita para a esquerda

int a = 1; // a começa com valor 1
int b = 2; // b começa com valor 2
int c = a + b; // c começa com valor 3
int d;
d= 4;
int e = d * 2; // e é igual ao dobro de d, ou seja 8.

int a = 1; // a começa com valor 1
int b = 2; // b começa com valor 2
int c = a + b; // c começa com valor 3
int d;
d= 4;
int e = d * 2; // e é igual ao dobro de d, ou seja 8.

Declaração resumida de variáveis

,

int a, b, c, d, e;
a = 1; // a começa com valor 1
b = 2; // b começa com valor 2
c = a + b; // c começa com valor 3
d= 4;
e = d * 2; // e é igual ao dobro de d, ou seja 8.

int a, b, c, d, e;
a = 1; // a começa com valor 1
b = 2; // b começa com valor 2
c = a + b; // c começa com valor 3
d= 4;
e = d * 2; // e é igual ao dobro de d, ou seja 8.

Variáveis do Processing

O Processing já possui uma série de variáveis que são criadas no momento de execução do programa. Tais variáveis não precisam ser declaradas e são atualizadas de maneira indireta através da chamada à funções e à interação com o programa. A variável width reflete a largura da janela do programa e a variável height contém o valor da altura. A chamada à função size modifica o valor destas variáveis, mas, caso não seja chamada, tanto a largura quanto a altura ficarão com valor de 100 pixels.

A importância de usar estas funções está em deixar o seu programa facilmente adaptável caso haja uma modificação apenas no tamanho da janela.

Não precisam ser declaradas

Deixam o programa adaptável

size(300, 200);
line(100, 0, 100, 200);
line(200, 0, 200, 200);
line(0, 100, 300, 100);
//A importância de usar estas funções está em deixar o seu programa facilmente 
//adaptável caso haja uma modificação apenas no tamanho da janela. A seguir, por 
//exemplo, cria-se um programa para dividir a tela em seis partes iguais.

size(300, 200);
line(100, 0, 100, 200);
line(200, 0, 200, 200);
line(0, 100, 300, 100);
size(450, 100);
line(width/3, 0, width/3, height);
line(width/3*2, 0, width/3*2, height);
line(0, height/2, width, height/2);
// Caso o valor de size seja modificado, todas as demais constantes devem ser 
// modificadas. Com o uso de width e height como parâmetros, valores diferentes 
// de size mantem a mesma proporção.

size(450, 100);
line(width/3, 0, width/3, height);
line(width/3*2, 0, width/3*2, height);
line(0, height/2, width, height/2);
focused: valor lógico que indica se o usuário está com o foco na janela do programa executando; frameCount: no modo contínuo, é um número inteiro que contém o número de frames mostrados desde o início da execução do programa. Cada chamada ao método draw incrementa este valor; frameRate: valor aproximado de taxa de atualização máxima de frames na execução do programa em modo contínuo; online: valor lógico que representa se o programa está sendo executado dentro de uma página Web ou não; screen.width: largura da tela do computador em pixels; screen.height: altura da tela do computador em pixels; mouseButton: indica qual dos botões do mouse foi pressionado (LEFT, CENTER ou RIGHT); mousePressed: valor lógico que indica se qualquer botão do mouse foi pressionado; mouseX: posição horizontal do mouse (eixo X) no frame atual; mouseY: posição vertical do mouse (eixo Y); pmouseX: posição horizontal do mouse (eixo X) no frame anterior; pmouseY: posição vertical do mouse (eixo Y) no frame anterior; key: contém o valor da mais recente tecla pressionada ou solta; keyCode: usada para detectar o pressionamento de teclas especiais como UP, DOWN, RIGHT e LEFT; keyPressed: valor lógico que indica se qualquer tecla foi pressionada.

Exibição de variáveis

Para exibir o valor de uma variável em um instante pode-se usar as funções print e println. Tais funções exibem informações na área de texto denominada console do Processing. O usuário nunca terá acesso a estas informações, pois o console do Processing é de exclusivo acesso do programador. Entretanto, muitas vezes, quando for necessária a depuração e correção de código com erro, as funções print e println permitirão ao programador a verificação dos valores de cada variável no momento desejado.

No exemplo, a função println mostra os valores das expressões que usam as variáveis width e height.

Usando as variáveis width e height para deixar o programa com resolução dinâmica

Há diferentes maneiras de manter a simetria em seu desenho.

Você pode deixar os parâmetros de desenho dependentes das variáveis width (largura) e height (altura).

Por exemplo, ao invés de:

line(250,0,250,500);

ellipse(250, 125, 83, 83);

rect(166, 166, 166, 166);

rect(166,332, 41, 166);

rect(291, 332, 41, 166);

Você pode substituir por valores proporcionais à largura e altura.

size(500,500);

line(width/2,0,width/2,height);

ellipse(width/2, height/4, width/6, height/6);

rect(width/3, height/3, width/3, height/3);

rect(width/3,height/3*2, width/12, height/3);

rect(width/3*2-width/12,height/3*2, width/12, height/3);

Neste caso, se você alterar a largura e a altura da tela o desenho se adapta à nova altura e largura.

size(500,500);

line(250,0,250,500);

ellipse(250, 125, 83, 83);

rect(166, 166, 166, 166);

rect(166,332, 41, 166);

rect(291, 332, 41, 166);

size(500,500);

line(width/2,0,width/2,height);

ellipse(width/2, height/4, width/6, height/6);

rect(width/3, height/3, width/3, height/3);

rect(width/3,height/3*2, width/12, height/3);

rect(width/3*2-width/12,height/3*2, width/12, height/3);

Usando variáveis para centralizar configurações

É uma boa prática centralizar as cores que você usou em seu código no início de seu programa.

Assim, toda vez que precisar de uma cor utilizará a variável relacionada a esta cor.

Além disso, fica fácil a mudança das cores de seu programa, já que estas estão em um lugar só.

size(600,500);

color corCabeca = color(255,0,0);

color corCorpo  = color(0,255,0);

color corPerna  = color(0,0,255);

line(width/2,0,width/2,height);

fill(corCabeca);

ellipse(width/2, height/4, width/6, height/6);

fill(corCorpo);

rect(width/3, height/3, width/3, height/3);

fill(corPerna);

rect(width/3,height/3*2, width/12, height/3);

rect(width/3*2-width/12,height/3*2, width/12, height/3);

Técnica para descobrir o valor das variáveis de um programa

Execute passo a passo o algoritmo

Em um ponto qualquer, escreve um texto

Antes de exibir o texto é necessário selecionar a fonte

Se necessária a exibição de uma variável para o usuário pode-se usar a função text para mostrar o valor da variável na tela. A utilização da função text, porém, não pode ser feita sozinha. Por exemplo, o código abaixo, ao ser executado, indica o erro de falta de indicação de qual fonte deve ser utilizada: “Use textFont() before text()”.

Seleciona a fonte atual

Converte fonte disponível no computador para Processing

Processo lento para criação da fonte

Carrega uma fonte gerada anteriormente

Usa ferramenta de geração de fontes

A fonte dentro da pasta do projeto

Listar as fontes disponíveis no sistema

PFont font;
// A fonte deve ser criada através da ferramenta de geração de fontes 
// Ela é armazenada dentro da pasta "data" dentro do projeto
font = loadFont("AgencyFB-REG-48.vlw"); // Carrega a fonte
textFont(font, 32); // Seleciona a fonte com tamanho 32
text("word", 15, 50); // Exibe o texto na posição 15,50

Tem Parâmetros e Retorno

Podem ter efeitos colaterais

Anatomia de um código

Funções sem retorno

Função com retorno

Composição de funções

Armazenamento do retorno da função

Expressões Aritméticas

A matemática pode ser utilizada para produzir forma e movimento em um programa. Os operadores aritméticos tradicionais, embora sejam bastante intuitivos podem ser aplicados na criação de comportamentos complexos, principalmente quando misturados entre si para gerar funções.

Adiciona dois valores ou concatena dois strings. Pode ser usado para modificar a posição de um elemento na tela em relação a uma coordenada existente, deixando o elemento mais à direita em relação ao eixo x ou mais para baixo em relação ao eixo y.

Adiciona dois valores

Concatena strings

Incrementa uma variável

Desloca para a direita no eixo x

Descola para baixo no eixo y

float inicio       = 10;

float deslocamento = 50;

float posicaoX      = inicio;

fill(255,0,0); // Vermelho

rect(posicaoX, 10, 20, 30); // Retângulo

posicaoX = posicaoX + deslocamento; // Desloca para a direita

fill(0,255,0); // Verde

rect(posicaoX, 10, 20, 30); // Retângulo

Subtrai dois valores. Semelhante ao operador “+”, o – também pode deslocar um elemento. No caso do operador – o elemento é deslocado para cima em relação ao eixo y e para a esquerda em relação ao eixo x. O operador “-” também pode ser usado para inverter uma direção de movimento.

Subtrai dois valores

Desloca para esquerda no eixo x

Desloca para cima no eixo y

float inicio       = 60;

float deslocamento = 50;

float posicaoY     = inicio;

fill(255,0,0); // Vermelho

rect(10, posicaoY, 20, 30); // Retângulo

posicaoY = posicaoY - deslocamento; // Desloca para a cima

fill(0,255,0); // Verde

rect(10, posicaoY, 20, 30); // Retângulo

Multiplica dois valores. Sua utilidade está, por exemplo, no reescalonamento de uma posição. A operação de multiplicação por zero também terá vez em relação à habilitação de desenho de um elemento.

Multiplica dois valores

Reescalonamento de uma posição ou tamanho

Multiplicar por zero esconde um desenho

float largura       = 5;

float escala        = 2;

background(255);   // Fundo branco

strokeWeight(2);   // Tamanho do pincel

noFill();           // Sem preenchimento

stroke(255,0,0);    // Cor do pincel

rect(10, 10, largura, 30); // Retângulo

largura = largura * escala; // Duplica a largura

stroke(0,255,0); // Verde

rect(10, 10, largura, 30); // Retângulo

largura = largura * escala; // Duplica a largura

stroke(0,0,255); // Azul

rect(10, 10, largura, 30); // Retângulo

largura = largura * escala; // Duplica a largura

stroke(255,255,0); // Amarelo

rect(10, 10, largura, 30); // Retângulo

largura = largura * escala; // Duplica a largura

stroke(255,0,255); // Rosa

rect(10, 10, largura, 30); // Retângulo

Divide um valor por outro. Indica quantas vezes um elemento serve dentro de outro. Operações com “/” podem ser usadas, por exemplo, para criar funções que aumentam de uma unidade após um certo tempo.

Divide um valor por outro

Reescalonamento de uma posição

Útil em animações periódicas

size(110,100);

float largura       = 90;

float escala        = 3;

background(255);   // Fundo branco

strokeWeight(2);   // Tamanho do pincel

noFill();           // Sem preenchimento

stroke(255,0,0);    // Cor do pincel em vermelho

rect(10, 10, largura, 30); // Retângulo

largura = largura / escala; // Divide a largura

stroke(0,255,0); // Verde

rect(10, 10, largura, 30); // Retângulo

largura = largura / escala; // Divide a largura

stroke(0,0,255); // Azul

rect(10, 10, largura, 30); // Retângulo

largura = largura / escala; // Divide a largura

stroke(255,255,0); // Amarelo

rect(10, 10, largura, 30); // Retângulo

largura = largura / escala; // Divide a largura

stroke(255,0,255); // Rosa

rect(10, 10, largura, 30); // Retângulo

Retorna o resto inteiro da divisão. Usado para restringir um conjunto de números a um intervalo desejado.

Este operador permite que se criem expressões aritméticas que tem como resultado o resto inteiro de uma divisão. Exemplos:

  • 6 % 3 é igual a 0,  já que 6 dividido por 3 dá 2 e o resto é 0, então 6 % 3 é igual a 0;
  • 14 % 4 é igual a 2,  já que 14 dividido por 4 é igual a 3 (4*3 = 12) e o resto é 2, então 14 % 4 é igual a 2;
  • 35 % 3 é igual a 2, já que 35 dividido por 3 é igual a 11 ( 3 * 11 = 33) e o resto é 2, então 35 % 3 é igual a 2;
  • 3 % 10 é igual a 3, já que 3 dividido por 10 é igual a 0 (3 * 0 = 0) e o resto é 3, então 3 % 10 é igual a 3.

Para entender melhor o significado do módulo, observe a tabela, com a variação de x sendo incrementado e a aplicação do módulo de 3 em cada valor.

x x % 3
0 0
1 1
2 2
3 0
4 1
5 2
6 0
7 1
8 2
9 0
10 1
11 2

Na tabela, o valor de x % 3 possui um comportamento periódico que vai se repetindo de 3 em 3 aplicações do operador. Caso fosse aplicado o módulo de 4 o valor se repetiria de 4 em 4 aplicações, e assim sucessivamente.

Resto inteiro da divisão

Útil em animações periódicas

Útil para repetição de padrões periódicos

Restringe um conjunto de números a um intervalo

x x % 3
0 0
1 1
2 2
3 0
4 1
5 2
6 0
7 1
8 2
9 0
10 1
11 2

size(200,200);

smooth();

int   n = 0;

float posicao;

posicao = (n % 3) * 20;

ellipse(posicao+100,n*10,15,15);

n = n + 1;

posicao = (n % 3) * 20;

ellipse(posicao+100,n*10,15,15);

n = n + 1;

posicao = (n % 3) * 20;

ellipse(posicao+100,n*10,15,15);

n = n + 1;

posicao = (n % 3) * 20;

ellipse(posicao+100,n*10,15,15);

n = n + 1;

posicao = (n % 3) * 20;

ellipse(posicao+100,n*10,15,15);

n = n + 1;

posicao = (n % 3) * 20;

ellipse(posicao+100,n*10,15,15);

n = n + 1;

posicao = (n % 3) * 20;

ellipse(posicao+100,n*10,15,15);

n = n + 1;

posicao = (n % 3) * 20;

ellipse(posicao+100,n*10,15,15);

n = n + 1;

posicao = (n % 3) * 20;

ellipse(posicao+100,n*10,15,15);

Expressões Relacionais

Uma expressão relacional é obtida quando dois valores são comparados. Esta comparação tem como resultado um valor lógico. Tal valor pode ser o valor verdadeiro (true) ou o falso (false).

Devolve verdadeiro quando dois operandos são iguais

println(int(3==3));
println(int(3==4));
println(int(30!=40));
println(int(40!=40));
println(int(10>5));
println(int(10<5));
println(int(10>10));
println(int(10>=10));

Conversão de boolean para inteiro

Usar a função int

println(int(3==3));
println(int(3==4));
println(int(30!=40));
println(int(40!=40));
println(int(10>5));
println(int(10<5));
println(int(10>10));
println(int(10>=10));

Divisão de um problema complexo em pedaços menores

Reduz complexidade

Facilita a manutenção

Permite o compartilhamento de código

Técnica de refinamentos sucessivos (top down)

Também existe técnica bottom-up

Vamos chamar o pedaço associado à função de bloco de código

O Processing ajuda a localizar as chaves

são formadas por um bloco principal

podem ser chamadas a partir de seu nome

Função setup

Chamada automaticamente quando o programa inicia

Pode chamar outras funções

void setup() {

   rect(10,10,80,80);

   rect(30,30,60,60);

}

Se você usar a função setup todos os comandos deverão ser chamados a partir dela

Colocar comando fora do setup

Esquecer a abertura da chave

Esquecer o fechamento da chave

Declaração da função

tipo retorno nome(parametros) {

   instruções;

   // Opcional:

   return valor;

}

Função sem parâmetros e sem retorno

void desenharCabeca() {

  noFill();

  ellipse(40,20,10,10);

  ellipse(60,20,10,10);

  ellipse(50,30, 40,40);

}

void desenharCabeca() {

  noFill();

  ellipse(40,20,10,10);

  ellipse(60,20,10,10);

  ellipse(50,30, 40,40);

}

Função com parâmetros e sem retorno

void desenharCabeca(float diametro) {

  noFill();

  ellipse(40,20,diametro/4,diametro/4);

  ellipse(60,20,diametro/4,diametro/4);

  ellipse(50,30,diametro,diametro);

}

void setup() {

  desenharCabeca(60);

}

void desenharCabeca(float diametro) {

  noFill();

  ellipse(40,20,diametro/4,diametro/4);

  ellipse(60,20,diametro/4,diametro/4);

  ellipse(50,30,diametro,diametro);

}

void setup() {

  desenharCabeca(60);

}

Função sem parâmetros e com retorno

color sortearCor() {

  float vermelho = random(0,256);

  float verde    = random(0,256);

  float azul     = random(0,256);

  color c = color(vermelho, verde, azul);

  return c;

}

void setup() {

  color c = sortearCor();

  background(c);

}

color sortearCor() {

  float vermelho = random(0,256);

  float verde    = random(0,256);

  float azul     = random(0,256);

  color c = color(vermelho, verde, azul);

  return c;

}

void setup() {

  color c = sortearCor();

  background(c);

}

Função com parâmetros e com retorno

float maiorDistancia(float x1, float y1, float x2, float y2, float x3, float y3) {

  float dist1 = dist(x1,y1,x2,y2);

  float dist2 = dist(x1,y1,x3,y3);

  float maxDist = max(dist1,dist2);

  return maxDist;

}

void setup() {

 

  line(10,10,20,20);

  line(10,10,10,50);

 

  float maiorDistancia = maiorDistancia(10,10,

                                        20,20,

                                        10,50);

  println("Distancia maxima:" + maiorDistancia);

}

float maiorDistancia(float x1, float y1, float x2, float y2, float x3, float y3) {

  float dist1 = dist(x1,y1,x2,y2);

  float dist2 = dist(x1,y1,x3,y3);

  float maxDist = max(dist1,dist2);

  return maxDist;

}

void setup() {

 

  line(10,10,20,20);

  line(10,10,10,50);

 

  float maiorDistancia = maiorDistancia(10,10,

                                        20,20,

                                        10,50);

  println("Distancia maxima:" + maiorDistancia);

}

Chamada a uma função criada

Escrever o nome da função seguido dos parâmetros

void desenharCabeca() {

  noFill();

  ellipse(40,20,10,10);

  ellipse(60,20,10,10);

  ellipse(50,30, 40,40);

}

void setup() {

 desenharCabeca();

}

Boa prática de formatação de código

dois espaços na frente de cada comando

Fácil de dar manutenção

void setup() {

    line(10,10,20,20);

    line(10,10,10,50);

}

void setup() {

line(10,10,20,20);

line(10,10,10,50);

}

void setup() {

    line(10,10,20,20);

line(10,10,10,50);

       line(10,10,20,20);

}

As variáveis criadas em uma função valem apenas para esta função

Não tem por padrão no Processing

String nome = javax.swing.JOptionPane.showInputDialog("Qual é seu nome?");

textAlign(CENTER);

PFont f = createFont("",10);

textFont(f);

text("Oi, " + nome, width/2, height/2);

String nome = javax.swing.JOptionPane.showInputDialog("Qual é seu nome?");

textAlign(CENTER);

PFont f = createFont("",10);

textFont(f);

text("Oi, " + nome, width/2, height/2);

String sDiametro = javax.swing.JOptionPane.showInputDialog("Qual é o diâmetro do círculo?");

float diametro = float(sDiametro);

ellipse(width/2,height/2,diametro,diametro);

Funções recursivas infinitas

Funções recursivas são funções que chamam a si próprias

Recursivas infinitas chamam a si próprias infinitas vezes

A natureza é rica em estruturas recursivas

Fonte: http://www.flickr.com/photos/70626035@N00/2546625778/

criar estruturas complexas que possuem partes que se repetem

Recursão é bastante difícil de entender

O pensamento humano não é recursivo

É difícil de chegar em uma solução nova sem experiência em recursão

Existem figuras que só podem ser desenhadas via código

Modelo de recursão infinita

void funcao() {

  // Passo a ser repetido

  funcao();

}

Modelo de recursão infinita com passagem de parâmetros

void funcao(int a) {

  // Passo a ser repetido

  // Faça algo com o valor de a

  funcao(a);

}

Acompanhando uma função infinita passo a passo

// Esta função salva um arquivo de imagem no formato

void salvarPasso() {

  // Seleciona o arquivo para salvar a imagem

  String arquivo = selectOutput();

  // Salva o arquivo no formato png.

  save(arquivo+".png");

}

void funcao() {

  // Passo a ser repetido

  salvarPasso();

  funcao();

}

// Esta função salva um arquivo de imagem no formato

void salvarPasso() {

  // Seleciona o arquivo para salvar a imagem

  String arquivo = selectOutput();

  // Salva o arquivo no formato png.

  save(arquivo+".png");

}

void retanguloRecursivo() {

  rectMode(CENTER); // Os dois primeiros parâmetros determinam o centro do retângulo

  rect(0,0,100,100);

  rotate(PI/8); // Rotaciona 12 graus

  salvarPasso();

  retanguloRecursivo();

}

void setup() {

  size(300,300);

  background(255);

  translate(width/2, height/2);

  retanguloRecursivo();

}

Um objeto é desenhado dentro do outro

O objeto interior é semelhante  ao exterior

// Esta função salva um arquivo de imagem no formato

void salvarPasso() {

  // Seleciona o arquivo para salvar a imagem

  String arquivo = selectOutput();

  // Salva o arquivo no formato png.

  save(arquivo+".png");

}

void retanguloConcentrico() {

  rectMode(CENTER);

  rect(0,0,100,100); 

  scale(0.9);

  salvarPasso();

  retanguloConcentrico();

}

void setup() {

  size(300,300);

  background(255);

  translate(width/2, height/2);

  retanguloConcentrico();

}

// Esta função salva um arquivo de imagem no formato

void salvarPasso() {

  // Seleciona o arquivo para salvar a imagem

  String arquivo = selectOutput();

  // Salva o arquivo no formato png.

  save(arquivo+".png");

}

void circuloConcentrico() {

  ellipse(0,0,100,100); 

  scale(0.7);

  salvarPasso();

  circuloConcentrico();

}

void setup() {

  size(300,300);

  background(255);

  translate(width/2, height/2);

  circuloConcentrico();

}

Um objeto é formado por outros menores

Pode ser formado pela rotação de um objeto não concêntrico

// Esta função salva um arquivo de imagem no formato

void salvarPasso() {

  // Seleciona o arquivo para salvar a imagem

  String arquivo = selectOutput();

  // Salva o arquivo no formato png.

  save(arquivo+".png");

}

void trianguloComposto() {

  beginShape();

  vertex(-10,0);

  vertex(0,-100);

  vertex(10,0);

  endShape(CLOSE);

  rotate(PI/4);

  salvarPasso();

  trianguloComposto();

}

void setup() {

  size(300,300);

  background(255);

  translate(width/2, height/2);

  trianguloComposto();

}

Gerados a partir da repetição de linhas de tamanho igual

A soma dos ângulos externos de um polígono convexo é igual a

// Esta função salva um arquivo de imagem no formato

void salvarPasso() {

  // Seleciona o arquivo para salvar a imagem

  String arquivo = selectOutput();

  // Salva o arquivo no formato png.

  save(arquivo+".png");

}

void hexagono() {

  line(0,0,0,-50);

  translate(0,-50);

  rotate(2*PI/6);

  salvarPasso();

  hexagono();

}

void setup() {

  size(300,300);

  background(255);

  translate(width/2, height/2);

  hexagono();

}

// Esta função salva um arquivo de imagem no formato png

void salvarPasso() {

  // Seleciona o arquivo para salvar a imagem

  String arquivo = selectOutput();

  // Salva o arquivo no formato png.

  save(arquivo+".png");

}

void octogono() {

  line(0,0,0,-50);

  translate(0,-50);

  rotate(2*PI/8);

  salvarPasso();

  octogono();

}

void setup() {

  size(300,300);

  background(255);

  translate(width/2, height/2);

  octogono();

}

void poliReg(float passo, float lados) {

  line(0,0,0,-passo);

  translate(0,-passo);

  rotate(2*PI/lados);

  salvarPasso();

  poliReg(passo, lados);

}

// Esta função salva um arquivo de imagem no formato png

void salvarPasso() {

  // Seleciona o arquivo para salvar a imagem

  String arquivo = selectOutput();

  // Salva o arquivo no formato png.

  save(arquivo+".png");

}

void poliReg(float passo, float lados) {

  line(0,0,0,-passo);

  translate(0,-passo);

  rotate(2*PI/lados);

  salvarPasso();

  poliReg(passo, lados);

}

void setup() {

  size(300,300);

  background(255);

  translate(width/2, height/2);

  poliReg(30, 5);

}

Procedimento semelhante ao de um polígono regular

Alterando o ângulo externo de uma estrela se  altera o número de pontas

Cada vez que se realiza um giro de 360 graus a estrela é fechada

// Esta função salva um arquivo de imagem no formato png

void salvarPasso() {

  // Seleciona o arquivo para salvar a imagem

  String arquivo = selectOutput();

  // Salva o arquivo no formato png.

  save(arquivo+".png");

}

void estrelaDe5Pontas() {

  line(0,0,0,-50);

  translate(0,-50);

  rotate(radians(144));

  salvarPasso();

  estrelaDe5Pontas();

}

void setup() {

  size(300,300);

  background(255);

  translate(width/2, height/2);

  estrelaDe5Pontas();

}

// Esta função salva um arquivo de imagem no formato png

void salvarPasso() {

  // Seleciona o arquivo para salvar a imagem

  String arquivo = selectOutput();

  // Salva o arquivo no formato png.

  save(arquivo+".png");

}

void estrela() {

  line(0,0,0,-50);

  translate(0,-50);

  rotate(radians(80));

  salvarPasso();

  estrela();

}

void setup() {

  size(300,300);

  background(255);

  translate(width/2, height/2);

  estrela();

}

// Esta função salva um arquivo de imagem no formato png

void salvarPasso() {

  // Seleciona o arquivo para salvar a imagem

  String arquivo = selectOutput();

  // Salva o arquivo no formato png.

  save(arquivo+".png");

}

void estrela() {

  line(0,0,0,-50);

  translate(0,-50);

  rotate(radians(150));

  salvarPasso();

  estrela();

}

void setup() {

  size(300,300);

  background(255);

  translate(width/2, height/2);

  estrela();

}

void poli(float passo, float angulo) {

  line(0,0,0,-passo);

  translate(0,-passo);

  rotate(radians(angulo));

  salvarPasso();

  poli(passo, angulo);

}

Poliespirais são polígonos cujo lado cresce ou diminui a cada passo

// Esta função salva um arquivo de imagem no formato png

void salvarPasso() {

  // Seleciona o arquivo para salvar a imagem

  String arquivo = selectOutput();

  // Salva o arquivo no formato png.

  save(arquivo+".png");

}

void poliEspiral(float passo, float angulo, float incremento) {

  line(0,0,0,-passo);

  translate(0,-passo);

  rotate(radians(angulo));

  salvarPasso();

  poliEspiral(passo+incremento, angulo, incremento);

}

void setup() {

  size(300,300);

  background(255);

  translate(width/2, height/2);

  poliEspiral(10,45,2);

}

Espirais também podem ser desenhadas com pontos ou círculos  em suas extremidades

void espiral(float passo, float angulo, float incremento) {

  ellipse(0,-passo,10,10);

  translate(0,-passo);

  rotate(radians(angulo));

  salvarPasso();

  espiral(passo+incremento, angulo, incremento);

}

// Esta função salva um arquivo de imagem no formato png

void salvarPasso() {

  // Seleciona o arquivo para salvar a imagem

  String arquivo = selectOutput();

  // Salva o arquivo no formato png.

  save(arquivo+".png");

}

void setup() {

  size(300,300);

  background(255);

  translate(width/2, height/2);

  espiral(10,122,3);

}

 

void espiral(float passo, float angulo, float incremento) {

  ellipse(0,-passo,10,10);

  translate(0,-passo);

  rotate(radians(angulo));

  salvarPasso();

  espiral(passo+incremento, angulo, incremento);

}

// Esta função salva um arquivo de imagem no formato png

void salvarPasso() {

  // Seleciona o arquivo para salvar a imagem

  String arquivo = selectOutput();

  // Salva o arquivo no formato png.

  save(arquivo+".png");

}

void setup() {

  size(300,300);

  background(255);

  translate(width/2, height/2);

  espiral(10,92,3);

}

Ao invés de variar o passo, varia-se o ângulo

 

void inspiral(float passo, float angulo, float incremento) {

  line(0,0,0,-passo);

  translate(0,-passo);

  rotate(radians(angulo));

  salvarPasso();

  inspiral(passo, angulo+incremento, incremento);

}

// Esta função salva um arquivo de imagem no formato png

void salvarPasso() {

  // Seleciona o arquivo para salvar a imagem

  String arquivo = selectOutput();

  // Salva o arquivo no formato png.

  save(arquivo+".png");

}

void setup() {

  size(300,300);

  background(255);

  translate(width/2, height/2);

  inspiral(20,10,10);

}

Adaptado do livro Learning Processing, by Daniel Shiffman, published by Morgan Kaufmann Publishers, Copyright 2008 Elsevier Inc.

Adaptado do livro Learning Processing, by Daniel Shiffman, published by Morgan Kaufmann Publishers, Copyright 2008 Elsevier Inc.

Adaptado do Appendix B of Processing:Creative Coding and Computational Art, Ira Greenberg, Friends of ED, 2007 

Capítulo 2 do Livro “Lógica de Programação – A Construção de Algoritmos e Estruturas de Dados” de Forbellone e Eberspächer. Páginas 17 a 21.

Tal ambiente, derivado da linguagem de programação Java, é uma linguagem de programação e ambiente para pessoas que desejam programar imagens, animações e interações. O Processing pode ser usado para o ensino dos fundamentos da programação de computadores usando um contexto visual. Seu público alvo é formado, principalmente, por artistas, estudantes e pesquisadores. A facilidade de instalação, uso e aprendizagem aliada à produtividade na geração de programas que utilizem interações complexas, faz com que o Processing seja ideal para a prototipação rápida de ideias e como caderno de esboços em software.

O aspecto didático do Processing não limita a sua aplicação apenas programas reais que exijam alto desempenho em processamento gráfico e ou que exijam portabilidade para diversas plataformas de software. Por ser baseado na linguagem Java, os programas em Processing geram applets e programas que apresentam excelente performance, principalmente se comparado com outras alternativas  como Flash e JavaScript. Além disso, tais programas tem suporte para as plataformas Windows, Linux e Mac OS inclusive para funcionalidades como programação gráfica em 3d, OpenGL, processamento de som e vídeo, geração de arquivos PDF, exibição de imagens SVG, e, qualquer biblioteca existente para a linguagem Java.

Sua instalação é bastante leve e simples e deve ser feita a partir do próprio portal da ferramenta.

rect(30,20,40,60);

line(30,20,70,80);