# Vec3

Interface representing a 3D vector. A 3D vector is represented by (x, y, z) coordinates, and can
represent a point in space, a directional vector, or other types of data with three ordered
dimensions. 3D vectors can be multiplied by 4x4 matrices (Mat4) using homogeneous coordinate math,
enabling efficient 3D geometry computation. Vec3 objects are created with the `ecs.math.vec3`

Vec3Factory, or through operations on other Vec3 objects.

## Code Example

`const {vec3} = ecs.math `

const a = vec3.xyz(1, 2, 3)

const b = vec3.up() // b is 0, 1, 0

const c = a.plus(b).times(vec3.xyz(3, 1, 1)).normalize() // c is (1, 1, 1)

## Source

The Vec3Source interface represents any object that has x, y, and z properties and hence can be used
as a data source to create a Vec3. In addition, Vec3Source can be used as an argument to Vec3
algorithms, meaning that any object with `{x: number, y: number, z: number}`

properties can be used.

Vec3Source has the following enumerable properties:

`readonly x: number`

Access the x component of the vector.

`readonly y: number`

Access the y component of the vector.

`readonly z: number`

Access the z component of the vector.

## Factory

Vec3 objects are created with the `ecs.math.vec3`

Vec3Factory, with the following methods:

### vec3.from()

`vec3.from({x, y, z}: {x: number, y: number, z: number}) => Vec3`

Create a Vec3 from a Vec3, or other object with x, y, z properties.

### vec3.one()

`vec3.one: () => Vec3`

Create a Vec3 with all elements set to one. This is equivalent to `vec3.from({x: 1, y: 1, z: 1})`

.

### vec3.scale()

`vec3.scale: (s: number) => Vec3`

Create a Vec3 with all elements set to the scale value s. This is equivalent to
`vec3.from({x: s, y: s, z: s})`

.

### vec3.up()

`vec3.up: () => Vec3`

Create a Vec3 pointing in the positive y direction. This is equivalent to
`vec3.from({x: 0, y: 1, z: 0})`

.

### vec3.xyz()

`vec3.xyz: (x: number, y: number, z: number) => Vec3`

Create a Vec3 from x, y, z values. This is equivalent to `vec3.from({x, y, z})`

.

### vec3.zero()

`vec3.zero: () => Vec3`

Create a Vec3 with all components set to zero. This is equivalent to
`vec3.from({x: 0, y: 0, z: 0})`

.

## Properties

Vec3 has the following enumerable properties:

`readonly x: number`

Access the x component of the vector.

`readonly y: number`

Access the y component of the vector.

`readonly z: number`

Access the z component of the vector.

## Immutable API

The following methods perform computations based on the current value of a Vec3, but do not modify its contents. Methods that return Vec3 types return new objects. Immutable APIs are typically safer, more readable, and less error-prone than mutable APIs, but may be inefficient in situations where thousands of objects are allocated each frame. In cases where object garbage collection is a performance concern, prefer the Mutable API (below).

### .clone()

`clone: () => Vec3`

Create a new vector with the same components as this vector.

### .cross()

`cross: (v: Vec3Source) => Vec3`

Compute the cross product of this vector and another vector.

### .data()

`data: () => number[]`

Access the vector as a homogeneous array (4 dimensions).

### .distanceTo()

`distanceTo: (v: Vec3Source) => number`

Compute the euclidean distance between this vector and another vector.

### .divide()

`divide: (v: Vec3Source) => Vec3`

Element-wise vector division.

### .dot()

`dot: (v: Vec3Source) => number`

Compute the dot product of this vector and another vector.

### .equals()

`equals: (v: Vec3Source, tolerance: number) => boolean`

Check whether two vectors are equal, with a specified floating point tolerance.

### .length()

`length: () => number`

Length of the vector.

### .minus()

`minus: (v: Vec3Source) => Vec3`

Subtract a vector from this vector.

### .mix()

`mix: (v: Vec3Source, t: number) => Vec3`

Compute a linear interpolation between this vector and another vector v with a factor t such that
the result is `thisVec * (1 - t) + v * t`

. The factor t should be between 0 and 1.

### .normalize()

`normalize: () => Vec3`

