Como fazer uma flecha pousar em uma posição específica no espaço do mundo 3D

8

No meu jogo, quando clico com o mouse no terreno em algum lugar, gostaria que o jogador disparasse uma flecha nessa posição de maneira parabólica.

A seta tem uma posição, aceleração e velocidade, todos usando vetores 3D. Eu olhei para a Trajetória de um artigo de projétil na wikipedia, mas não sei como aplicá-lo na minha situação, pois explica a matemática 2D. Eu queria saber se existe uma solução para vetores 3D? Algum bom recurso talvez relacionado à situação 3D?

usuario
fonte
5
Não escreverei isso como resposta, pois espero que alguém possa dar uma resposta mais completa, mas você pode usar a solução 2D em 3D. A solução 2D se aplica ao plano vertical que percorre o ponto inicial e final, então você pega a solução 2D e a gira para corresponder a esse plano no espaço 3D.
Kylotan

Respostas:

12

Para expandir o comentário de Kylotan, você pode usar as fórmulas 2D em 3D. Supondo que Y esteja ativo:

calcule a posição do alvo no espaço X'Y'Z ', onde o eixo X' é paralelo à direção do vôo da seta, o eixo Y 'está para cima e Z' é perpendicular aos eixos X 'e Y'.

diagrama

Depois de calcular X 'e Y', você pode converter novamente em espaço XYZ real

Exemplo

Um arqueiro está em (1,0,1). Ele quer disparar uma flecha para (4,0,5). Tomamos X 'como o vetor unitário (0,6, 0, 0,8), uma vez que aponta diretamente da fonte para o ponto de destino. Em seguida, consideramos Z '(-0,8, 0, 0,6) porque é uma perpendicular, mas como a seta não se move no eixo Z', a ignoraremos. Seu problema agora é descobrir como disparar uma flecha de (0,0) a (0,5) no espaço X'Y '.

.. faça cálculos 2D aqui. Observe que você provavelmente desejará funções paramétricas de X 'e Y' em termos de t , a variável de tempo.

Uma maneira de abstrair a conversão entre as duas coordenadas é usar uma matriz de transformação.

let archer = Vector3d(1.0,0.0,1.0)
let target = Vector3d(4.0,0.0,5.0)
let travel = target - archer
let transform = Matrix4d.CreateTranslation(-archer) *
                Matrix4d.CreateRotationY(Math.Atan2(travel.Z,travel.X)) 
Vector3d.Transform(archer, transform) // transforms archer to (0,0,0)
Vector3d.Transform(target, transform) // transforms target to (5,0,0)

quando convertemos de X'Y'Z ' para XYZ , isso é simplesmente uma transformação linear reversa.

let inverse = Matrix4d.Invert(transform)
Vector3d.Transform(Vector3d.Zero, transform) // transforms (0,0,0) to (1,0,1)
Jimmy
fonte
Obrigado, consegui fazê-lo funcionar! Ainda tentando descobrir como fazê-lo funcionar com diferentes alturas agora ... :)
Nick
Nao! Erm. Isso pode ser resolvido analiticamente em qualquer dimensão sem recorrer a alterações de coordenadas ou trigonometria. Veja Como explicar a aceleração ao apontar projéteis? e playtechs.blogspot.com/2007/04/aiming-at-moving-target.html para exemplos.
Electro