Cogito, ergo sum

Difference between revisions of "Vector"

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search
m (Vector scaling: linked Wikipedia NaN)
m (added vector transformation operators)
Line 70: Line 70:
 
===Mirroring vectors===
 
===Mirroring vectors===
 
There's a convenient mirroring function called <code>MirrorVectorByNormal()</code> that takes two parameters. The first parameter is the vector you want to mirror and the second is the [[wp:surface normal|surface normal]] vector of a plane will "reflect" your vector. The direction (towards or away from your vector) and length do not matter, as long as the length is not zero.
 
There's a convenient mirroring function called <code>MirrorVectorByNormal()</code> that takes two parameters. The first parameter is the vector you want to mirror and the second is the [[wp:surface normal|surface normal]] vector of a plane will "reflect" your vector. The direction (towards or away from your vector) and length do not matter, as long as the length is not zero.
 +
 +
===Coordinate system transformation===
 +
Sometimes it is easier to express an offset relative to a rotation, for example to specify the 1st person weapon position. All engine versions provide two special operators for conversion between world coordinates and a local coordinate system expressed by a [[rotator]]. Assume ''CamRot'' is a camera rotation describing a local coordinate system, for example a player view. Then <code>V << CamRot</code> converts a global offset into a camera-relative local offset, while <code>V >> CamRot</code> converts a camera-relative offset into a global offset.
  
 
===Vector projection<sup>3</sup>===
 
===Vector projection<sup>3</sup>===

Revision as of 08:32, 4 March 2011

The type vector is not a built-in type, but a struct defined in the Object(RTNP, U1, UT, U2, U2XMP, UE2Runtime, UT2003, UT2004, UDK, UT3) class of all Unreal Engine games. Conceptually it corresponds to a three-dimensional euclidean vector and the Object class defines many functions and operators for working with vector values. The importance of the vector struct is stressed by the fact that it is one of only two struct types whose values can be specified directly using a literal.

Vector components use single precision floating-point format, which imposes a practical limit to level sizes. The maximum floating point accuracy is about 7 digits in total. Considering you will most likely want at least 2 or 3 digits after the decimal point to get smooth player movement, the play area of a map should not exceed about ±100000 Unreal Units on each coordinate axis. Static environment can exist a bit further away, since it doesn't require smooth location updates.

Important: The vector struct's components are rounded to integers for replication. Additionally, the values may not exceed the range of about ±1000000 or they will overflow. If you need to replicate vectors with fractional precision or larger values, consider scaling the vector value for replication.

Note: Unreal Engine 3 games may also define other vector-like structs, such as Vector2D or Vector4. In theory, many operations described in this article can also be applied to two- and four-dimensional vectors, but most of them are only defined for three-dimensional vectors (i.e. the Vector struct) in the engine. See the functions and operators defined in Object and other classed of your game to see which operations are available for the data type you want to use.

Vector operations

Not all vector-related operations are available in all Unreal Engine generations. These operations are marked as follows:

  • 3 – The operation is only available in Unreal Engine 3.
  • (no number) – The operation is available in all Unreal Engine generations.

There may be other vector operations available for your game. Just have a look at your game's Object class functions to find out what other predefined functions you can use.

Vector (in)equality

Like all structs, vectors can be compared for equality or inequality with the == and != operators respectively. Two vectors are (in)equal if their corresponding components are (in)equal.

There are no other operators to compare vectors, but of course you can compare certain properties of vectors, such as length. Also you can exploit the definition of the dot product to compare vector directions.

Addition and subtraction

Adding or subtracting two vectors is done via the + and - operators. Two vectors are added or subtracted by adding or subtracting their corresponding components respectively.

Vector scaling

Vector scaling corresponds to multiplication or division by a scalar (i.e. float) value. Multiplying (or dividing) by negative values reverses the vector's direction. Values other than 1 (and -1) change the length of the vector.

Vectors can be multiplied and divided by scalar (i.e. float) values via the * and / operators. Scalar multiplication is commutative (sVal * vVal == vVal * sVal), but scalar division is only defined as vector divided by scalar. Scalar multiplication and division is defined as component-wise multiplication and division by the scalar value respectively.

Multiplication by -1 can be expressed with the preoperator - and corresponds to reversing the vectors direction without changing its length.

Note: It is possible to divide vectors by zero. Like for other float values divided by zero, the resulting vector's components will contain an error value. Such an error value will propagate through all vector operations, causing the results to be error values as well. Be very careful about error values ending up in Actor locations, velocities or accelerations, as these may cause the engine to crash in weird ways! Fortunately there are only few other operations (e.g. Sqrt() or Loge()) capable of producing such "invalid" float values.

