Diagramas de fluxo

Pedro Cacique
phcacique
Published in
7 min readJan 15, 2022

--

Desenhando curvas fluidas

O ano de 2022 começou cheio de inspiração para mim. Eu participei nos primeiros dias do Genuary, que é um movimento no Twitter (principalmente) em que artistas do mundo inteiro seguem uma lista diária de temas pra criação de arte generativa.

Se você nunca ouviu falar nesses termos, art generativa é uma expressão artística em que o artista cria um conjunto de regras a serem seguidas. A execução destas regras gera uma saída criativa. Perceba que quanto mais parâmetros variáveis tivermos nessas regras, mais diferentes serão os resultados.

Veja alguns dos meus resultados nos primeiros dias:

Genuary 2022 — Pedro Cacique

Se quiser ver mais do meu trabalho com arte generativa, me siga no Twitter, pois sempre posto meus resultados por lá: https://twitter.com/phcacique

Ah! os tópicos são sempre um pouco vagos, o que permite a maior criatividade do artista, incluindo a sua própria interpretação do tema.

Um dos temas que eu mais gostei de trabalhar foi o do quarto dia: The next next Fidenza. Eu não conhecia o tema e resolvi pesquisar um pouco para descobrir do que se trata.

Acontece que é uma obra de arte muito interessante criada por Tyler Hobbs (https://tylerxhobbs.com/fidenza) e é baseada em diagramas de fluxo para construção de linhas curvas, como nesta obra a seguir.

Fidenza — Tyler Hobbs

O mais interessante é que esta é um das obras mais vendidas como NFT (Non Fungible Token) e o artista explica os passos básicos do algoritmo no seu site.

Uma vez que eu já tinha aprendido um pouco sobre o conceito, comecei a pensar no tópico do Genuary. Lembre-se que a interpretação do tema faz parte da criação do trabalho. Fiquei dividido entre tentar reproduzir o algoritmo acrescentando algo meu ou tentar criar algo diferente, mas tão incrível que fosse tão famoso quanto o original, sendo o próximo Fidenza.

Como eu nunca tinha utilizado mapas de fluxo para desenhar, resolvi ir pelo primeiro caminho, assim eu aprenderia mais uma técnica para o meu arsenal.

Neste artigo, quero te mostrar a ideia principal do algoritmo e mostrar alguns resultados interessantes.

Diagramas de Fluxo

Para este contexto, um diagrama de fluxo nada mais é do que uma tabela contendo valores que representam o ângulo que uma linha deve ter ao passar por uma determinada localização.

Veja bem, que este conceito pode ser utilizado de muitas outras formas. Como por exemplo em um mapa de temperatura, temos uma tabela que representa não o ângulo, mas a temperatura em uma posição geográfica.

Veja, na figura abaixo, como o widget de previsão do tempo utiliza este conceito, no iPhone.

Neste caso, para cada ponto cartesiano(x,y) do mapa temos um equivalente (i,j) em uma tabela, com o valor de temperatura naquele ponto. Ao plotar este valor no gráfico, é feito um mapeamento que nos diz qual cor corresponde aquele valor dentro de um determinado intervalo. Neste caso, quanto mais vermelho, mais quente e quanto mais verde, mais frio.

E viva o calor de verão em São Paulo!

Da mesma forma, imagine que uma tabela contenha valores no intervalo de 0 a 360º e que em vez de pintar um quadrado com uma cor, vamos desenhar uma seta apontando na direção desse ângulo.

Teríamos algo mais ou menos assim:

Mas o que determina o ângulo para cada célula? Bom, depende do contexto a ser apresentado. Por exemplo, poderíamos usar uma API de previsão do tempo e mostrar a direção do vento em um mapa.

Para este caso específico, eu fiz uma função simples que relaciona a posição X da célula com a largura total da tabela, retornando o valor do seno deste número. Ou seja:

α = sin(i / w)

Em que:
i = posição horizontal na tabela
w = número de colunas

Uma dica para termos resultados interessantes aqui é sempre variar a angulação das setas de acordo com a posição na tabela. Veja que se tivermos funções mais variadas, termos resultados diferentes para o mesmo algoritmo. Então tudo depende da função que gera o valor do ângulo.

Se eu varar o valor de acordo com a coordenada Y também, podemos ter algo assim:

Neste caso, nossa função é:

α = sin(i / w) + sin(j / h)

Em que:
i = posição horizontal na tabela
j = posição vertical na tabela
w = número de colunas
h = número de linhas

Outra possível variação na criação da tabela é determinar a quantidade de linhas e colunas para o espaço do nosso Canvas, o que vai fazer com que tenhamos maior ou menor variação dos ângulos em um pequeno espaço na tela.

Veja o resultado com 3x mais linhas e colunas:

Desenhando as linhas

Agora que sabemos como criar uma tabela com ângulos que preenchem o espaço, podemos pensar em como desenhar as linhas.

O conceito é bastante simples e muito utilizado em diversos algoritmos de desenho.

Para desenharmos uma reta, precisamos conhecer as coordenadas de dois pontos no gráfico. Com estes valores, podemos calcular o ângulo entre essa reta e o eixo X.

Outra opção é termos o tamanho desejado da reta e o ângulo que ela deve formar com o eixo X (o que está mais perto do que temos, não é mesmo?)

Veja, no gráfico abaixo, uma representação desse conceito. Queremos encontrar os valores do ponto P com base no ângulo α (que vai ser o da nossa tabela) e o tamanho do segmento de reta: R.

O que estamos fazendo aqui é uma transformação do sistemas de coordenadas polares para o sistema cartesiano. Para isso, vamos usar as relações trigonométricas que conhecemos.

Podemos observar um triângulo aqui, certo? Nele temos que:

dy = cateto oposto = coordenada y de P
dx = cateto adjacente = coordenada x de P
R = hipotenusa = distância do ponto P até a origem

Tomemos o valor do cosseno, por exemplo. Se você se lembra bem do seu tempo de vestibular, sabe que:

cos = cat. op / hip

Ou seja, o cosseno do ângulo α é igual ao cateto oposto divido pela hipotenusa do triângulo formado, ou seja:

cos(α) = dy / R

ou ainda:

dy = cos(a) * R

Aqui estamos considerando a distância de P para a origem do sistema cartesiano, mas se quisermos ter a distância do ponto P a outro ponto no espaço, podemos apenas somar ao valor encontrado a coordenada de tal ponto. Assim:

dy = y' + cos(a) * R

Em que:

y' = coordenada y do ponto de origem do segmento R

De forma análoga, podemos compara o seno do ângulo, sendo:

sin = cat. adj / hip
sin(α) = dx / R
dx = sin(α) * R
dx = x' + sin(α) * R

Sendo assim, temos duas equações que nos fornecem as coordenadas do ponto P com base no tamanho do segmento de reta desejado e o ângulo fornecido:

dx = x' + sin(α) * R
dy = y’ + cos(a) * R

Agora, tudo o que precisamos é escolher um ponto na tela, conferir na tabela qual deve ser o ângulo de desenho e na sequência estabelecer qual seria o próximo ponto com as equações que encontramos acima.

Agora temos um segmento de reta, para termos uma linha mais completa, repetimos o procedimento várias vezes, agora tomando o novo ponto como ponto de partida.

Se utilizarmos valores de R pequenos, teremos linhas mais suaves, mas precisaremos repetir esse procedimento mais vezes para uma linha mais comprida.

Veja uma linha que foi desenhada com base no nosso algoritmo.

Aqui, foi escolhido um ponto aleatório em um dos limites do canvas e desenhada uma linha com vários segmentos. Neste Faso, foram 100 segmentos de tamanho 40px.

Veja algumas variações desse método, desenhando mais ou menos linhas, com diferentes funções de determinação do ângulo:

Fidenza

O que torna o algoritmo Fidenza tão interessante é a variação das espessuras das linhas, o número de segmentos que compões cada uma delas, o tamanho da tabela com diagrama de fluxo e um componente extra: a detecção de colisão.

Você pode acrescentar um algoritmo que detecta se uma linha colide com outra para determinar se ela pode ou não existir, o que vai dar um aspecto mais ordenado à obra. Veja:

Neste caso, variei os tamanhos das linhas (a quantidade de segmentos), a espessura delas, suas cores e verifiquei se uma não colidia com a outra, chegando o mais próximo possível do algoritmo original de Fidenza.

Viu como foi interessante? Perceba que ainda podemos explorar bastante este algoritmo. Já imaginou como seria se usássemos a área das linhas para escrever palavras de um poema? Teríamos um fluxo dirigido de leitura. Ou ainda se deixássemos linhas compridas e finas e desenhássemos flores nas pontas?

O que você faria para incrementar este algoritmo e dar o seu toque pessoal nele? Se você resolver implementar o algoritmo na sua linguagem favorita, não se esqueça de me enviar o resultado, ok?

--

--

Pedro Cacique
phcacique

Coordinator at Apple Developer Academy | Mackenzie