Daniel Rangel

Vetores em duas dimensões

O que são vetores?

Uma reta orientada possui um sentido de percurso considerado positivo e indicado por uma seta.

Um segmento orientado é determinado por um par ordenado de dois pontos no espaço, onde o primeiro é a origem e o segundo a extremidade do segmento. Por exemplo, um segmento que vai do ponto A até o ponto B é denominado de AB. É desenhado conforme a Figura 1.

segmento_orientado_modern

Figura 1 - segmento de reta orientado AB

Um segmento de reta CD possui a mesma direção de AB se as retas suporte que contêm os segmentos são paralelas ou coincidem.

Somente quando dois segmentos de reta possuem a mesma direção é que se pode comparar os sentidos dos segmentos.

Dois segmentos de reta são equipotentes quando possuem a mesma direção, sentido e comprimento. É representado geometricamente por AB~CD.

segmentos_equipotentes_modern

Figura 2 - segmentos de reta equipotentes

Um vetor é o conjunto de todos os segmentos de reta equipotentes.

Quando observamos a natureza, podemos quantificar suas grandezas com números, como por exemplo, a massa dos corpos, a temperatura, o comprimento e o tempo. Não há necessidade de outra informação além do dado numérico para se entender o seu significado. Esse tipo de grandeza é chamada de escalar. No entanto, algumas grandezas físicas, como a velocidade e força, necessitam da representação da direção e sentido para que se compreenda seus efeitos e interações com outras grandezas.

Espaço Vetorial

Seja V um conjunto não vazio munido das operações de adição "+" e multiplicação por escalar "·" fechadas em V. Ou seja:

Adição

μ,νV,μ+νV

Multiplicação por escalar

α,μV,αμV

Seguem-se as seguintes propriedades em relação à adição e multiplicação:

Axiomas da adição

Associatividade

(μ+ν)+ω=μ+(ν+ω)μ,ν,ωV

Comutatividade

μ+ν=ν+μμ,νV

Elemento neutro (Identidade)

0V,μVtal queμ+0=0+μ=μ

Elemento oposto

μV,(μ)Vtal queμ+(μ)=(μ)+μ=0

Axiomas da multiplicação

Para todo μ,νV e α,β temos que:

Associatividade

(αβ)μ=α(βμ)

Distributividade em relação à adição

(α+β)μ=αμ+βμα(μ+ν)=αμ+αν

Elemento neutro (Identidade)

1μ=μ

Assim, denotamos o espaço vetorial (V,+,·) ou simplesmente V quando estiverem claras suas operações.

Generalizações dos espaços vetoriais

Da definição acima, podemos obter espaços vetoriais diversos como 2 ou 3 ou do conjunto das matrizes com m linhas e n colunas, M(m,n). Assim, dependendo do espaço vetorial considerado, seus vetores serão elementos do conjunto correspondente e obedecerão os axiomas relativos à adição e multiplicação já descritos.

O espaço vetorial 2

Por exemplo, o conjunto V2={(x,y)x,y} é um espaço vetorial com as operações acima descritas da seguinte forma:

Adição de vetores em 2

(x1,y1)+(x2,y2)=(x1+x2,y1+y2)

Multiplicação por escalar

α(x,y)=(αx,αy)

O espaço vetorial V é definido como um par ordenado de números reais. A magnitude dos vetores em 2 pode ser calculada medindo-se a distância entre o ponto de origem e a extremidade do vetor da seguinte maneira:

sev=(vx,vy)2,então,v=vx2+vy2

sev=(15,8)temos:v=152+82v=17

norma

Figura 3 - Magnitude do vetor (15,8)

Vamos criar uma classe em Python que represente nossa definição matemática do espaço vetorial euclidiano em duas dimensões.

import numpy as np  # Importa a biblioteca numérica

