# @fimbul-works/vec

A high-performance TypeScript vector math library providing both **functional** and **object-oriented** APIs for 2D, 3D, and 4D vector operations with a focus on performance, type safety, and immutability.

[![npm version](https://badge.fury.io/js/%40fimbul-works%2Fvec.svg)](https://www.npmjs.com/package/@fimbul-works/vec)
[![TypeScript](https://badges.frapsoft.com/typescript/code/typescript.svg?v=101)](https://github.com/microsoft/TypeScript)
[![Bundle Size](https://img.shields.io/bundlephobia/minzip/@fimbul-works/vec)](https://bundlephobia.com/package/@fimbul-works/vec)

## ✨ Highlights

- **🎯 Two API Styles**: Choose between modern functional API (arrays) or classic OOP API (classes)
- **🛡️ Type Safe**: Full TypeScript support with strict typing and array tuple types
- **📏 Multiple Distance Metrics**: Euclidean, Manhattan, Chebyshev, and Minkowski
- **🎮 Graphics Ready**: Homogeneous coordinates and RGB/RGBA color support
- **🧮 Comprehensive**: Complete set of vector operations for game dev, graphics, and physics
- **🌳 Tree-Shakeable**: Import only what you need with the functional API

## 📦 Installation

```bash
npm install @fimbul-works/vec
```

## 🚀 Quick Start

### Functional API (Recommended)

The **functional API** uses array tuples and is recommended for new projects:

```typescript
// Import the functional API
import { add2D, magnitude2D, dot2D, normalize2D } from "@fimbul-works/vec/2d";
import { add3D, cross3D } from "@fimbul-works/vec/3d";

// Type: ArrayVector2D = [number, number]
const position: ArrayVector2D = [100, 200];
const velocity: ArrayVector2D = [5, 10];

// Immutable operations return new arrays
const newPosition = add2D(position, velocity); // [105, 210]
const speed = magnitude2D(velocity); // 11.18...

// 3D operations
const v1: ArrayVector3D = [1, 2, 3];
const v2: ArrayVector3D = [4, 5, 6];
const sum = add3D(v1, v2); // [5, 7, 9]
const cross = cross3D(v1, v2); // [-3, 6, -3]

// Chain operations functionally
const result = normalize2D(add2D(position, velocity));
```

**Benefits of the Functional API:**
- ✅ Immutable - data never changes unexpectedly
- ✅ Tree-shakeable - smaller bundles
- ✅ Simple - just functions and arrays
- ✅ Pattern-matching ready - works with destructuring

### OOP API (Legacy)

The **OOP API** uses mutable classes and is maintained for backward compatibility:

```typescript
import { Vec2, Vec3, Vec4 } from "@fimbul-works/vec";

// Create and manipulate vectors
const position = new Vec2(100, 200);
const velocity = new Vec2(5, 10);

position.add(velocity); // Mutates position

// Method chaining
const result = new Vec3(1, 0, 0)
  .rotateY(Math.PI / 4)
  .scale(2)
  .normalize();

// 3D graphics with homogeneous coordinates
const point = new Vec4(x, y, z, 1);    // Point in 3D space
const vector = new Vec4(dx, dy, dz, 0); // Direction in 3D space

// Color manipulation with RGB accessors
const color = new Vec3(0.8, 0.2, 0.4);
color.r = 1.0; // Set red component
```

## 📖 API Documentation

Complete API documentation generated by TypeDoc:

### Functional API
- **[2D Vector Functions](./docs/ArrayVector2D.md)** - Complete 2D functional API reference
- **[3D Vector Functions](./docs/ArrayVector3D.md)** - Complete 3D functional API reference
- **[4D Vector Functions](./docs/ArrayVector4D.md)** - Complete 4D functional API reference
- **[Spherical Interpolation Functions](./docs/Slerp.md)** - Spherical Interpolation API reference

### OOP API (Legacy)
- **[Vec2 Class](./docs/Vec2.md)** - Complete Vec2 class documentation
- **[Vec3 Class](./docs/Vec3.md)** - Complete Vec3 class documentation
- **[Vec4 Class](./docs/Vec4.md)** - Complete Vec4 class documentation

## 🎯 Common Operations

### Functional API Examples

```typescript
import {
  add2D, subtract2D, multiply2D, divide2D,
  dot2D, cross2D,
  magnitude2D, normalize2D, negate2D,
  distance2D, distanceManhattan2D, distanceChebyshev2D,
  lerp2D, clamp2D, limitMax2D, limitMin2D,
  rotate2D, reflect2D, project2D,
  angleBetween2D, angleX2D, angleY2D
} from "@fimbul-works/vec/2d";

// Vector arithmetic
const v1: ArrayVector2D = [3, 4];
const v2: ArrayVector2D = [1, 2];

add2D(v1, v2);        // [4, 6]  - Addition
subtract2D(v1, v2);   // [2, 2]  - Subtraction
multiply2D(v1, v2);   // [3, 8]  - Component-wise multiplication
divide2D(v1, v2);     // [3, 2]  - Component-wise division

// Products
dot2D(v1, v2);        // 11      - Dot product
cross2D(v1, v2);      // 2       - 2D cross product (returns scalar)

// Magnitude & normalization
magnitude2D(v1);      // 5       - Vector length
normalize2D(v1);     // [0.6, 0.8] - Unit vector
negate2D(v1);        // [-3, -4] - Opposite direction

// Distance metrics
distance2D(v1, v2);           // 3.606  - Euclidean distance
distanceManhattan2D(v1, v2);   // 4      - Manhattan distance
distanceChebyshev2D(v1, v2);   // 2      - Chebyshev distance

// Interpolation & clamping
lerp2D(v1, v2, 0.5);  // [2, 3]  - Linear interpolation
clamp2D(v1, 2, 8);     // Keeps magnitude between 2 and 8
limitMax2D(v1, 3);     // Limits magnitude to maximum of 3
limitMin2D(v1, 6);     // Ensures magnitude is at least 6

// Rotation & reflection
rotate2D(v1, Math.PI / 2);  // [-4, 3] - Rotate 90°
reflect2D(v1, v2);          // Reflection

// Angles
angleBetween2D(v1, v2);  // Angle between vectors in radians
angleX2D(v1);            // Angle with x-axis
```

### Homogeneous Coordinates (4D)

```typescript
// 3D point: w = 1
const point: ArrayVector4D = [x, y, z, 1];

// 3D direction: w = 0
const direction: ArrayVector4D = [dx, dy, dz, 0];
```

## 🔄 Migration from OOP to Functional

Migrating from the OOP API to the functional API is straightforward:

| OOP (Vec2) | Functional (2D) |
|-----------|-----------------|
| `new Vec2(x, y)` | `[x, y]` as `ArrayVector2D` |
| `Vec2.add(v1, v2)` | `add2D(v1, v2)` |
| `v1.add(v2)` | `add2D(v1, v2)` |
| `v.x` | `v[0]` |
| `v.y` | `v[1]` |
| `v.magnitude` | `magnitude2D(v)` |
| `v.normalize()` | `normalize2D(v)` |

**Key differences:**
- Functional API is **immutable** - returns new arrays instead of mutating
- Uses **array indexing** `[0], [1]` instead of properties `.x, .y`
- Functions are **standalone** instead of class methods

## 📦 Import Paths

```typescript
// Functional API (Recommended)
import { add2D } from "@fimbul-works/vec/2d";
import { add3D } from "@fimbul-works/vec/3d";
import { add4D } from "@fimbul-works/vec/4d";

// OOP API (Legacy)
import { Vec2 } from "@fimbul-works/vec/vec2";
import { Vec3 } from "@fimbul-works/vec/vec3";
import { Vec4 } from "@fimbul-works/vec/vec4";

// Types
import type { ArrayVector2D } from "@fimbul-works/vec/2d";
import type { ArrayVector3D } from "@fimbul-works/vec/3d";
import type { ArrayVector4D } from "@fimbul-works/vec/4d";
```

## 📄 License

MIT License - See [LICENSE](LICENSE) file for details.

---

Built with ⚡ by [FimbulWorks](https://github.com/fimbul-works)
