> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spurdoverse.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Vector2

> 2D vector for screen positions and sizes.

export const like_0 = "Vec2Like"

export const name_0 = "Vector2"

A 2D vector for screen positions and sizes, in pixels with `y` pointing down. Global class, no import.

```ts theme={null}
const center = new Vector2(960, 540);
const corner = center.add([100, -50]);   // [x, y] and { x, y } work anywhere a Vector2 does
```

Fields are 32-bit floats; assigning a non-number or NaN throws.

A [Vector](/api/types/vector) is accepted too and gives its `x` and `y`. To get a screen position from a world one, use [render.worldToScreen](/api/render#worldtoscreen).

## Overview

<CardGroup cols={2}>
  <Card title="Common" icon="layer-group" href="#common">
    `from`, `set`, `add`, `lerp`, `normalize`…
  </Card>

  <Card title="Length and distance" icon="ruler" href="#length-and-distance">
    `length`, `distTo`, `dot`, `cross`.
  </Card>

  <Card title="Rotation" icon="rotate" href="#rotation">
    `rotated`.
  </Card>
</CardGroup>

***

## Common

Every argument takes any <code>{like_0}</code>, not just a <code>{name_0}</code>.

| Member | Does |
| :- | :- |
| <code>new {name_0}(value)</code>, <code>{name_0}.from(value)</code> | Copy from any <code>{like_0}</code>. |
| `set(...)` | Replaces every component in place, returns `this`. Same arguments as the constructor. |
| `clone()` | A copy. |
| `equals(other, epsilon?)` | Every component within `epsilon`. Default `0`, exact. |
| `toArray()`, `toJSON()` | Plain array, plain object. |
| `toString()` | <code>"{name_0}(…)"</code> |
| `add(other)`, `sub(other)` | Component-wise. |
| `scale(factor)` | Every component times `factor`. |
| `mul(x)`, `div(x)` | By a number, or component-wise by another value. Dividing by zero throws `RangeError`. |
| `lerp(other, t)` | Linear blend, `t` not clamped. |
| `normalize()`, `normalized()` | The first changes the value and returns `this`, the second returns a copy. |

Only `set()` and `normalize()` change the value. Nothing changes its arguments.

| Also | Returns |
| :- | :- |
| `Vector2.zero()`, `Vector2.one()` | `(0, 0)`, `(1, 1)` |
| `negate()`, `abs()` | New `Vector2` |
| `isZero(epsilon?)` | Both components within `epsilon` (default `1e-6`) of zero |
| `isFinite()` | No NaN or infinite component |

***

## Length and distance

| Method | Returns |
| :- | :- |
| `length()`, `lengthSqr()` | Length, squared length |
| `distTo(other)`, `distToSqr(other)` | Distance, squared distance |
| `dot(other)` | Dot product |
| `cross(other)` | `x * other.y - y * other.x`, a number |

```ts theme={null}
const fromCenter = screen.distTo(render.screenSize.scale(0.5));   // pixels from the crosshair
```

***

## Rotation

### rotated

<br />

```ts theme={null}
rotated(degrees: number, pivot?: Vec2Like): Vector2
```

A copy rotated around `pivot` (default `(0, 0)`). Positive degrees turn clockwise on screen, because `y` points down.

```ts theme={null}
new Vector2(1, 0).rotated(90);                     // (0, 1), pointing down
const tip = center.add([radius, 0]).rotated(angle, center);
```

***

## Example

An arrow at the edge of a circle around the crosshair, pointing at a target's world position.

```ts theme={null}
import render from "@native/render";

const target = new Vector(1200, -350, 64);

on("render", () => {
    const center = render.screenSize.scale(0.5);
    const screen = render.worldToScreen(target);
    if (!screen) return;

    const dir = screen.sub(center);
    if (dir.length() < 120) return;   // already close to the crosshair

    const unit = dir.normalized();
    const tip = center.add(unit.scale(100));
    const back = tip.sub(unit.scale(14));

    render.triangleFilled(tip, back.rotated(25, tip), back.rotated(-25, tip), "#ffcc00");
});
```