# Cria a classe Vetor que é um vetor de duas dimensões
class Vetor(object):

    # Define os componentes do vetor como (x,y) ao inicializar uma instância
    def __init__(self, x, y):
        try:
            self.x = float(x)
            self.y = float(y)
        except ValueError:
            raise ValueError('x e y devem ser números reais')

    # Implementa a multiplicação do vetor por um escalar Vetor * n
    def __mul__(self, scalar):
        """Multiplica um vetor por um escalar elemento por elemento"""
        # Tenta converter scalar para um número do tipo float e gera um erro caso não seja possível
        try:
            scalar = float(scalar)
        except ValueError:
            raise ValueError(f'O argumento={scalar} deve ser um número real')
        # Retorna um vetor com o produto da operação
        return Vetor(scalar * self.x, scalar * self.y)

    # Método caso a multiplicação ocorra à direita n * Vetor
    def __rmul__(self, scalar):
        return self * scalar

    # Calcula o produto interno entre dois vetores
    def dot(self, other):
        """Calcula o produto interno de um vetor pelo outro."""
        if type(other) != Vetor:
            raise ValueError(f'O argumento={other} deve ser um Vetor')
        return self.x * other.x + self.y * other.y

    # Calcula o produto vetorial ou cruzado
    def cross(self, other):
        """Calcula o produto vetorial (cross product) de um vetor pelo outro."""
        if type(other) != Vetor:
            raise ValueError(f'O argumento={other} deve ser um Vetor')
        return self.x * other.y - self.y * other.x

    # Adiciona dois vetores
    def __add__(self, other):
        """Adiciona vetor v e w de mesma dimensão (cardinalidade)"""
        return Vetor(self.x + other.x, self.y + other.y)

    # Subtrai dois vetores, adicionando o primeiro com o oposto do segundo
    def __sub__(self, other):
        """Calcula a subtração de um Vetor pelo outro como a soma do primeiro com o inverso do segundo"""
        other = -1 * other
        return self + other

    @property
    def magnitude(self):
        """Calcula a magnitude do vetor em R^2 como a distância entre o ponto de origem e da extremidade do Vetor"""
        return np.sqrt(self.x**2 + self.y**2)

    def __eq__(self, other):
        if type(other) != Vetor:
            raise ValueError(f'O argumento={other} deve ser um Vetor')
        return self.x == other.x and self.y == other.y

    def __neq__(self, other):
        return not self.__eq__(other)

    def __repr__(self):
        return f'Vetor({self.x}, {self.y})'

Abaixo, vamos criar alguns vetores e escalares e, após isso, vamos testar os axiomas aditivos e multiplicativos que descrevemos acima:

import unittest

# Vamos recriar as variáveis para o teste
a = 2.0
b = 3.0

u = Vetor(2, 2)
u2 = Vetor(2, 2)
v = Vetor(3, 0)
w = Vetor(5, 6)
nulo = Vetor(0, 0)

class TestMetodosClasse(unittest.TestCase):
    def testa_igualdade(self):
        self.assertEqual(u, u2)

    def testa_desigualdade(self):
        self.assertNotEqual(u, w)

    def testa_multiplicação(self):
        self.assertEqual(u * 2, 2 * u)

    def testa_magnitude(self):
        self.assertEqual(u.magnitude, np.sqrt(u.x**2 + u.y**2))

    def testa_dot(self):
        self.assertAlmostEqual(u.dot(v) / (u.magnitude * v.magnitude), np.cos(np.pi / 4))

class TestAxiomasAdição(unittest.TestCase):
    def testa_associatividade(self):
        self.assertEqual((u + v) + w, (v + w) + u)

    def testa_comutatividade(self):
        self.assertEqual(u + v, v + u)

    def testa_identidade(self):
        self.assertEqual(u + nulo, u)

    def testa_oposto(self):
        self.assertEqual(u + (u * -1), nulo)

class TestAxiomasMultiplicação(unittest.TestCase):
    def testa_associatividade(self):
        self.assertEqual((a * b) * u, a * (b * u))

    def testa_distributividade_vetorial(self):
        self.assertEqual((a + b) * u, (a * u) + (b * u))

    def testa_distributividade_escalar(self):
        self.assertEqual(a * (u + v), a * u + a * v)

    def testa_identidade(self):
        self.assertEqual(1 * u, u)

unittest.main(argv=[''], exit=False)

Representando graficamente os vetores em 2

Vamos representar graficamente nosso vetor de duas dimensões e posicioná-lo na origem do plano cartesiano. Para isso, criaremos um vetor u que representa duas unidades no eixo x e três unidades no eixo y.

u=(2,3)

Lembrando que u é um representante dos vetores (2,3). Escolhemos de forma arbitrária o vetor nulo O como origem para plotagem de u. Perceba como o vetor representa um 'deslocamento' de duas unidades no eixo x e 3 unidades no eixo y.

Para esses vetores unitários (0,1) e (1,0) dá-se o nome de versor. Encontra-se o vetor unitário normalizado de u como produto da razão de u pela sua magnitude:

r=uu

