Mudanças entre as edições de "Imagens Vetoriais e Transformações"

De Aulas
 
(5 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 1: Linha 1:
 +
  
  
Linha 165: Linha 166:
 
tal que:
 
tal que:
  
* x = x + Tx
+
* x = x + T<sub>x</sub>
* y = y + Ty
+
* y = y + T<sub>y</sub>
  
 
== Escala ==
 
== Escala ==
Linha 174: Linha 175:
 
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:
 
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:
  
 +
<div style="text-align: center;">
 
<math>\begin{bmatrix} S_x & 0 \\ 0 & S_y \end{bmatrix}</math>
 
<math>\begin{bmatrix} S_x & 0 \\ 0 & S_y \end{bmatrix}</math>
 +
<br>
 +
<code style="font-size: 70%;">\begin{bmatrix} S_x & 0 \\ 0 & S_y \end{bmatrix}</code>
 +
</div>
  
 
tal que:
 
tal que:
  
* <math>S_x \text{ é a modificação da escala na horizontal, e}</math>
+
* S<sub>x</sub> é a modificação da escala na horizontal, e
* <math>S_y \text{ é a modificação da escala na vertical.}</math>
+
* S<sub>y</sub> é a modificação da escala na vertical.
  
  
 
Logo, a fórmula matemática da operação de translação fica da seguinte forma:
 
Logo, a fórmula matemática da operação de translação fica da seguinte forma:
  
 +
<div style="text-align: center;">
 
<math>\begin{bmatrix} x & y \end{bmatrix} \times \begin{bmatrix} S_x & 0 \\ 0 & S_y \end{bmatrix}</math>
 
<math>\begin{bmatrix} x & y \end{bmatrix} \times \begin{bmatrix} S_x & 0 \\ 0 & S_y \end{bmatrix}</math>
 +
<br>
 +
<code style="font-size: 70%;">\begin{bmatrix} x & y \end{bmatrix} \times \begin{bmatrix} S_x & 0 \\ 0 & S_y \end{bmatrix}</code>
 +
</div>
  
 
tal que:
 
tal que:
  
 +
<div style="text-align: center;">
 
<math>
 
<math>
 
\begin{bmatrix} x & y \end{bmatrix} \times \begin{bmatrix} S_x & 0 \\ 0 & S_y \end{bmatrix} = \begin{bmatrix} (x \times S_x) + (y \times 0) & (x \times 0) + (y \times S_y) \end{bmatrix}
 
\begin{bmatrix} x & y \end{bmatrix} \times \begin{bmatrix} S_x & 0 \\ 0 & S_y \end{bmatrix} = \begin{bmatrix} (x \times S_x) + (y \times 0) & (x \times 0) + (y \times S_y) \end{bmatrix}
 
</math>
 
</math>
 +
<br>
 +
<code style="font-size: 70%;">
 +
\begin{bmatrix} x & y \end{bmatrix}
 +
\times \begin{bmatrix} S_x & 0 \\ 0 & S_y \end{bmatrix} =
 +
\begin{bmatrix} (x \times S_x) + (y \times 0) & (x \times 0) + (y \times S_y) \end{bmatrix}
 +
</code>
 +
</div>
  
 
Resumindo:
 
Resumindo:
  
* <math>x' = (x \times S_x) + (y \times 0) = x \times S_x</math>
+
<div style="text-align: center;">
* <math>y' = (x \times 0) + (y \times S_y) = y \times S_y</math>
+
<math>x' = (x \times S_x) + (y \times 0) = x \times S_x</math>
 +
<br>
 +
<code style="font-size: 70%;">x' = (x \times S_x) + (y \times 0) = x \times S_x</code>
 +
</div>
 +
 
 +
<div style="text-align: center;">
 +
<math>y' = (x \times 0) + (y \times S_y) = y \times S_y</math>
 +
<br>
 +
<code style="font-size: 70%;">y' = (x \times 0) + (y \times S_y) = y \times S_y</code>
 +
</div>
 +
 
  
 
=== O Problema do deslocamento ===
 
=== O Problema do deslocamento ===
Linha 222: Linha 249:
 
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:
 
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:
  
 +
<div style="text-align: center;">
 
<math>
 
<math>
\begin{bmatrix} \cos(\theta) & \sin(\theta) \\ -\sin(\theta) & \cos(\theta) \end{bmatrix}
+
\begin{bmatrix} \cos(ang) & \sin(ang) \\ -\sin(ang) & \cos(ang) \end{bmatrix}
 
</math>
 
</math>
 +
<br>
 +
<code style="font-size: 70%;">\begin{bmatrix} \cos(\theta) & \sin(\theta) \\ -\sin(\theta) & \cos(\theta) \end{bmatrix}</code>
 +
</div>
  
 
tal que:
 
tal que:
  
* <math>\text{ang é o ângulo, em radianos, que se quer rotacionar o objeto,}</math>
+
* é o ângulo, em radianos, que se quer rotacionar o objeto,
* <math>\sin \text{ é a operação do seno sobre o ângulo, e }</math>
+
* sin é a operação do seno sobre o ângulo, e
* <math>\cos \text{ é a operação do cosseno sobre o ângulo.}</math>
+
* 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:
 
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:
  
 +
<div style="text-align: center;">
 
<math>
 
<math>
 
\begin{bmatrix} x & y \end{bmatrix}
 
\begin{bmatrix} x & y \end{bmatrix}
Linha 245: Linha 277:
 
\end{bmatrix}
 
\end{bmatrix}
 
</math>
 
</math>
 +
<br>
 +
<code style="font-size: 70%;">
 +
\begin{bmatrix} x & y \end{bmatrix}
 +
\begin{bmatrix}
 +
\cos(\text{ang}) & \sin(\text{ang}) \\
 +
-\sin(\text{ang}) & \cos(\text{ang})
 +
\end{bmatrix}
 +
=
 +
\begin{bmatrix}
 +
(x \times \cos(\text{ang})) + (y \times -\sin(\text{ang})) & (x \times \sin(\text{ang})) + (y \times \cos(\text{ang}))
 +
\end{bmatrix}
 +
</code>
 +
</div>
  
 +
tal que:
  
tal que:
+
<div style="text-align: center;">
 +
<math>x' = (x \times \cos(\text{ang})) + (y \times -\sin(\text{ang}))</math>
 +
<br>
 +
<code style="font-size: 70%;">
 +
x' = (x \times \cos(\text{ang})) + (y \times -\sin(\text{ang}))</math>
 +
</code>
 +
</div>
  
* <math>x' = (x \times \cos(\text{ang})) + (y \times -\sin(\text{ang}))</math>
+
<div style="text-align: center;">
* <math>y' = (x \times \sin(\text{ang})) + (y \times \cos(\text{ang}))</math>
+
<math>y' = (x \times \sin(\text{ang})) + (y \times \cos(\text{ang}))</math>
 +
<br>
 +
<code style="font-size: 70%;">
 +
y' = (x \times \sin(\text{ang})) + (y \times \cos(\text{ang}))</math>
 +
</code>
 +
</div>
  
Observe que agora temos x' e y'. Isso por que em ambas as oeprações estamos utilizando o x e y originais.
+
Observe que agora temos x' e y'. Isso por que em ambas as operaçõ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.
 
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.
Linha 262: Linha 319:
 
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:
 
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:
  
 +
<div style="text-align: center;">
 
<math>
 
<math>
 
\sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2}
 
\sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2}
 
</math>
 
</math>
 +
<br>
 +
<code style="font-size: 70%;">
 +
\sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2}
 +
</code>
 +
</div>
  
 
= Funções Trigonométricas =
 
= Funções Trigonométricas =

Edição atual tal como às 13h19min de 31 de março de 2025


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.

Código em C++

class Point2D {
public:
    float x;
    float y;
};

Código em Python

class Point2D:
    def __init__(self, x: float, y: float):
        self.x: float = x
        self.y: float = y

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).

Código em C++

class Ponto3D {
public:
    float x;
    float y;
    float z;
};

Código em Python

class Point3D:
    def __init__(self, x: float, y: float, z: float):
        self.x: float = x
        self.y: float = y
        self.z: float = z

Desenhando um Triângulo em um espaço bidimensional

Código em C++

#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <iostream>

class Ponto
{
public:
    float x;
    float y;
    Ponto (float _x, float _y) : x(_x), y(_y) {}
};

int main()
{
    sf::RenderWindow* app = new sf::RenderWindow(sf::VideoMode(800, 600, 32), "Triangulo 2D");

    Ponto* triangulo[3];
    triangulo[0] = new Ponto(50, 100);
    triangulo[1] = new Ponto(100, 50);
    triangulo[2] = new Ponto(150, 100);

    while (app->IsOpened())
    {
        sf::Event* event = new sf::Event();
        while (app->GetEvent(*event))
        {
            if (event->Type == sf::Event::Closed)
            {
                app->Close();
            }
        }
        if (app->GetInput().IsKeyDown(sf::Key::Escape))
        {
            return EXIT_SUCCESS;
        }

        app->Clear(sf::Color(255, 255, 255));
        for (int i = 0; i < 3; i++)
        {
            int j = i + 1;
            if (j > 2) j = 0;
            sf::Shape line = sf::Shape::Line(triangulo[i]->x, triangulo[i]->y,
                                             triangulo[j]->x, triangulo[j]->y,
                                             1, sf::Color(0, 0, 0));
            app->Draw(line);
        }
        app->Display();
    }
    return EXIT_SUCCESS;
}

