# Difference between revisions of "Vector"

(→Declaration: Added notes on orientation) |
m (→Cross product: added links) |
||

Line 111: | Line 111: | ||

A cross product is a vector '''perpendicular''' to two input vectors. It's used to extrapolate a third dimension from just two: the cross product of a vector pointing down the X-axis and a vector pointing down the Y-axis is a vector pointing down the Z-axis. | A cross product is a vector '''perpendicular''' to two input vectors. It's used to extrapolate a third dimension from just two: the cross product of a vector pointing down the X-axis and a vector pointing down the Y-axis is a vector pointing down the Z-axis. | ||

− | The equation is fiddly and doesn't have to be learnt; just use <code>CrossProduct(vecA,vecB,&vecResult)</code>. There generally isn't any need to normalise the input vectors. | + | The equation is fiddly and doesn't have to be learnt; just use <code>CrossProduct(vecA,vecB,&vecResult)</code>. There generally isn't any need to normalise the input vectors. Most modders will likely only use cross products rarely, if ever - but if required, be aware that a [http://mathworld.wolfram.com/CrossProduct.html moderate amount of math] is required to [http://en.wikipedia.org/wiki/Cross_product properly understand] this operation. |

== Member functions == | == Member functions == |

## Revision as of 02:38, 15 April 2009

## Contents

**Vector** is a C++ class that represents a line with direction and length, starting at the current origin.

Each vector contains three `vec_t`

'ordinates'. `(0,20,5)`

means 20 units in front of and 5 units above the current origin.

**Note:**Source's vector class is geometric and

*very*different from the Standard Template Library's, which is a type of array. The STL-style vector has been renamed

`CUtlVector`

in Source.## Declaration

Vector vecMyVector = Vector(0,20,5);

- The classname
`Vector`

is case-sensitive. - You could also assign to the X, Y and Z member variables separately.
`vec`

(or sometimes just`v`

) identifies the variable as a`Vector`

.

### Orientation

The vast majority of the time, vectors are considered to be orientated relative to global coordinates, that is, they are **world-axis-aligned**: the *forward* (X) component is aligned to the east-west line, the *right* (Y) component is aligned north-south, and the 'up' Z component is up-down.

In a few cases, however, the vector should instead be considered to be **object-axis-aligned** - rotated to the local coordinate frame of the parent's angles. This is the case in some functions for applying forces to physics objects, so coders should be aware of this, and check for any comments specifying this when in doubt.

## Uses

### Positioning

Every entity's position is stored as a vector relative to its parent. You are likely to be familiar with this idea already as grid coordinates.

The parent-relative vector stored by the entity is 'local'; calculating an 'absolute' vector relative to the world requires extra work. The two Abs functions below do that work for you, but are more expensive.

### Movement

An entity attempts to move the length of its velocity vector once per second. The code looks something like this:

Vector velocity = Vector(0,5,0);// 5 units/second forwardVector vecNewOrigin = GetAbsOrigin() + velocity * gpGlobals->frametime;// frametime is in seconds, e.g. 0.033SetAbsOrigin(vecNewOrigin);

Notice how `frametime`

is used to regulate the entity's speed regardless of how long each frame takes to calculate. See scalar multiplication for more detail on the operation.

As with the origin, velocity is stored relative to the parent. AbsVelocity represents the velocity relative to the rest frame of the world, and is the more commonly used method.

### Tracelines

*Main article: TraceLines*

Tracing is the process of going from a point A towards another point B, and finding out the first thing that we "hit" on our way from A to B (**TraceLine**).

## Operations

All vectors in an operation must have the same origin for the result to make sense. Whether a local or absolute origin is used depends on what you're trying to achieve.

### Addition

Adding two (or more) vectors **combines** them. You have already experienced vector addition if you've ever pushed an object with two hands!

### Subtraction

Subtracting one vector from another produces the **difference** between the two - in other words, how to get to the first location from the second. The result is local to the *second* vector.

**Tip:**The order in which you subtract defines the direction of the vector.

### Multiplication

#### Scalar

Multiplying or dividing a vector by a scalar (i.e. an int or float) will change its **length** (sometimes called "magnitude") without affecting its direction.

**Tip:**Dividing a vector by its length normalises it. Use

`VectorNormalize()`

to do this quickly.#### Dot product

Multiplying two vectors then adding the result's ordinates produces a dot product, which when both vectors have been normalised (see above) is equal to the **cosine** of the angle between the two vectors.

One use of a dot product is to tell how closely the two vectors align. +1 means a match, 0 means they are perpendicular to each other, and -1 means they are opposed.

**Note:**

*True dot products are only produced when the length of both vectors is 1.*The normalisation step has been skipped in the following demonstration to make its equations simpler (but the positive/zero/negative rule still applies).

This code calculates a dot product with the aid of Source's various helper functions:

Vector vecTarget = GetAbsOrigin() - pTarget->GetAbsOrigin();// Get local vector to targetVectorNormalize(vecTarget);// Normalisation needs to be done beforehandVector vecFacing;AngleVectors(GetLocalAngles(),&vecFacing);// Convert facing angle to equivalent vector (arrives normalised)float result =DotProduct(vecTarget,vecFacing);// Get the dot product.if (result > 0) Msg("pTarget is in front of me!\n");

**Tip:**There is no need to normalise if you only care about whether one location is in front of another.

#### Cross product

A cross product is a vector **perpendicular** to two input vectors. It's used to extrapolate a third dimension from just two: the cross product of a vector pointing down the X-axis and a vector pointing down the Y-axis is a vector pointing down the Z-axis.

The equation is fiddly and doesn't have to be learnt; just use `CrossProduct(vecA,vecB,&vecResult)`

. There generally isn't any need to normalise the input vectors. Most modders will likely only use cross products rarely, if ever - but if required, be aware that a moderate amount of math is required to properly understand this operation.

## Member functions

### Length

`vec_t Length()`

`vec_t LengthSqr()`

`Length()`

returns the vector's length in units. It's faster to use`LengthSqr()`

and square the value for comparison, however.`bool IsLengthGreaterThan(flValue)`

`bool IsLengthLessThan(flValue)`

- Helpers that perform fast length checks using
`LengthSqr()`

. `void Zero()`

- Guess what?

### Direction

`void Init(vec_t X, Y, Z)`

- Quickly set an existing vector's ordinates.
`void Random(vec_t minVal,vec_t maxVal)`

- Randomises all three ordinates within the given range.
`void Negate()`

- Reverses the vector's direction without affecting its length.
`Vector Max(vOther)`

`Vector Min(vOther)`

- Clamps the vector's ordinates either above or below the given values. The ordinates won't stay in proportion (i.e. direction might change).

### Comparison

`vec_t DistTo(vOther)`

`vec_t DistToSqr(vOther)`

- Returns the distance between the current vector and
`vOther`

as a scalar. As ever, the squared flavour is faster. `vec_t Dot(vOther)`

- Returns the dot product of the current vector and
`vOther`

. `Vector Cross(vOther)`

- Returns the cross product of the current vector and
`vOther`

. `bool WithinAABox(vecBoxmin,vecBoxmax)`

- Does the vector end within this box? Argument vectors are local.

### Casts

`Vector2D AsVector2D()`

- Casts to Vector2D.
`vec_t Length2D()`

`vec_t Length2DSqr()`

- As their standard equivalents, but ignoring the Z-axis.
`Base()`

- Casts to vec_t.
**To do:**What does that achieve?

## Helper functions

`vec_t DotProduct(vecA,vecB)`

- See #Dot product.
`void CrossProduct(const Vector& a, const Vector& b, Vector& result )`

- See #Cross product.