As componentes unitárias do resultado da operação possuem mesmo sentido e direção que o vetor u, mas magnitude um. As componentes no plano coordenado cartesiano são grafadas como i^ e j^ no eixo x e y, respectivamente. Algebricamente, o vetor u pode ser representado como a soma dos versores.

# Importa a biblioteca de visualização do Python
import matplotlib.pyplot as plt

# Cria nosso vetor
u = Vetor(2, 3)

# Cria o vetor nulo
O = Vetor(0, 0)

# Cria a figura onde serão grafados os vetores
fig, ax = plt.subplots()

# Define o tamanho da nossa tela de plotagem
ax.set_xlim(-1, 3)
ax.set_ylim(-1, 4)

# Cria a figura do nosso vetor com origem em O
ax.quiver(O.x, O.y, u.x, u.y, angles='xy', scale_units='xy', headaxislength=5, scale=1, color='g')

# Mostra o gráfico na tela
plt.show()

Se multiplicarmos u por 2, dobraremos a sua magnitude (comprimento) mantendo sua direção e sentido. Multiplicar por -1 inverte o sentido do vetor (Figura 6).

fig, ax = plt.subplots()
ax.set_xlim(-1, 5)
ax.set_ylim(-5, 10)

# Aumenta o nosso vetor u em 2 vezes
v = 2 * u

# Inverte o vetor u
w = -1 * u

# Cria a figura do u com origem em O
ax.quiver(O.x, O.y, u.x, u.y, angles='xy', scale_units='xy', headaxislength=5, scale=1, color='g')
# Cria a figura do segundo u com origem no primeiro u
ax.quiver(u.x, u.y, u.x, u.y, angles='xy', scale_units='xy', headaxislength=5, scale=1, color='g')
# Cria a figura do vetor v
ax.quiver(O.x, O.y + 1, v.x, v.y, angles='xy', scale_units='xy', headaxislength=5, scale=1, color='r')
# Cria o vetor w
ax.quiver(u.x, u.y - 1, w.x, w.y, angles='xy', scale_units='xy', headaxislength=5, scale=1, color='y')
plt.show()

Iremos agora somar dois vetores e observar sua representação no espaço cartesiano.

v = Vetor(0, 4)
# Soma v com o vetor u
r = v + u

fig, ax = plt.subplots()
ax.set_xlim(-2, 5)
ax.set_ylim(-2, 10)

# Vetor u
ax.quiver(O.x, O.y, u.x, u.y, angles='xy', scale_units='xy', headaxislength=5, scale=1, color='g')

# Vetor v
ax.quiver(O.x, O.y, v.x, v.y, angles='xy', scale_units='xy', headaxislength=5, scale=1, color='b')

# Vetor resultado
ax.quiver(O.x, O.y, r.x, r.y, angles='xy', scale_units='xy', headaxislength=5, scale=1, color='r')

plt.show()

Podemos representar u com sua origem na extremidade de v. Agora é possível ver r como resultado de r=u+v. Assim, r se inicia na origem de u e termina na extremidade de v.

fig, ax = plt.subplots()
ax.set_xlim(-1, 5)
ax.set_ylim(-1, 10)

# Vetor u
ax.quiver(v.x, v.y, u.x, u.y, angles='xy', scale_units='xy', headaxislength=5, scale=1, color='g')

# Vetor v
ax.quiver(O.x, O.y, v.x, v.y, angles='xy', scale_units='xy', headaxislength=5, scale=1, color='b')

# Vetor resultado
ax.quiver(O.x, O.y, r.x, r.y, angles='xy', scale_units='xy', headaxislength=5, scale=1, color='r')

plt.show()

É possível representar a diferença entre dois vetores como a soma de um vetor com o oposto do segundo.

vu=v+(u)
fig, ax = plt.subplots()
ax.set_xlim(-5, 5)
ax.set_ylim(-5, 10)

w = u - v

# Vetor u
ax.quiver(O.x, O.y, u.x, u.y, angles='xy', scale_units='xy', headaxislength=5, scale=1, color='g')

# Vetor v
ax.quiver(O.x, O.y, v.x, v.y, angles='xy', scale_units='xy', headaxislength=5, scale=1, color='b')
ax.quiver(O.x, O.y, -v.x, -v.y, angles='xy', scale_units='xy', headaxislength=5, scale=1, color='black')

# Vetor resultado
ax.quiver(O.x, O.y, w.x, w.y, angles='xy', scale_units='xy', headaxislength=5, scale=1, color='r')

plt.show()

No notebook com o código do texto, é possível modificar os valores e explorar as representações geométricas dos vetores no plano. Clique aqui!