Saltar para o conteúdo
Giovani Drosda Lima
Matemática · Gráficos

Plano cartesiano 3D: a fórmula simples que desmistifica os gráficos 3D

·

É possível desenhar gráficos «tridimensionais» num plano bidimensional jogando com a perspetiva. Os programas que dão a impressão de profundidade fazem-no com truques que enganam a perceção humana, e há uma fórmula muito simples que chega para o conseguir:

x' = x / z
y' = y / z

O plano cartesiano a duas dimensões

Imagine um plano bidimensional, ou seja, com duas dimensões: largura e altura. É isso que significa bidimensional. Quanto às coordenadas, ponha o ponto (0, 0) no meio. No centro do plano, x e y valem zero.

Plano cartesiano desenhado à mão, com o eixo x na horizontal e o eixo y na vertical, ambos marcados de -3 a 3 e cruzados na origem.
O plano cartesiano a duas dimensões

É isso que representam o x e o y da fórmula: a posição de um ponto num plano cartesiano. (3, 3) seria um ponto no canto superior direito desta imagem, (-3, 0) um ponto à esquerda, a meia altura, e (0, -3) um ponto em baixo, ao centro.

O plano cartesiano a três dimensões

O z não passa de mais um eixo neste gráfico, o da profundidade, que vai da frente para o fundo. Com ele, o plano cartesiano passa a ter três dimensões. Aqui, quanto maior o z, mais ao fundo está o ponto.

Os três eixos x, y e z desenhados em perspetiva, com um observador em primeiro plano a olhar ao longo do eixo z.
O eixo z dá a profundidade, a partir do observador

Se quanto mais ao fundo maior é o z, conclui-se que:

  • quanto mais ao fundo, maior o denominador, e
  • quanto maior o denominador, menor o resultado.

Isto bate certo com o mundo real. Olhe por uma janela e imagine um ponto no canto superior direito. Agora imagine que esse ponto se mantém à mesma altura e à mesma distância horizontal de si, mas vai recuando.

Se imaginar a mesma ação num plano bidimensional, vai reparar que:

  • o ponto diminui de tamanho, caso lhe tenha dado um tamanho;
  • parece aproximar-se do centro, na vertical e na horizontal. A três dimensões é apenas uma ilusão de ótica, mas a duas dimensões é verdade.

Se ainda não estiver convencido, faça uma experiência. Ponha duas garrafas em cima de uma mesa, uma atrás da outra. Olhando de frente, a segunda está escondida pela primeira. Assim que se desloca para a direita, por exemplo, a garrafa de trás passa a aparecer mais à direita do que a da frente.

E de facto, se as garrafas estiverem em x = -100 (à esquerda, por isso negativo), a primeira em z = 10 e a segunda em z = 12,5, o x' de cada uma fica:

x' (primeira garrafa) = -100 / 10   = -10
x' (segunda garrafa)  = -100 / 12,5 = -8

Ou seja, no plano bidimensional a segunda garrafa fica mais à direita, porque -8 > -10.

Como as garrafas têm tamanho e não são apenas pontos, a segunda também parece um pouco mais pequena, pelo mesmo princípio. Isto vai fazer mais sentido daqui a pouco.

Um pormenor importante

No ecrã, a origem é o canto superior esquerdo. O eixo x cresce para a direita e o y cresce para baixo: é a convenção das janelas e do canvas do browser. Por isso é preciso mapear os valores para o tamanho do ecrã e inverter o eixo vertical.

Qual é a intuição?

Intuitivamente, faz sentido que as coisas mais distantes do observador se aproximem do centro (pense numa cordilheira enorme que parece caber no meio da sua visão, por muito que se estenda por quilómetros de um lado ao outro) e que essa aproximação dependa da distância.

Também quer dizer que as coisas mais distantes parecem mover-se mais devagar, porque qualquer deslocação é reduzida pela divisão pela distância ao observador, o / z da fórmula.

Porque é que a fórmula funciona?

A matemática por trás é simples e bonita. Usa apenas o facto de os lados de triângulos com os mesmos ângulos manterem sempre as mesmas proporções.

Demonstração manuscrita com triângulos semelhantes: o olho na origem, o ponto P à distância z e a sua projeção P' no ecrã à distância 1, de onde resulta y' = y/z.
Demonstração com triângulos semelhantes

Demonstração

Basta aplicar a fórmula num contexto 2D para obter uma sensação de profundidade. Abaixo, os oito vértices de um cubo, de (-1, -1, -1) a (1, 1, 1), são rodados em torno do eixo vertical, afastados do observador (somando 4 ao z) e projetados com x / z e y / z. Nada mais. Cada painel é o mesmo cubo com um ângulo diferente:

0°20°40°60°
O mesmo cubo, projetado só com x / z e y / z

Com o ponto (1, 1) a recuar de z = 1 até z = 5, a projeção cai sobre a origem ao longo de uma linha reta, exatamente como o ponto que imaginou à janela:

0x'y'z = 1z = 2z = 3z = 4z = 5
O ponto (1, 1) a recuar: x' = 1 / z, y' = 1 / z

O código da versão animada, em JavaScript puro desenhado num elemento <canvas>, está no GitHub: github.com/dlgiovani/simple-3D.

Cubo em arame verde sobre fundo preto, desenhado pela versão animada do programa.
Uma imagem da versão animada

Para saber mais

Há mais sobre isto no vídeo do canal Tsoding (em inglês).

Fora do Jornal, o meu trabalho são integrações e automações entre CRM, ERP e plataformas de gestão, para empresas em Guimarães, Braga e no resto do país. Veja os trabalhos anteriores ou fale comigo.