Dot product

The dot product of two vectors, also called inner product or scalar product, is defined as the sum of the products of corresponding components of the two vectors.
In UnrealScript this is done with the operator Dot.

By definition, the dot product of perpendicular vectors is zero. The dot product is negative if the vectors point in relatively opposite directions (more than 90 degrees) and positive if they point in relatively similar directions. (less than 90 degrees) Applied to unit vectors, the dot product is exactly the cosine of the angle between the two vectors.

Cross product

The cross product of two 3D vectors, also called the outer product or vector product, is defined as a vector whose length is equal to the area of the parallelogram formed by the two vectors, and that is perpendicular to each of the two vectors. The cross product is not commutative, exchanging the operands inverts the direction of the resulting vector: a×b = -(b×a).

UnrealScript provides the operator Cross for calculating the cross product. The directions of the two operands and the result of the cross product can be determined by the right hand rule:

  • Hold the thumb, index finger and middle finger of your right hand in such a way that they are perpendicular to each other.
  • Now your index and middle finger represent the directions of the first and second operand respectively and the thumb represents the direction of the cross product result.

You can easily see that exchanging the first and second parameters makes your thumb point in the opposite direction. The length of the resulting vector is the product of the length of the operand vectors and the sine of the angle they form. Same or opposite direction results means the sine (and thus the resulting vector) is zero.

Component-wise product

Sometimes you may want to calculate a vector whose components are the products of the corresponding components of two vectors. This can be done with the operator *.

Vector length and unit vector

To get the length of a vector, you can use the VSize() function. To normalize a vector's length to 1 without changing its orientation, you can use the Normal() function. The null vector vect(0,0,0) does not have an orientation by definition, so trying to normalize it does not have any effect.

More vector length3

The standard vector length calculation involves taking the square root of the sum of squared vector component values. In Unreal Engine 3 you can also drop the square root operation and get the squared vector length via the VSizeSq() function. For example if you only want to compare vector lengths, this function is a bit faster. If the engine version you use doesn't provide the squard vector size function, don't bother creating it in UnrealScript just for performance reasons, any UnrealScript implementation would be slower than VSize() itself. If, however, you want to create it because you need the value, you can choose between the expressions Square(VSize(X)) and X dot X, which are equivalent.

Testing for the zero vector can be done using the IsZero() function. This is a bit more efficient than explicitly comparing a vector value to a zero vector literal. (X == vect(0,0,0))

Unreal Engine 3 also provides means to ignore the Z value of a vector when calculating its length. The related functions are called VSize2D() and VSizeSq2D() and work analogously to their "3D" counterparts mentioned above.

If you only want to limit the length of a vector to a certain maximum value, you can use the ClampLength() function. One possible implementation for earlier engine versions could be:

static final function vector ClampLength(vector V, float MaxLength)
{
  return Normal(V) * FMin(VSize(V), MaxLength);
}

Random vectors

To get a vector with a random direction, you can use the VRand() function. It will return a vector of length 1 with a random direction. The end points of vectors returned by this function are approximately uniformly distributed on a unit sphere.

Mirroring vectors

There's a convenient mirroring function called MirrorVectorByNormal() that takes two parameters. The first parameter is the vector you want to mirror and the second is the surface normal vector of a plane will "reflect" your vector. The direction (towards or away from your vector) and length do not matter, as long as the length is not zero.

Coordinate system transformation

Sometimes it is easier to express an offset relative to a rotation, for example to specify the 1st person weapon position. All engine versions provide two special operators for conversion between world coordinates and a local coordinate system expressed by a rotator. Assume CamRot is a camera rotation describing a local coordinate system, for example a player view. Then V << CamRot converts a global offset into a camera-relative local offset, while V >> CamRot converts a camera-relative offset into a global offset.

Vector projection3

Another convenient function is called ProjectOnTo() and takes two parameters. The function returns only that part of the first vector that points in the same direction as the second vector.

Imagine pulling a car with a rope and you don't pull exactly in the direction the car is facing. Not all of your applied force is actually used to move the car, but only the part of your applied force that points in the same direction as the car is facing. That's exactly the part of the vector returned by ProjectOnTo().

In engine versions that don't provide ProjectOnTo(), you can create an equivalent function with the following code:

static final function vector ProjectOnTo(vector A, vector B)
{
  return Normal(B) * (A dot Normal(B));
}

See also