The first step in explaining how it work, Is forst to make sure you understand the data types.
LocationA
location has three components: the object ID of the area, a vector representing the position within the area, and a floating point number representing the facing.
It is the vector within that data type that we will be most concerned with.
vectorNow a
vector is a
Struct The code for defining the vector structure in NWN would look like this.
struct vector
{
float x;
float y;
float z;
}
This allows each of the elements to be minipulated useing the
dot (".") operator Now how you treat a vector is all acording to what you are storing in it. Like the use in the location data type above it is commonly used as just an (x,y,z) position within the map grid.
Other Times it is used to represent, wait for it..., you would never guess..., a vector.
Here are a couple links I just found on vectors. I have not read either of thies they just looked interesting for the subject at hand.
Vector Math for 3D Computer Graphics
http://emweb.unl.edu...rs/vectors.html
Note: I am only going to use two dimentions (x,y) in this explanation, The logic still hold true regaurdless of the number of dimentions you use.
A vector being really nothing more then a direction and a magnitude(distance).
The direction of the vector can be look at as the slope of the line that passes through the orgin cords (0,0) and the point given by the vector. The
Slope–intercept form of the equation for a stright lin is given as y=mx+b. Where m = the rise in the y axsis divided by the run in the x axsis which defines the slop of the line. b = to the point at which the line crosses the y axis. since our vectors are definded by a single point with a line going through the orgin (0,0) we can simply ingnore the b since it will alway be 0 once we have your value for our vector. Our direction of our vector is simply defined by the slope of the line, the vector (x,y) will head in the direction of a line with a slope of y/x.
The magnitude of the vector is nothing more then the distance form the orgian(0,0) to the point (x,y).
So the way you use your vector data type is highly dependent on what you currently have stored in it. You do not want to treat a vector holding a position the way you would treat a vector holding a vector.
Explanation of the function
No this is not really as hard as the above may have made it sound. Everything above is just good back gorund information to help you minipulate vevtors to you hearts content. The best way to explain the function I gave to take my thought process step by step in writing the function.
After reading your original post. I deducted that you wanted to move a given distance from source location towards a target location. In order to script it. All I really had to do is figure out the direction(vector) between the two locations and give it the distance(magnitude) that you wanted to move. At this point all I have is a
line segment defined by two locations. The First thing I need to do is pull the x,y cords out of the locations to have my two segment ends defined. This was done using the
GetPositionFromLocation function. another option would have been to use the
GetPosition function to get it from an object.
vector vSource = GetPositionFromLocation(lSource);
vector vTwards = GetPositionFromLocation(lTowards);
Since both of thies are vector data types I can use the
dot (".") operator to get the x, y information. so my points are.
(vSource.x,vSource.y) and (vTowards.x,vTowards.y)
Now in order to turn this segment into a vector, instead of two positions, What i need to do is move the segment to where the source point is at the orgin or cords (0,0). I can do this by subtracting my source cords from both points. NWN script will allow you to do this by simply subtracting the vectors.
vector1 - vector2 = (vector1.x-vector2.x , vector1.y - vector2.y)
Is the way that subtracting one vector from another works.
So to move my segment so vSource is at (0.0) I am going to subtract vSource from both the Source and Towards points.
// Since this is always moved to (0,0) it is implied and can be ingnored.
vector vMovedSource = vSource - vSource;
//Since vMovedSource of this segment is now at (0,0) This is now my Vector no longer a position with a magnitude
// equal to is length.
vMovedTowards = vTowards - vSource;
We have now changed our segment into a vector. This vector gives both the direction and the distance that lTowards is from lSource.. We still have a litle bit of work to do to it though. It is really no good to us with the magnitude(length) that it currently has. What we need to do is what is called mormalizing the vector. All this means is to give the vector a length of one unit. In our case 1 meter since NWN uses meters. In order to normalize the vector we devide both the x and the y cords by the distance. This will keep the same slope for the line it is on and at the same time decrease the size to 1 unit.
Now you could use the
Distance formula to figure out the magnitude. But bioware has already given us a function to find the distance between two locations So i used it:
GetDistanceBetweenLocationsBioware also has other built in functions to normlize vectors:
VectorNormalizeThere is also a function that I could have used to get the length of the vector:
VectorMagnitude For simplicity right now lets just use VectorNormalize
vector vNormilizedTowards = VectorNormize(vMovedTowards);
The only thing really left to do to our vector, so we can use it, is to change the magnitude to the length we want to move our source location. We do that by simply legnthing the vector back out by multiplying both x and y of our cord by the length we want.
vector vVectorToMove =
Vector (vNormalizedTowards.x * fMeters , vNormalizedTowards.y * fMeters);
Edit: Ok So I'm tired and didnt read the numbers on the grid lines right. The normilized and magnitude vectors ar ten times too big.
In order to move our vSource position vector, the distance and direction we want, just add the new vVectorToMove to it.
vMoveTo = vSource + vVectorToMove.;
The only thing lest after that is rebulding the location and returning it.
return
Location( GetAreaFromLocation(lSource), vMoveTo,
VectorToAngle(vMoveTo));
Hope this helps you understand what was done. I did do a little combining of the instructions above. and Reordered them to combine them together better. but this is the main thought process behing the function.
L8
Modifié par Lightfoot8, 04 mars 2011 - 03:14 .