Position Calculation

I'm using SFML with C++ to make my little game that I'm working on, and it's all going reasonably well though I have one thing that I need help with. I need a formula which will take the direction and speed and give the x,y, movement. SFML gives rotation in degrees anticlockwise from North btw.

This is currently a bit beyond my level of maths as I'm still in early high school, so I'm not just being lazy. Also, this has almost certainly been asked before I'd guess though I have no clue what to search for.

Thanks for any help
I think what you're after is the vector of the object's direction? If you don't know what vectors are check this out

http://physics.about.com/od/mathematics/a/VectorMath.htm

You want to calculate a vector for the direction which you can do using the dot product.

http://freespace.virgin.net/hugo.elias/routines/r_dot.htm

Think of 'north' as you put it, as an up vector (0,-1). You already know the angle between the up vector and the vector representing the direction of your object, and we also know that

Cos(angle) = DotProduct(upVector,DirectionVector) / (length(upVector) * length(directionVector))

I don't want to just do the problem for you as that won't help you to learn but the links I've provided tell you how to calculate dot product and the length of a vector so by filling in the values in the equation above and rearranging it you can calculate the direction vector.

Good luck.
Last edited on
I don't see how the dot product helps here. In order to use it he needs the direction vector, but the problem here is that he is trying to find the direction vector.

Crash course on sin/cos:

Get a piece of paper and draw a circle on it. This circle is on a "grid", where the center point is at (0,0). The circle has a radius of 1, so the right-most point of the circle is (1,0), the top is (0,1), the left side is (-1,0), and the bottom is (0,-1).

With me so far?

now put your finger at the right most point. With your finger, start tracing the circle counter clockwise.

Your finger is now forming sin and cos waves. The Y position of your finger forms a sin wave, and the X position of your finger forms a cos wave.


so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// assuming 'sin' and 'cos' take degrees:
// right-most point:
cos( 0 );  // <- 1
sin( 0 );  // <- 0

// top-most point:
cos( 90 );  // <- 0
sin( 90 );  // <- 1

// left-most point:
cos( 180 );  // <- -1
sin( 180 );  // <- 0

// bottom-most point:
cos( 270 );  // <- 0
sin( 270 );  // <- -1
}


So basically, if you have a target angle "theta" and want to find out the desired X,Y position on that circle, you can just use sin/cos:

1
2
y = sin(theta);
x = cos(theta);


That will form a "unit vector" (a vector with a length of 1) which moves in the direction of the given angle theta.

From there, you can multiply x and y by a speed. So say you want to move an object 6 pixels/units instead of 1:

1
2
y = sin(theta) * 6;
x = cos(theta) * 6;



Now there are are a few things to be concerned with:

1) sin/cos in the c library take radians not degrees. So if you have the angle in degrees, you'll need to convert. Converting is simple: 180 degrees = pi radians, so to convert:
 
angle_in_radians = angle_in_degrees * pi / 180;


2) Remember that with sin/cos, the circle is formed counter-clockwise, not clockwise.

3) With sin/cos, positive Y is up and negative Y is down. In SFML it's the other way around, so you might have to negate your Y.

4) With sin/cos, the circle starts (ie: angle 0) is the right-most point, not the top-most point. So if you want it to originate at the top most point, you'll need to adjust (add 90 degrees to theta)
Ok, so, I wrote this...though there appears to be something wrong:

1
2
3
4
5
6
7
8
9
10
11
12
if (up)
		{
 			float dRotation = 360 - SpaceShip.GetRotation();
			float rRotation = dRotation * pi / 180;
			float rOffputX = std::sin(rRotation);
			float rOffputY = std::cos(rRotation);
			float dOffputX = rOffputX * 180 / pi;
			float dOffputY = rOffputY * 180 / pi;
			SpaceShip.Move(dOffputX, dOffputY);
		}

Good effort. I spot a few problems:

1
2
3
4
5
6
7
8
float dRotation = 360 - SpaceShip.GetRotation();  // <-  switches from counter-clockwise to clockwise.  Good.
float rRotation = dRotation * pi / 180;  // <- convert degrees to radians.  Good.
float rOffputX = std::sin(rRotation);  // <- mixed up x and y here.  cos is x
float rOffputY = std::cos(rRotation); // <- and sin is y.  not the other way around

float dOffputX = rOffputX * 180 / pi; // <- no need for conversion here.  You no longer have an angle
float dOffputY = rOffputY * 180 / pi; // <-  rOffputX and Y are "unit vectors" which point in the direction
  // you want to move.  All you have to do now is scale them to your speed 

Fixed, thanks a bunch :D
1
2
3
4
5
float dRotation = 270 - SpaceShip.GetRotation();
			float rRotation = dRotation * pi / 180; 
			float rOffputX = std::cos(rRotation) / 2;
			float rOffputY = std::sin(rRotation) / 2;
			SpaceShip.Move(rOffputX, rOffputY);
Topic archived. No new replies allowed.