Ponto V!

Home Arquitetura Matemática e Física Matrizes e Transformações – Parte 1
Vinícius Godoy de Mendonça
Matrizes e Transformações – Parte 1Imprimir
Escrito por Vinícius Godoy de Mendonça

Todos nós estudamos matrizes no segundo grau. Entretanto, a maioria de nós faz isso se perguntando qual é a sua utilidade, e o porquê de tantos cálculos. O que muitos não sabem é que são justamente as matrizes as grandes responsáveis por todos os gráficos 3D dos jogos atuais. Que tal ler esse artigo e descobrir o como?

Coordenadas cartesianas

Você deve estar lembrado que sempre que desenhamos coisas usamos para isso um sistema coordenado, chamado de coordenadas cartesianas. Ele foi inventado por Renatus Cartesius, mais conhecido no Brasil como René Descartes. Nesse sistema, cada ponto é representado em 2D por um par de valores, indicando sua linha e sua coluna:

Um carro, num sistema de coordenadas qualquer

Você pode imaginar que embaixo desse sistema de coordenadas hipotético, está uma folha de papel, ou mesmo o monitor do seu computador. Tanto faz. O importante é sabermos que, as coordenadas exatas dos pontos são apenas uma referência, uma convenção.

Por exemplo. Digamos que giraremos a folha de papel em 20o no sentido horário, e então iremos colocá-la por cima da folha anterior, e redesenhar o carro, exatamente no mesmo local, por cima de sua “sombra”. Obteríamos a seguinte imagem:

Mesmo carro, coordenadas inclinadas

Sem dúvida, não houve qualquer modificação no desenho do carro, ele está exatamente no mesmo local. Entretanto, no novo sistema de coordenadas, ao ajeitarmos a folha, esse carro pareceria ter girado 20o no sentido anti-horário, veja:

Ao ajustar a folha, o carro está inclinado

O que fizemos no final, ajeitar a folha, é um processo chamado de transformação de coordenadas. Simplesmente pegamos as coordenadas que estavam num sistema (o da folha girada) e as transformamos elas num outro sistema (o da folha normal).

E o que matrizes têm a ver com tudo isso? Tudo.

Representação matemática do sistema de coordenadas

Considere um sistema de coordenadas qualquer, ainda com duas dimensões, e que sobre ele utilizemos vários pontos pra traçar uma figura.

Uma figura num sistema coordenado qualquer

Sabemos que o ponto superior direito dessa figura deve ter uma coordenada positiva de grande valor, como (100,120) ou (10,12) e o seu valor exato não nos importa agora.

A figura por ter sido construída aí, segue uma regra: ela é proporcional a esse sistema. Ou seja, se a figura tem 5cm de largura e 6cm de altura, e a unidade desse sistema for o milímetro, então, o canto superior direito dessa figura será (50,60)mm.

Agora, imaginemos os eixos coordenados dessa figura como dois vetores, chamados vetores de base e, como seu tamanho, atribuiremos o valor um. Novamente, o tamanho os pontos da figura não importam, e sim o fato deles serem equivalentes de 1:1 com esse nosso eixo:

Uma figura num sistema coordenado qualquer

Vamos escrever cada um desses valores em uma tabelinha?

Ordenadas (x)

Abscissas (y)

X

1

0

Y

0

1

Note como os valores, destacados com cores, foram transportados para as colunas da tabelinha. Se retirarmos os títulos, acabaremos com uma matriz que representa esse nosso sistema de coordenadas.

Matriz do sistema de base

Se você lembrar-se das suas aulas do segundo grau, se lembrará que esta é a matriz identidade. Ela tem uma propriedade interessante: qualquer matriz multiplicada pela identidade, não altera seu valor. Ou seja, é como se essa matriz representasse o número um numa multiplicação. Como sabemos, qualquer coisa multiplicada por um não altera seu valor.

Procure se lembrar dessa informação. Ela será importante em breve.

Vetores e matrizes

Você deve se lembrar que vetores podem representar pontos. Não se lembra? Então confira rapidamente nosso artigo sobre vetores.

Por exemplo, o ponto do canto superior direito daquela figura que no exemplo calculamos ser (50,60), poderia ser representado pelo seguinte vetor:

Vetor [50,60]

O que muitos não sabem, é que esse vetor pode ser representado como uma matriz de uma linha, e duas colunas, como essa aqui: clip_image004

