# Difference between revisions of "Vector"

(oh I like this :)) |
m (→Length: LengthSqr(): Language is still a little awkward, but I think this clarifies things a bit better) |
||

Line 120: | Line 120: | ||

; <code>[[vec_t]] Length()</code> | ; <code>[[vec_t]] Length()</code> | ||

; <code>vec_t LengthSqr()</code> | ; <code>vec_t LengthSqr()</code> | ||

− | : <code>Length()</code> returns the vector's length in [[unit]]s. It's faster to use <code>LengthSqr()</code> and square the value | + | : <code>Length()</code> returns the vector's length in [[unit]]s. It's faster to use <code>LengthSqr()</code> and square the other value being compared. |

; <code>[[bool]] IsLengthGreaterThan(flValue)</code> | ; <code>[[bool]] IsLengthGreaterThan(flValue)</code> | ||

; <code>bool IsLengthLessThan(flValue)</code> | ; <code>bool IsLengthLessThan(flValue)</code> |

## Revision as of 08:53, 19 July 2011

** 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:
**X**+forward/-backward**Y**+left/-right**Z**+up/-down

`(1,20,5)`

means 1 unit forward, 20 units to the left 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(1,20,5);

- The classname
`Vector`

is case-sensitive. - You can construct it by defining the X, Y and Z member variables separately, pass a single value for all three or copying the data of another Vector.
- The prefix
`vec`

(or sometimes just`v`

) identifies the variable as a vector.

## Orientation

A vector does not have an orientation; that is determined by the code that uses it.

In the vast majority of cases a vector will be interpreted as **world axis aligned** regardless of an entity's rotation, but there are few cases (e.g. applying physics forces), where they are considered **object axis aligned**.

There is no way of telling which interpretation will be used from the variable, so check for function comments when in doubt. Use `VectorRotate()`

and `VectorIRotate()`

to translate between alignments.

## Uses

- Positioning
- Every entity's position ('origin') is stored as a vector relative to its parent: you are likely to be familiar with this idea already as Cartesian grid coordinates. See
`GetAbsOrigin()`

for more details. - Movement
- An entity attempts to move the length of its velocity vector once per second.
- Collision Traces
- A Traceline or -hull is fired from one point to another, detecting what it "hits" along its path.

## 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 = pTarget->GetAbsOrigin() - GetAbsOrigin(); // Get local vector to target
VectorNormalize(vecTarget); // Normalisation needs to be done beforehand
Vector 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.

## Rotation

Rotating a Vector requires a matrix, so can't be done with an operation like those above. Thankfully you don't need to get involved in the gritty details: just call `VectorRotate(Vector in, QAngle in, Vector& out)`

.

## Special Vectors

Source defines two special Vectors:

`vec3_origin`

- Vector(0,0,0).
`vec3_invalid`

- This is used for invalid Vectors, e.g. if you need to return a Vector in a function, but something is not possible (such as the intersection-point of two parallel straight lines).

## 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 other value being compared.`bool IsLengthGreaterThan(flValue)`

`bool IsLengthLessThan(flValue)`

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

. `void Zero()`

- Sets all elements to 0.

### 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)`

- Tests whether the Vector ends within the given box. Box min/max values are local to the Vector.

### 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*, basically the same as &vec.x or (float*)&vec.

## Helper functions

These globals are all available through `cbase.h`

.

`float VectorNormalize(vec)`

- Divides the vector by its length, normalising it. Modifies the Vector and returns the old length.
`vec_t DotProduct(vecA,vecB)`

- See #Dot product.
`void CrossProduct(vecA,vecB,vecResult)`

- See #Cross product.
`void VectorTransform(Vector in1, matrix3x4_t in2, Vector out)`

- See matrix3x4_t.