Estou aprendendo a usar vetores normalizados em meus jogos.
Aprendi que, para conhecer o ângulo entre dois vetores, posso usar o produto escalar. Isso me dá um valor entre -1 e 1, em que
- 1 significa que os vetores são paralelos e estão na mesma direção (o ângulo é de 180 graus).
- -1 significa que eles são paralelos e estão voltados para direções opostas (ainda 180 graus).
0
significa que o ângulo entre eles é de 90 graus.
Quero saber como converter o produto escalar de dois vetores, em um ângulo real em graus. Por exemplo, se o produto escalar de dois vetores for 0.28
, qual é o ângulo correspondente entre 0 e 360 graus?
2d
mathematics
vector
geometry
user3150201
fonte
fonte
Respostas:
dot(A,B) = |A| * |B| * cos(angle)
que pode ser reorganizado para
angle = arccos(dot(A,B) / (|A|* |B|))
.Com esta fórmula, você pode encontrar o menor ângulo entre os dois vetores, que estará entre 0 e 180 graus. Se você precisar entre 0 e 360 graus, essa pergunta pode ajudá-lo.
A propósito, o ângulo entre dois vetores paralelos apontando na mesma direção deve ser 0 graus, não 180.
fonte
Vou expandir um pouco o comentário do TravisG e dar outra resposta, aproveitando o fato de sua pergunta ter a tag "2D".
Você pode obter o ângulo entre dois vetores usando o produto de ponto, mas não pode obter o ângulo assinado entre dois vetores usando-o. Dito de outra forma, se você deseja transformar um personagem ao longo do tempo em direção a um ponto, o produto escalar indica quanto girar, mas não em qual direção. Há outra fórmula simples, no entanto, que é muito útil quando combinada com o produto escalar. Você não apenas tem
dot(A,B) = |A| * |B| * cos(angle)
Você também pode ter outra fórmula (cujo nome eu inventei no politicamente correto):
pseudoCross(A,B) = |A| * |B| * sin(angle)
onde se A = (a, b), B = (x, y), então pseudoCross (A, B) é definido como o terceiro componente do produto cruzado (a, b, 0) x (x, y, 0 ) Em outras palavras:
a*x+b*y = |A| * |B| * cos(angle)
-b*x+a*y = |A| * |B| * sin(angle)
O ângulo total assinado é então
angle=atanfull(-b*x+a*y,a*x+b*y)
(as funções atanfull ou atan2 perdoam se você passar valores não normalizados). Se A e B são normalizados, isto é, se|A|=|B|=1
são simplesmente:a*x+b*y = cos(angle)
-b*x+a*y = sin(angle)
Para uma explicação mais profunda, observe que as equações acima podem ser expressas pela equação da matriz:
Mas a e b pode ser expresso como
a=cos(ang1)
,b=sin(ang1)
por algum valorang1
(nãoangle
). Portanto, a matriz à esquerda é uma matriz de rotação que gira o vetor (x, y) pela quantidade -ang1. Isso é equivalente a mudar para um quadro de referência onde o vetor unitário "A" é tratado como o vetor / eixo (1,0)! Então, apenas desenhando o círculo unitário / triângulo retângulo nesse quadro, você pode ver por que o vetor resultante desse produto é (cos (ângulo), sin (ângulo)).Se você escrever (a, b) e (x, y) na forma polar, e aplicar as fórmulas de diferença de ângulo
cos(l)*cos(m)+sin(l)*sin(m)=cos(l-m)
esin(l)*cos(m)-cos(l)*sin(m)=sin(l-m)
, você expressará novamente que os senos / cossenos são dados por este produto, pois (lm) = ângulo. Alternativamente, essas identidades podem ser usadas para ver por que o produto linear dado acima gira um vetor.Todas essas identidades significam que você raramente precisa de ângulos. Como os ângulos podem ser estranhos - radiano / graus, convenções para seno / cosseno inverso, o fato de que eles se repetem a cada 2 * pi - isso pode realmente ser mais útil e economizar um monte de lógica "se (ang <180)" etc.
fonte