Ou mesmo como uma matriz de uma única coluna e duas linhas, como essa: [50,60] Como a notação de coluna é difícil ocupa muito espaço escrita, podemos usar a notação de linha, através da matriz transposta: [50 60]T.

Você deve estar se perguntando. E daí? Se você ainda não reparou, uma vez que um vetor é representado por uma matriz, isso também significa que ele pode ser multiplicado por uma matriz. E essa multiplicação permite-nos transformar um vetor que está num sistema de coordenadas qualquer, em um vetor em outro sistema.

Usar linhas ou colunas tem uma implicação importante: Matrizes linhas representam o sistema de coordenadas da mão esquerda. Nele, as funções de rotação funcionam no sentido horário, e as transformações ocorrerão na ordem em que são multiplicadas. Na matriz coluna, as rotações ocorrem em sentido anti-horário, e as transformações ocorrem em ordem inversa da multiplicação. Utilizaremos nessa série de artigos as matrizes colunas, pois são padrão em muitas APIs e livros de computação gráfica, por serem adotadas na OpenGL.

Já as matrizes linha são comumente usadas no DirectX, não é à toa que estão presentes em nossos artigos de XNA e shaders.

Multiplicação de matrizes

Antes de continuarmos, vamos lembrar como se dá a multiplicação de matrizes. Ao multiplicar duas matrizes A e B, calculamos cada elemento Cij (onde i é a linha e j a coluna) usando de um processo simples:

  • Na matriz A, pegamos os elementos da linha i, que queremos calcular;
  • Na matriz B, pegamos os elementos da coluna j, que queremos calcular;
  • Então, multiplicamos esses elementos entre si, e somamos os seus produtos. Note que para que essa multiplicação seja possível, o número de colunas de A, deve ser exatamente igual ao número de linhas de B.

Ainda perdido? Veja abaixo como calculamos o elemento c24:

Multiplicação de matrizes

Se você como eu sempre se perde nesses cálculos. Eis uma forma mais gráfica de representar: desenhe a matriz C, e sobre ela a matriz B e a sua esquerda a matriz A. Os elementos usados para calcular um valor em C estarão na mesma linha em A, e na mesma coluna em B, observe:

Multiplicação de matrizes (regra prática)

Agora que revisamos, vamos voltar ao tema.

Transformações lineares

Escala

Podemos usar matrizes para representar outros eixos coordenados, diferentes do eixo de base. Basta, para isso, imaginarmos como esse eixo seria.

Por exemplo, vamos supor que queiramos ampliar uma imagem em duas vezes. Isso significa que queremos que seu eixo de base seja duas vezes maior que nosso próprio eixo, certo?

Escala

Portanto, usando as proporções do segundo eixo como uma matriz, teríamos:

Matriz de escala

Com essa matriz, podemos transformar qualquer ponto do sistema de base, num ponto do sistema escalado. Para isso, a matriz de escala e multiplicar pelo vetor que queremos ampliar. Tomemos como exemplo o nosso vetor [50 60], citado anteriormente:

Cálculo de escala

Não surpreendentemente, os pontos dobraram de valor. Para ampliar uma figura inteira, multiplicaríamos o vetor que representa cada um de seus pontos. Se você está achando que é muito trabalho para pouco resultado, continue lendo o artigo.

Rotação

Alterar o tamanho não é a única coisa que podemos fazer com transformações lineares. O que aconteceria se no lugar da matriz Matriz de escala em 2x usássemos a matriz Matriz de escala e rotação ?

Veja um eixo sobre o outro:

Escala e rotação

Note que agora não só alteramos o tamanho da imagem, como também alteramos a inclinação dos eixos. Como conseqüência, a transformação final também será inclinada (nesse caso, em 26o).

Escala e rotação

Se lembrarmos da formula sobre como criar um vetor baseado num ângulo, poderemos facilmente chegar a uma matriz, que faz uma rotação qualquer. Se você não se lembra, criamos um vetor de tamanho t, baseado num ângulo α com a função:

Vector2D Vector2D::bySizeAndAngle(float size, float angle)
{
   return Vector2D(
      cos(angle) * size,
      sin(angle) * size);
}

Ou seja, equivalente à formula:

Vetor num ângulo alfa qualquer

