How to shift a vector based on the rotation of another vector?

I’m learning 2D programming, so excuse my approximations, and please, don’t hesitate to correct me. I am just trying to fire a bullet from a player. I’m using HTML canvas (top left origin).

Here is a representation of my problem: • The black vector represent the position of the player (the grey square).
• The green vector represent its direction.
• The red disc represents the target.
• The red vector represents the direction of a bullet, which will move in the direction of the target (red and dotted line).
• The blue cross represents the point from where I really want to fire the bullet (and the blue and dotted line represents its movement).

This is how I draw the player (this is the player object. Position, direction and dimensions are 2D vectors):

ctx.save();
ctx.translate(this.position.x, this.position.y);
ctx.rotate(this.direction.getAngle());
ctx.drawImage(this.image, Math.round(-this.dimensions.x/2), Math.round(-this.dimensions.y/2), this.dimensions.x, this.dimensions.y);
ctx.restore();

This is how I instanciate a new bullet:

var bulletPosition = playerPosition.clone(); // Copy of the player position
var bulletDirection = Vector2D.substract(targetPosition, playerPosition).normalize(); // Difference between the player and the target, normalized
new Bullet(bulletPosition, bulletDirection);

This is how I move the bullet (this is the bullet object):

var speed = 5;

And this is how I draw the bullet (this is the bullet object):

ctx.save();
ctx.translate(this.position.x, this.position.y);
ctx.rotate(this.direction.getAngle());
ctx.fillRect(0, 0, 3, 3);
ctx.restore();

How can I change the direction and position vectors of the bullet to ensure it is on the blue dotted line?

I think I should represent the shift with a vector, but I can’t see how to use it.

• Basically, you're trying to simulate the bullet being fired from the side of the player instead of the center of the player? Changing the angle of fire from the side based on the target the player is looking at? – MichaelHouse Nov 16 '12 at 2:34
• Yes, basically I’m trying to fire the bullet from a gun (blue cross) held by the player (grey square). – bpierre Nov 17 '12 at 0:05
• Then the angle will change depending on how far away the object that the player is looking at is. Since you'll have to find the object the player is looking at, you can just use it's position to point the gun. – MichaelHouse Nov 17 '12 at 0:40
• Yes, this is what I am already doing: the target (red disc) is the mouse pointer, and the player direction follows it. My problem is to translate the bullet position according to the player rotation, I can’t see how to do this. – bpierre Nov 17 '12 at 0:45

Just offset the shot when you instance a new bullet.

I assume your always working in world space given how you instance a new bullet so like this.

Vector2D offset = player.velocity.perpendicular().normalize().scaleBy(playerWidth * 0.5);

// Some vector.perpendicular() functions will be left handed some will be right.
// so you might have to negate this offset value to get it on the proper side of the player.

var bulletPosition = playerPosition.clone().add(offset); // Copy of the player position

// now you should have no problems calculating your angle etc since you have a valid starting point for your bullet.

Edit: I just noticed that your also calculating the direction of travel for the bullet from the player's position and not the bullets position when you first instantiate a new bullet.

var bulletDirection = Vector2D.substract(targetPosition, bulletPosition).normalize(); // Difference between the bullet and the target, normalized
new Bullet(bulletPosition, bulletDirection);

Edit: Your right I screwed up. You need to use the players facing as your offset.

// If the player's velocity is independent to the player rotation
// (ie. a space game or drifting etc) use the rotation as the vector your facing.
Vector2D offset = player.velocity.perpendicular().normalize().scaleBy(playerWidth * 0.5);