Thank you so much for this thread. I was just about to post something along these lines myself, so you've saved me a ton of work. There are a few small things missing which I will add.
In mathematics a vector is a set of ordered real numbers (a real number is simply a number that has a fractional part). In the Cartesian coordinate system they are used to define points in space, either 2D (x, y) or 3D (x, y, z). From this point on I will, for simplicity's sake deal with just 2D vectors. The coordinates 0,0 (or 0,0,0 in 3D) has a special name - it is called the origin and all vectors are defined relative to it. This is important when things such as rotation are considered. As the position of each object in an area in NwN is defined by a 3D vector so there is an origin - the extreme South-West corner of the area.
There are three main operations that can be carried out on vectors - addition, subtraction and multiplication (Note vectors may never have division applied to them, but there is a workaround). There are 2 different ways (that I know of - true mathematicians may know more) that these operations may be carried out. Scalar operations are those where a single number is applied to a vector. You can have scalar addition, scalar subtraction and scalar multiplication.
Examples where v is a vector and s is a single real number.
addition - v = (v.x + s, v.y + s)
subtraction - v = (v.x - s, v.y - s)
multiplication - v = (v.x * s, v.y * s)
Note it is possible to simulate scalar division by performing scalar multiplication. The trick is to use the reciprocal (don't panic explanation follows) of the divisor. The reciprocal is calculated by dividing the number 1.0 by (in this case) the divisor. Say you want to divide a vector by 2 you find the reciprocal of 2 (i.e. 1.0 / 2.0 = 0.5) and then perform scalar multiplication using that number.
As the operations involving 2 vectors have already been more than adequately explained I will move on.
Vectors can be considered to be straight lines drawn from the origin to the coordinates that are stored in the vector variable. As such they have a another property that can be calculated - their length. This is a relatively simple thing to calculate (note I writing the following equation in this manner due to lack of symbols) - length = square root((x * X) + (y * Y)).
Finally rotation. Through the use of trigonometry it is possible to rotate a vector around the origin. Now as that stands it's not very useful in NwN. However, by combining vector operations (i.e. operations involving two vectors) it is possible to make a vector orbit a different point in space. What you need to do is (the explanation is more complicated than the actuality) to move the vector you want to orbit to the location it would occupy if the point to be orbited was actually the origin, perform the rotation and then move the rotated vector back by the same amount as in your original move. Simply put ->
O is the vector to orbit
s is the vector to do the orbiting
a is the angle of rotation (how many degrees to travel)
move
s = s - o
rotate
s.x = s.x * Cosine(a) + s.y * Sine(a)
s.y = s.x * Sine(a) + s.y * Cosine(a)
move back
s = s + o
or in NwN script (the 4 variable declarations at the start are for illustrative purposes only)
float fAngle;
vector vStartPosition = GetPositionFromLocation(lcurrent);
vector vCentrePos = GetPositionFromLocation(lcentre);
vector vNewPosition;
//theoretically move vector to centre
float fOldX = vStartPosition.x - vCentrePos.x;
float fOldY = vStartPosition.y - vCentrePos.y;
//rotate about the origin (0,0)
float fSine = sin(fAngle);
float fCosine = cos(fAngle);
float fWorkingX = fOldX * fCosine - fOldY * fSine;
float fWorkingY = fOldX * fSine + fOldY * fCosine;
//theoretically move vector to new position
vNewPosition.x = fWorkingX + vCentrePos.x;
vNewPosition.y = fWorkingY + vCentrePos.y;
Be warned, unless you are careful the above code fragment could place the vector outside of the area which in turn may well crash NwN.
TR