Se na hora de montar nosso novo sistema coordenado esse for o vetor de um dos eixos, então, seu vetor perpendicular a ele, será o vetor do outro eixo. Há uma regra simples para achar um vetor perpendicular. Basta inverter a posição dos dois valores, e o sinal do de um deles. Por exemplo, se o vetor em questão é (x,y) seu perpendicular será (-y, x).

Dessa forma, como queremos alterar apenas o ângulo, teremos t = 1, e formamos seguinte sistema em azul, sobre nosso sistema base, em cinza:

Eixos rotacionados

E com isso, podemos deduzir a matriz de rotação genérica, que é:

Matriz de rotação no ângulo alfa

Repare bem que a primeira linha dessa matriz é exatamente a fórmula do método Vector2D::bySizeAndAngle. E note que a segunda, nada mais é que seu vetor perpendicular.

Assim, se tivermos um vetor (x,y) qualquer, sua rotação será definida por:

Matriz que representa um vetor rotacionado em alfa

A fórmula acima te causa arrepios? Dê uma olhada no método rotate da classe Vector2D. Reconhece essa fórmula?

Vector2D& Vector2D::rotate(float angle)
{
   float s = sin(angle);
   float c = cos(angle);

   float newX = x * c - y * s;
   float newY = x * s + y * c;

   x = newX;
   y = newY;

   return *this;
}

Transformações combinadas

Um detalhe interessante. Você pode ter notado que ambas as matrizes de transformação podem ser multiplicadas umas pelas outras. Porém, essa operação faria sentido? O que ocorreria se multiplicássemos uma matriz por outra?

A resposta é que obteríamos uma terceira matriz que realiza as duas operações ao mesmo tempo.

Se isso não parece muito interessante, vamos calcular um pouco. Suponha que você tenha uma figura formada por 2000 pontos. Se você aplicar individualmente a rotação e a escala, terá feito 4000 operações (2000 rotações e 2000 escalas). Porém, se você primeiro multiplicar as matrizes, fará ao final apenas 2001 operações: a primeira será a multiplicação da matriz de rotação R, pela matriz de escala E, obtendo a matriz composta C. E em seguida, 2000 multiplicações dos vetores dos pontos por C.

Ou seja, você pode ter dezenas de transformações, que elas impactarão muito pouco no tempo total de cálculo.

Um detalhe importante: Lembre-se que a multiplicação de matrizes não é comutativa. Portanto, a ordem que a multiplicação dessas matrizes ocorre afeta o resultado. Veremos exemplos disso no próximo artigo.

Concluindo

Nesse artigo, vimos que matrizes representam um papel importante na computação gráfica. Elas são usadas para transformar coordenadas de um sistema qualquer em outro. No artigo, vimos às transformações lineares, que são capazes de fazer rotação e escala em qualquer eixo.

Vimos também que matrizes graficamente podem representar um sistema de coordenadas, proporcional a outro sistema qualquer, chamado de sistema base. E, principalmente, vimos como entender essas matrizes de maneira gráfica.

No próximo artigo, abordaremos também as transformações afins (AffineTransforms), que acrescentam a operação de afastamento (translação).