Código em Python

import sys
import pygame

WIDTH: int = 800
HEIGHT: int = 600
Color_screen: pygame.Color = (255, 255, 255)
Color_line: pygame.Color = (0, 0, 0)

class Point:
    def __init__(self, x: float, y: float):
        self.x: float = x
        self.y: float = y

def main():
    global CONICAL
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    triangle : list[Point] = [
            Point(50, 100),
            Point(100, 50),
            Point(150, 100)
        ]
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit(0)
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    sys.exit(0)
        
        screen.fill(Color_screen)
        pygame.draw.line(screen, Color_line, (triangle[0].x, triangle[0].y), (triangle[1].x, triangle[1].y))
        pygame.draw.line(screen, Color_line, (triangle[1].x, triangle[1].y), (triangle[2].x, triangle[2].y))
        pygame.draw.line(screen, Color_line, (triangle[2].x, triangle[2].y), (triangle[0].x, triangle[0].y))
        pygame.display.flip()

if __name__ == "__main__":
    main()

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:


\begin{bmatrix} T_x & T_y \end{bmatrix}

tal que:

x = x + Translação na horizontal Tx

y = y + Translação na vertical Ty

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


\begin{bmatrix} x & y \end{bmatrix} + \begin{bmatrix} T_x & T_y \end{bmatrix}

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:


\begin{bmatrix} S_x & 0 \\ 0 & S_y \end{bmatrix}

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:


\begin{bmatrix} x & y \end{bmatrix} \times \begin{bmatrix} S_x & 0 \\ 0 & S_y \end{bmatrix}

tal que:


\begin{bmatrix} x & y \end{bmatrix} \times \begin{bmatrix} S_x & 0 \\ 0 & S_y \end{bmatrix} = \begin{bmatrix} (x \times S_x) + (y \times 0) & (x \times 0) + (y \times S_y) \end{bmatrix}

Resumindo:


x' = (x \times S_x) + (y \times 0) = x \times S_x


y' = (x \times 0) + (y \times S_y) = y \times S_y


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:


\begin{bmatrix} \cos(\theta) & \sin(\theta) \\ -\sin(\theta) & \cos(\theta) \end{bmatrix}

tal que:

  • é o ângulo, em radianos, que se quer rotacionar o objeto,
  • sin é 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:


\begin{bmatrix} x & y \end{bmatrix} \begin{bmatrix} \cos(\text{ang}) & \sin(\text{ang}) \\ -\sin(\text{ang}) & \cos(\text{ang}) \end{bmatrix} = \begin{bmatrix} (x \times \cos(\text{ang})) + (y \times -\sin(\text{ang})) & (x \times \sin(\text{ang})) + (y \times \cos(\text{ang})) \end{bmatrix}

tal que:


x' = (x \times \cos(\text{ang})) + (y \times -\sin(\text{ang}))</math>


y' = (x \times \sin(\text{ang})) + (y \times \cos(\text{ang}))</math>

Observe que agora temos x' e y'. Isso por que em ambas as operaçõ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:


\sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^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