Imagens Vetoriais e Transformações

De Aulas

Links Relacionados: Matemática e Física para Jogos

Representação

O plano é um espaço bidimensional composto de dois vetores, x e y. Para representar elementos vetoriais no plano, é necessário primeiramente representar cada ponto (x, y) ligados por linhas.

1class Ponto2D {
2public:
3    float x;
4    float y;
5};

O espaço tridimensional, por sua vez, é composto por três vetores. Desta forma, para representar os elementos vetoriais neste espaço é necessário acrescentar o eixo z aos já conhecidos x e y. Dessa forma, cada ponto pode ser representado por (x, y, z).

1class Ponto3D {
2public:
3    float x;
4    float y;
5    float z;
6};

Desenhando um Triângulo em um espaço bidimensional

 1#include <SFML/Graphics.hpp>
 2#include <SFML/Audio.hpp>
 3#include <iostream>
 4
 5class Ponto
 6{
 7public:
 8    float x;
 9    float y;
10    Ponto (float _x, float _y) : x(_x), y(_y) {}
11};
12
13int main()
14{
15    sf::RenderWindow* app = new sf::RenderWindow(sf::VideoMode(800, 600, 32), "Triangulo 2D");
16
17    Ponto* triangulo[3];
18    triangulo[0] = new Ponto(50, 100);
19    triangulo[1] = new Ponto(100, 50);
20    triangulo[2] = new Ponto(150, 100);
21
22    while (app->IsOpened())
23    {
24        sf::Event* event = new sf::Event();
25        while (app->GetEvent(*event))
26        {
27            if (event->Type == sf::Event::Closed)
28            {
29                app->Close();
30            }
31        }
32        if (app->GetInput().IsKeyDown(sf::Key::Escape))
33        {
34            return EXIT_SUCCESS;
35        }
36
37        app->Clear(sf::Color(255, 255, 255));
38        for (int i = 0; i < 3; i++)
39        {
40            int j = i + 1;
41            if (j > 2) j = 0;
42            sf::Shape line = sf::Shape::Line(triangulo[i]->x, triangulo[i]->y,
43                                             triangulo[j]->x, triangulo[j]->y,
44                                             1, sf::Color(0, 0, 0));
45            app->Draw(line);
46        }
47        app->Display();
48    }
49    return EXIT_SUCCESS;
50}

Transformações Vetoriais

Para fazer transformações em elementos vetoriais, na computação gráfica, são utilizadas as operações com matrizes.

Translação

A translação é a operação que move determinado objeto de um local à outro no plano.

A operação da translação ocorre com a soma da matriz de translação com todos os pontos do objeto. A matriz de translação é a seguinte:

[ Tx   Ty ]

tal que:

Tx é a translação na horizontal e
Ty é a translação na vertical

Logo, a fórmula matemática da operação de translação fica da seguinte forma:

[ x   y ] + [ Tx   Ty ]

tal que:

x = x + Tx
y = y + Ty

Escala

A escala no plano é a operação que modifica o tamanho de um objeto no plano.

A operação da escala ocorre com a multiplicação da matriz de Escala com todos os pontos do objeto. A matriz de escala é a seguinte:

| Sx    0 |
|  0   Sy |

tal que:

Sx é a modificação da escala na horizontal e
Sy é a modificação da escala na vertical

Logo, a fórmula matemática da operação de translação fica da seguinte forma:

[ x   y ] * | Sx    0 |
            |  0   Sy |

tal que:

             |     Sx            0       |
             |      0           Sy       |

[x    y ]    [(x*Sx)+(y*0)  (x*0)+(y*Sy) ]

Resumindo:

x = (x * Sx) + (y *  0) = x * Sx
y = (x *  0) + (y * Sy) = y * Sy

O Problema do deslocamento

Porém, temos um problema. Ao aplicar a escala, estamos modificando também a posição do nosso elemento. Para contornar o problema, devemos definir um ponto que é visto como o ponto de origem deste elemento, ou também chamado de Pivô.

Dessa forma, antes de efetuar a operação de escala, devemos mover nossa imagem com o pivô para a origem (0, 0). Para essa mudança, basta escolher um ponto que será o pivô ou criar um ponto apenas para ser o pivô da imagem. Diminuir todos os pontos pelo x do pivô, efetuar a operação e somar novamente pelos pontos do pivô.

Observe o seguinte algoritmo de exemplo:

pivo.x = ponto[0].x
pivo.y = ponto[0].y

translacao(-pivo.x, -pivo.y)
escala(2.0, 2.0)
translacao(pivo.x, pivo.y)