Comentários (35)
  • Jonathan Araujo
    avatar

    Cara muito bom o artigo.

    Eu pessoalmente gosto muito de ler artigos matemáticos sobre a área, pois esses conceitos se mantém independente da engine e ou api utilizada.

    Fica como sugestão e pedido meu para próximos artigos, algo sobre Quaternions e geometria 3D, é muito dificil achar algo em portugues sobre (pelo menos eu não achei muitos).

  • Vinícius Godoy de Mendonça
    avatar

    Sim, a idéia é chegar lá. Usar matrizes para explicar um grafo de cena e, depois, partir talvez para orientação no espaço (ângulos de Euler, vetor e ângulo, etc...)

    Talvez até dê para entrar em geometria 3D, mas é um campo um pouco mais árido. Vou pensar certinho em como abordar esse assunto de maneira mais prática.

  • to pasma baby
    avatar

    aê ganhou!

    :side: :woohoo:

  • Marcos Vasconcelos
    avatar

    Muito bom artigo, é interessante saber como isso funciona para criar jogos de qualidade.

    E ai está um bom exemplo que mostra que vetores não servem apenas para movimento.

  • droidevr
    avatar

    Mais um belo artigo do pontov!

    Estou passando por todos os artigos. O material do site de vocês é muito bom.

    Ainda não apliquei o conteudo na prática, pois estou fazendo um jogo 2D e por enquanto consigo seguir, mas futuramente estarei aprofundando no seu artigo.

    O mercado de games, ainda mais com mobiles está crescendo no Brasil, vocês vão ser a referência para gamedev.

    Continuem assim.

  • Vinícius Godoy de Mendonça
    avatar

    Valeu Droide. O interessante é que essas transformações que citei nesse artigo e citarei no próximo podem ser aplicadas em jogos 2D.

    O Java2D, por exemplo, tem a classe AffineTransform, que nada mais é que uma representação das matrizes de transformação.

    E creio que nem precisa dizer que as matrizes dessa forma são a base para jogos 3D, não é mesmo?

  • Anônimo
    avatar

    Podias colocar uma representação matemática das coordenadas cartesianas de uma matriz 3*3?

  • Vinícius Godoy de Mendonça
    avatar

    Não entendi. No artigo há diversos exemplos. O que exatamente vc não entendeu?

    No 3x3, a única diferença é que teremos um terceiro eixo.

  • Anônimo
    avatar

    Já entendi.
    Muito obrigado e bom artigo.

  • Fernando
    avatar

    Muito bom o artigo! Parabéns!!
    Estou fazendo pesquisas para fazer meu TCC de Especialização em matemática!!
    Com esse artigo pude tirar algumas dúvidas, e conhecer um pouco mais!
    Parabéns!

  • Vinícius Godoy de Mendonça
    avatar

    Obrigado. Semana que vem sai a segunda parte do artigo.

  • andressa  - parabens
    avatar

    nao sou boa em matematica e vc conseguiu me deixar mais maluca a inda :S :angry: :X

  • Vinícius Godoy de Mendonça
    avatar

    E o pior é que essa matéria é a base de toda a computação gráfica moderna. É isso que deu origem aos jogos 3D e efeitos especiais de filmes. Certamente é mais interessante saber que matrizes tem alguma utilidade prática, do que a forma que as estudamos no segundo grau: sem ter a menor noção da sua utilidade. :)

  • Renato Reis
    avatar

    Excelente! Ótimo artigo. Quanto mais leio sobre matemática na computação, mais me apaixono pelas duas coisas.

    Matemática é linda, pura poesia. :lol:

  • Bernardo Biesseck  - Co
    avatar

    Olá Vinícius, ótimo texto!

    Só uma correção: no tópico Representação matemática do sistema de coordenadas, no qual você colocou a figura da vaquinha, você fala do canto superior esquerdo, mas apresenta as coordenadas do ponto no canto superior direito. Acredito que a correção ajudaria a evitar confusões.

    Abraço!

  • Vinícius Godoy de Mendonça
    avatar

    Ooops. Tem razão. Já está corrigido. Obrigado pelo aviso! :)

  • Eunice Carvalho  - Adorei
    avatar

    Faço programação e matemática, e gostei de seu artigo. Esclareceu minha mente em alguns pontos, que eu não sabia. :cheer:

  • Vinícius Godoy de Mendonça
    avatar

    Obrigado. Qualquer dúvida é só entrar em contato. :)

  • Roberto  - Duvida
    avatar

    Muito bom o post , parabéns .
    Mas estou com uma duvida , fiz num sistema de coordenadas 3d o calculo de rotaçao no eixo Z , porém quero poder rotacionar o eixo X e Y ao mesmo tempo e descobri que nao daria. Você sabe algum calculo que eu possa fazer para conseguir rotacionar todos os eixos em diferentes angulos ao mesmo tempo ?

  • Vinícius Godoy de Mendonça
    avatar

    Tem algumas alternativas:
    a) Montar uma matriz de rotação separada em x, y e z e multiplicá-las. Isso gera uma terceira matriz, que faz todas as operações ao mesmo tempo.

    b) Criar uma matriz de rotação em torno de um eixo arbitrário: http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis _and_angle Nesse caso, você passa um vetor unitário com o eixo arbitrário que quer girar e o angulo da rotação.

    c) Utilizar quarternions (infelizmente, não tenho artigo sobre eles no site).

  • Roberto
    avatar

    Vlw Vinicius !

  • Renato
    avatar

    Cara tambem tenho a mesma duvida mas nao entendi como posso fazer a alternativa A eu tenho que multiplicar como x * x y*y e z*z ?

  • ViniGodoy  - Matrizes
    avatar

    Vou demostrar com um exemplo, usando a biblioteca de matrizes que disponibilizo junto ao artigo de vetores:

    Matrix3 rotationX = createRotationX(toRadians(10));
    Matrix3 rotationY = createRotationY(toRadians(20));
    Matrix3 rotationZ = createRotationZ(toRadians(-5));

    Matrix3 finalRotation = rotationX * rotationY * rotationZ;

    Vector3D ponto(10,20,30);
    Vector3D pontoGiradoEmXyz = transform(ponto, finalRotation);


    Ou seja, multiplicar um vetor pela matriz finalRotation é o mesmo que aplicar as transformações rotationX, rotationY e rotationZ em sequência.

  • Renato
    avatar

    Muito Obrigado !

  • Patricia  - Opinião
    avatar

    Oi...gostei muito desse artigo.

    Gostaria de manter contato contigo.

    Sou professora no curso Técnico em jogos Digitais estamos formando a primeira turma de técnicos em jogos digitais (ETEC - Vila Madalena - Extensão).


    No aguardo,
    Patricia

  • natany  - duvida
    avatar

    me ajude a resolver, por favor: encontre a nova posição do ponto (4,2) apos uma rotação de 60 ° no sentido horario, em torno da origem. agradeço.

  • ViniGodoy
    avatar

    Oi Natany,

    Basta criar a matriz de rotação descrita nesse artigo e multiplica-la por esse vetor.

  • Taylon
    avatar

    Olá Vinícius, tenho uma dúvida: eu gostaria muito de trabalhar nessa área de modelagem computacional e computação gráfica (motores de gráficos e de física), porém não tenho convicção de que curso ingressar no ensino superior, seria eng. da computação? Pois, tenho que conhecer o hardware com qual trabalho também, não? :(
    Se você me puder passar dicas ou mesmo algum artigo, pode ser em inglês.

    Valeu. :)

  • Vinícius Godoy de Mendonça
    avatar

    Ciências da computação ou engenharia da computação. A engenharia te dá a vantagem de estudar mais física e cálculo, mas é bastante focada em firmwares.

    Na ciência você estudaria a computação gráfica e muito mais programação. Aprende toda a base necessária para construir um motor em software. E não é tão fraca em matemática como Análise de Sistemas ou Bacharelado em Sistemas de Informação.


    Não existe curso completo. Você terá que optar por um deles, e estudar bastante por conta depois. Entre esses dois, ainda acho a ciência mais vantajosa para seu caso, embora a engenharia não fique muito atrás.

  • Neto  - Porque multiplicação ?
    avatar

    Pelo que deu a entender a forma como se distribui os dados (numeros) na matriz é para que quando haja a multiplicação o resultado seja o esperado. Não seria mais simples se utilizassem a soma de matrizes ? Alem do mais a multiplicação de matrizes tem mais operações que a soma.
    Eu sei que o padrão do opengl é a multiplicação de matrizes, mas porque optaram pela multiplicação e não pela soma ?

  • Vinícius Godoy
    avatar

    Por que são operações completamente diferentes. A soma combina apenas valores num mesmo eixo (x com x, y com y, etc.). É a multiplicação que consegue fazer a relação de todos os eixos com todos. E é isso que é necessário para uma transformação de matrizes.

  • Darbi Muller  - Matriz de rotação
    avatar

    Como está Vinícius, como está? Gostaria de saber se você tem a demonstração da representação de um vetor x~=(x,y) para um sistema de coordenadas rotacionada de um ângulo teta, ou um artigo ou site que traz esta demonstração. Agradeço.

  • Anônimo
    avatar

    :confused: nossa mais q matrizes complicadaaaass

  • Gabriel  - Transformação de sistema de coordenadas isométrica
    avatar

    Muito boa a explicação, estou gastando pouco da algebra linear que estou aprendendo na faculdade pra tentar encontrar a transformação linear de vetores em um sistema de coordenadas cartesiano para um isométrico. Alguma dica?

  • Anônimo  - SHOW
    avatar

    Muito bom, boa didática...

    Parabéns e VALEUUUUU!!!!

Escrever um comentário
Your Contact Details:
Gravatar enabled
Comentário:
[b] [i] [u] [url] [quote] [code] [img]   
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch::(:shock:
:X:side::):P:unsure::woohoo::huh::whistle:;):S:!::?::idea::arrow:
Security
Por favor coloque o código anti-spam que você lê na imagem.
LAST_UPDATED2  

Busca

Linguagens

Twitter