Return a new vector with the same direction as this vector, but with a length of 1.

### .plus()

`plus: (v: Vec3Source) => Vec3`

Add two vectors together.

### .scale()

`scale: (s: number) => Vec3`

Multiply the vector by a scalar.

### .times()

`times: (v: Vec3Source) => Vec3`

Element-wise vector multiplication.

## Mutable API

The following methods perform computations based on the current value of a Vec3, and modify its contents in place. They are parallel to methods in the mutable API above. Methods that return Vec3 types return a reference to the current object for convenient method chaining. Mutable APIs can be more performant than Immutable APIs, but are typically less safe, less readable, and more error-prone. In cases where a section of code will likely not be called many times on a given frame, consider using the Immutable API (above).

This next example is equivalent to the Immutable API example above, but allocates two Vec3 objects instead of six:

`const {vec3} = ecs.math `

const a = vec3.xyz(1, 2, 3)

const b = vec3.up() // b is 0, 1, 0

a.setPlus(b).setTimes(b.setXyz(3, 1, 1)).setNormalize() // a is (1, 1, 1) and b is (3, 1, 1)

### .setCross()

`setCross: (v: Vec3Source) => Vec3`

Compute the cross product of this vector and another vector. Store the result in this Vec3 and return this Vec3 for chaining.

### .setDivide()

`setDivide: (v: Vec3Source) => Vec3`

Element-wise vector division. Store the result in this Vec3 and return this Vec3 for chaining.

### .setMinus()

`setMinus: (v: Vec3Source) => Vec3`

Subtract a vector from this vector. Store the result in this Vec3 and return this Vec3 for chaining.

### .setMix()

`setMix: (v: Vec3Source, t: number) => Vec3`

Compute a linear interpolation between this vector and another vector v with a factor t such that the result is thisVec * (1 - t) + v * t. The factor t should be between 0 and 1. Store the result in this Vec3 and return this Vec3 for chaining.

### .setNormalize()

`setNormalize: () => Vec3`

Set the vector to be a version of itself with the same direction, but with length 1. Store the result in this Vec3 and return this Vec3 for chaining.

### .setPlus()

`setPlus: (v: Vec3Source) => Vec3`

Add two vectors together. Store the result in this Vec3 and return this Vec3 for chaining.

### .setScale()

`setScale: (s: number) => Vec3`

Multiply the vector by a scalar. Store the result in this Vec3 and return this Vec3 for chaining.

### .setTimes()

`setTimes: (v: Vec3Source) => Vec3`

Element-wise vector multiplication. Store the result in this Vec3 and return this Vec3 for chaining.

### .setX()

`setX: (v: number) => Vec3`

Set the Vec3's x component. Store the result in this Vec3 and return this Vec3 for chaining.

### .setY()

`setY: (v: number) => Vec3`

Set the Vec3's y component. Store the result in this Vec3 and return this Vec3 for chaining.

### .setZ()

`setZ: (v: number) => Vec3`

Set the Vec3's z component. Store the result in this Vec3 and return this Vec3 for chaining.

## Set API

The following methods set the value of the current Vec3 object without regard to its current content, replacing whatever was there before.

### .makeOne()

`makeOne: () => Vec3`

Set the Vec3 to be all ones. Store the result in this Vec3 and return this Vec3 for chaining.

### .makeScale()

`makeScale: (s: number) => Vec3`

Set the Vec3 to have all components set to the scale value s. Store the result in this Vec3 and return this Vec3 for chaining.

### .makeUp()

`makeUp: () => Vec3`

Set the Vec3 to be pointed in the positive y direction. Store the result in this Vec3 and return this Vec3 for chaining.

### .makeZero()

`makeZero: () => Vec3`

Set the Vec3 to be all zeros. Store the result in this Vec3 and return this Vec3 for chaining.

### .setFrom()

`setFrom: (source: Vec3Source) => Vec3`

Set this Vec3 to have the same value as another Vec3 or other object with x, y, and z properties. Store the result in this Vec3 and return this Vec3 for chaining.

### .setXyz()

`setXyz: (x: number, y: number, z: number) => Vec3`

Set the Vec3's x, y, and z components. Store the result in this Vec3 and return this Vec3 for chaining.