2d vector: a pair of values, eg. (x, y)
3d vector: a trio of values, eg. (x, y, z)
So all positions are vectors. Also all directions can be stored as vectors.
Given the points A and B, the direction from A to B is the vector B-A. Call this direction vector D. Then you can start doing basic algebra with them, eg. B = A+D (this is where the C++ vector class comes in handy as it lets you write such things directly).
The direction vector D contains both direction and distance information. You can extract the distance using Pythagoras:
dist = d.magnitude() = sqrt(d.x*d.x + d.y*d.y)
Once you have that, you can normalize d:
d.x /= dist;
d.y /= dist;
Or if you have good C++ classes:
d /= dist; or
d = ~d;
This will give you a unit vector, which holds only direction information. It points in the same direction as the original D, but has length=1. Unit vectors are especially handy for using with dot products...
The dot product, a | b = a.x*b.x + a.y*b.y. If a and b are both unit vectors, this gives the cosine of the angle between them. If only a is a unit vector, this tells you how much of vector b lies along the direction of a. Which is a lot more useful than it might seem! It will be zero if the lines are at right angles, positive if they are in the same direction, negative if they are in opposite directions.
An example of a simple vector based physics system:
Vector pos(0, 0);
Vector vel(0, 0);
Vector dir(0, 0);
// add velocity
pos += vel;
// apply air resistance
vel *= 0.9;
// apply gravity
const Vector gravity(0, 0.1);
vel += gravity;
// apply thrust
if (firing thruster)
vel += dir;
// turn by angle
dir = Vector(dir.x*cos(ang) - dir.y*sin(ang),
dir.y*cos(ang) + dir.x*sin(ang));
Which is probably very similar to stuff you are already doing, as a lot of vector math is just common sense!
Let's add a bit of collision. Assume we have a wall defined by an infinitely long line (if the line has fixed ends the same principle applies but needs a few extra checks). You can store this line as a vector holding any arbitrary point on the line, and another unit vector holding the normal of the line (the normal is just a vector at 90 degrees to the direction of the line).
Say L is a point on the line, N is the normal, and you want to check for collision of a point P. Work out:
// direction from point to line
Vector d = L - P;
// dot the direction with the line normal
float dot = d | N;
// which side of the line are we on?
if (dot > 0)
Ok, let's try bouncing off the line, rather than just stopping dead after we hit it. For that, we want to reverse the amount of our velocity that was heading towards the surface, but leave the amount of velocity that was sideways on to the surface alone. Really easy to do with dot products:
// how much velocity was towards the surface?
float dot = vel | N;
// recoil away from the surface by that amount
Vector recoil = dot * N;
// apply recoil. One of it will cancel out
// the movement towards the surface, and two
// of it makes us bounce back away from it.
vel -= recoil*2;
You can really easily extend this to support non-elastic collisions, where the surface absorbs some amount of your energy. Either change the last line above to:
vel -= recoil*1.5;
to absorb half the energy, or for a surface that also absorbs sideways motion:
vel = (vel-recoil*2) * 0.5;
The really great thing about vectors is that they work pretty much the same in 2d and 3d. Working with angles is ok but sometimes a bit complicated in 2d, but becomes a million times worse if you try to extend it into 3d, while vectors are equally simple in either.