Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

In my game when I click with the mouse on the terrain somewhere, I'd like the player to fire an arrow to that position in a parabolic fashion.

The arrow has a position, acceleration and velocity all using 3D vectors. I looked at the Trajectory of a projectile article on wikipedia, but I don't know how to apply it in my situation as it explains 2D mathematics. I was wondering if there's a solution for 3D vectors? Any good resources perhaps related to the 3D situation?

share|improve this question
5  
I won't write this as an answer as I hope someone can give a more thorough response, but you can use the 2D solution in 3D. The 2D solution applies to the vertical plane that runs through the start and end point, so you take the 2D solution and rotate it to match that plane in 3D space. –  Kylotan Aug 8 '12 at 23:16

1 Answer 1

up vote 11 down vote accepted

To expand on Kylotan's comment, You can use the 2D formulas in 3D. Assuming Y is up:

calculate the position of the target in X'Y'Z' space, where the X' axis is parallel to the arrow flight direction, Y' axis is up, and Z' is perpendicular to the X' and Y' axes.

diagram

Once you have X' and Y' calculated, you can convert back to real XYZ-space

Example

An archer is at (1,0,1). He wants to shoot an arrow to (4,0,5). We take X' to be the unit vector (0.6, 0, 0.8) since it points directly from the source to destination point. We then take Z' to be (-0.8, 0, 0.6) because it is a perpendicular, but since the arrow doesn't move in the Z' axis, we will ignore it. Your problem is now figuring out how to shoot an arrow from (0,0) to (0,5) in X'Y' space.

.. do 2D calculations here. Note that you'll probably want parametric functions of X' and Y' in terms of t, the time variable.

One way to abstract the conversion between the two coordinates is to use a transform matrix.

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)

when we convert back from X'Y'Z' to XYZ, this is simply a reverse linear transformation.

let inverse = Matrix4d.Invert(transform)
Vector3d.Transform(Vector3d.Zero, transform) // transforms (0,0,0) to (1,0,1)
share|improve this answer
3  
+1, Nice drawing! –  John McDonald Aug 9 '12 at 0:34
    
Thanks, I managed to make it work! Still figuring out how to make it work with different heights now... :) –  Nick Aug 10 '12 at 8:38
    
Nooooo! Erm. This can be solved analytically in any dimension without resorting to changing coordinates or trigonometry. See How to account for acceleration when aiming projectiles? and playtechs.blogspot.com/2007/04/aiming-at-moving-target.html for examples. –  Electro Dec 28 '13 at 10:08

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.