Veja que no exemplo acima utilizamos a operação de translação e de escala já apresentadas.

Rotação

A rotação, no plano, é a operação que rotaciona determinado objeto no plano.

A operação de rotação ocorre com a multiplicação da matriz de Rotação com todos os pontos do objeto. A matriz de rotação é a seguinte:

| cos(ang)   sen(ang) |
|-sen(ang)   cos(ang) |

tal que:

ang é o ângulo, em radianos, que se quer rotacionar o objeto,
sen é a operação do seno sobre o ângulo e
cos é a operação do cosseno sobre o ângulo.

Logo, a fórmula matemática da operação de translação se dá pela multiplicação da matriz do ponto pela matriz de rotação:

           |         cos(ang)                      sen(ang)         |
           |        -sen(ang)                      cos(ang)         |

[ x   y ]  [(x*cos(ang))+(y*(-sen(ang)))  (x*sen(ang))+(y*cos(ang)) ]

tal que:

x' = (x * cos(ang)) + (y * -sen(ang))
y' = (x * sen(ang)) + (y *  cos(ang))

Observe que agora temos x' e y'. Isso por que em ambas as oeprações estamos utilizando o x e y originais.

Se modificarmos o x na primeira operação, na segunda ele já vai estar modificado, o que distorce o elemento. A solução é criar variáveis auxiliares para não alterar os valores originais até o término do processo.

Outra coisa importante é que, assim como na escala, devemos transladar nosso objeto para o ponto de origem do espaço, baseando-se em um pivô do elemento.

Distância Euclidiana

A distância Euclidiana é a distância entre dois pontos. No caso do espaço bidimensional (vetores x e y), podemos ter a distância euclidiana como a seguinte fórmula:

raiz( (x2 - x1)2 + (y2 - y1)2)

Funções Trigonométricas

Triângulo

Considere o Triângulo da figura ao lado. Para o ângulo α, chamamos o lado cujo comprimento é x de lado adjacente, e chamamos o lado cujo comprimento é y de lado oposto. O lado oposto ao ângulo direito, cujo comprimento satisfaz o teorema de pitágoras (h2 = x2 + y2, é chamado de hipotenusa. As seis funções trigonométricas são definidas pelo ângulo como as razões de comprimentos de lado.

Funções Trigonométricas
Nome da Função Definição
seno sen α = y / h
cosseno cos α = x / h
tangente tg α = y / h = sen α / cos α
cossecante csc α = h / y = 1 / sen α
secante sec α = h / x = 1 / cos α
cotangente cot α = x / y = 1 / tg α

As funções cossecante, secante e cotangente são raramente utilizadas na programação. Dessa forma, vamos estudar mais as funções de seno, cosseno e tangente.

O que torna as funções trigonométricas úteis é que para um dado ângulo α, as razões de comprimento dos lados de um triângulo retângulo contendo o ângulo α são sempre as mesmas. Assim, as funções seno, cosseno e tangente dependem apenas do ângulo α, e não do tamanho real do triângulo.

Em uma circunferência de raio r, um radiano é o ângulo α para o qual o arco circular subtendido por α tem um comprimento igual ao próprio r.
Valores de funções trigonométricas para ângulos comuns
radianos graus sen α cos α tg α
0 0 1 0
π/6 30º 1/2 raiz(3)/2 raiz(3)/3
π/4 45º raiz(2)/2 raiz(2)/2 1
π/3 60º raiz(3)/2 1/2 raiz(3)
π/2 90º 1 0 indefinido

Exercícios

1. Implemente as funções que calculam:

1.a. A distância euclidiana entre dois pontos
1.b. A conversão de graus para radianos

Com base na representação do ponto e no exemplo do triângulo apresentado nessa sessão, faça os seguintes exercícios:

2. Implemente a função de translação. No programa principal, cada vez que pressionar as teclas das setas:

2.a. Cima: translade 10 pixeis para cima
2.b. Baixo: translade 10 pixels para baixo
2.c. Direita: translade 10 pixels para a direita
2.d. Esquerda: translade 10 pixels para a esquerda

3. Implemente a função de escala. No programa principal, efetue as seguintes operações:

3.a. Tecla PgUp: Faça o triângulo aumentar em 10%
3.b. Tecla PgDn: Faça o triângulo diminuir em 10%

observe que há o problema do deslocamento. Evite isso deixando um ponto como pivô.

4. Implemente a função de rotação. No programa principal, efetue as seguintes operações:

4.a. Tecla d: rotacione 15 graus para a direita
4.b. Tecla e: rotacione 15 graus para a esquerda