# Calculating Projectile Movement

I'm having some trouble putting together a method that will constantly move a "bullet" in the same direction accurately. Here is what I have so far

public Vector3f moveFromPosition(Vector3f location, float pitch, float yaw, Game game) {
Vector3f loc = location;
return loc;
}


This method is being called in the render method, so every frame it will move the bullet 1 space depending on the pitch, yaw, and location the bullet was fired from. The pitch and yaw values stay the same each frame, and the vector3f "location" stands for the location the bullet is currently at. The bullet is then translated accordingly depending on the return location from this method.

The x and z values are calculated correctly, but the y value seems to be a little off and I can't figure out why

Here is where the method is being called from

package Entitys;

import Main.Game;
import Model.Model;
import Tools.TrigCalculator;
import org.lwjgl.util.vector.Vector3f;

public class Projectile {

Model model;
Game game;
Entity entity;
Vector3f startLocation;
float startPitch;
float startYaw;
TrigCalculator trigCalculator;

public Projectile(Vector3f startLocation, float startPitch, float startYaw, Entity entity, Game game){
//The location the camera is at, or where the bullet will be fired from
this.startLocation = startLocation;
//Camera's pitch when shot
this.startPitch = startPitch;
//Camera's yaw when shot
this.startYaw = startYaw;
//The entity representing the bullet
this.entity = entity;
//The class the calculation moveFromPosition is at
this.trigCalculator = game.getToolHandler().getToolTrigCalculator();
}
/* This move method is being called in the render method */
public void move(){
//Translating the entity according the the calculation below.
entity.setTranslation(startLocation);
//Here is where the method is called
startLocation = trigCalculator.moveFromPosition(startLocation, startPitch, startYaw, game);
}
}


Requested Edit: This is how I create a new projectile

projectiles.add(new Projectile(new Vector3f(loc.x, loc.y, loc.z), game.getCamera().getPitch(), game.getCamera().getYaw(),entity, game));


After debugging the return of game.getCamera().getYaw() and getPitch() both return the correct value. Then it's passed into the startPitch value, which is passed into the moveFromPosition method each frame. Other than that it doesn't change.

• What is exactly happening with the pitch of the bullet vs what you are expecting? To high/low or wrong trajectory? Oct 24, 2014 at 16:44
• @Shroeder The bullet, as seen in the picture, should be lined up with the cross. When the pitch is 0, it works, but as I move up or down, the bullet starts to move off the target. So something is wrong with the y calculation in the method Oct 24, 2014 at 16:51
• Yes it looks like your pitch is slightly off, can you show the code you use to get and set the pitch for each logic cycle. Oct 24, 2014 at 18:33
• @Shroeder Edited post Oct 24, 2014 at 18:51
• Why exactly do you multiply by 0 in moveFromPosition?
– JFBM
Oct 25, 2014 at 17:37

Well for one, your x,y,and z would stay zero based on moveFromPosition. If you want the bullet to follow a certain path, you need to get rid of the zeros, math calculates anything multiplied by 0 is equal to 0

Your next problem is you are over-complicating the math in moveFromPosition. All you need to do during an update is

float horizontal = Math.cos(Math.toRadians(pitch)) * wantedSpeedForward;
float vertical = Math.sin(Math.toRadians(pitch)) * wantedSpeedForward;

loc.y += vertical;
//if you wanted strafing, or non-forward motion add this


This insures the bullet travels at the speed you want based on pitch and yaw (just set the rotations properly and it will work) but you may not want to create a physical bullet projectile like this because if you calculate physics, it will slow down the program a lot so the preferred way is a directional spray, probably through raycasting, and spawning particles after its fired upon the raycasted path. This severely decreases the actual physics and makes bullets simplified and more realistic in the end. Now if you were aiming for a bow, you would want this, but I think I have answered your problem and suggested a better solution if need be so I will hold my peace.

EDIT: wouldn't a separate object for the bullet itself be better (you know, where it holds its position, rotation and anything else significant) All you would need to do is bullet_object.update()

• The formula you've given here will move the bullet faster than wantedForwardSpeed if pitch is nonzero. To correct for this, you'd want to multiply the x & z increments by the cosine of pitch. (And as Peethor describes in the other answer, it's beneficial to do this trig only once and cache the increments on the three axes to a velocity vector) Feb 20, 2015 at 20:29
• Yea, I forgot exactly how to use the trig properly at the time and then remembered shortly afterward. I was just making sure understanding was shared here also. Feb 22, 2015 at 4:36

You're doing something strange: Every frame, you calculate the x,y,z values of the bullet's movement, based on a yaw and pitch that will never change. Why not create a vector3 that stores the direction and speed of the bullet in the bullet constructor? This way, you can do the calculations once per bullet, and then just add its speed vector to its current position every frame. This saves resources.

Also, wouldn't it be easier to store the camera's rotation as a matrix or quaternion? You might already be doing this, I can't tell. If you do that, you could simply say that the bullet's direction is equal to the forward member of the quaternion or matrix.

I've personally had a LOT of issues with rotations when trying to calculate them by yaw pitch and roll (especially when you add the third, it can be a nightmare), but simply copying over a rotation matrix (or quaternion) that already works is quite simple.

As a rule of thumb: never use Euler angles unless you have to. For velocities, it's probably just better to use vectors, and don't worry about the orientation. You can use the matrix representation of the camera to find which direction the player is facing.

public Vector3f moveFromPosition(Vector3f location, Vector3f velocity, float dt) {
return location + velocity * dt;
}


Or, since it seems you're using java, you'll probably need some boiler plate for copying and such.

public Vector3f moveFromPosition(Vector3f location, Vector3f velocity, float dt) {
Vetor3f loc = new Vector3f(location);
Vector3f vel = new Vector3f(velocity);
vel.multiply(dt);

public Vector3f getBulletDirection(Camera camera) {