# purescript-transformation-matrix

Spatial matrix transformations for 4x4 affine matrices used in 3D graphics.

## Purpose

My goal is to build a pure functional set of libraries to perform the heavy lifting of creating, transforming, and interacting with 3D objects. The results of these operations can then be passed to a lightweight WebGL renderer (threejs or other) that is used only for display purposes. The `purescript-transformation-matrix`

library will be the linear algebraic component of this set of libraries. The manipulation of geometries, materials, and meshes will be a separate library.

## Why not just use three.js?

While this project is heavily inspired by threejs I have found my self frustrated with threejs for several reasons. Here are a few of those reasons:

- Linear alegbraic operations are scattered across class inheritance structures making it difficult to find and reason about.
- Pure mathematical logic is tightly coupled with threejs specific object logic.
- Vectors and matrices are modified in place making it hard to keep track of modifications to their values.
- Source code lacks types.

I believe that investing in a homegrown, pure functional, 3D graphics library is worth the time and effort and hope that you think so too! Code contributions are always welcome :)

## Advantages

In the context of threejs, this library:

- Provides a direct API for linear algebraic operations used in 3D graphics
- Does not tighly couple linear alebraic operations with higher order 3D graphic data types
- Is not a FFI wrapper over threejs [1] [2] [3]

In the context of existing Purescript matrix libraries, this library:

- Is specific to the matrix operations and dimensions used in 3D graphics (spatial/affine transformations, 4x4 matrices, 3x1 vectors)
- Is not a general purpose matrix algebra library [1] [2]
- Is runtime safe and does not use unsafe functions [1] [2]
- Is not reliant on the user to make sure that their matrix functions are passed matrices of compatible dimensions

## Examples

### Translate

```
import Data.TransformationMatrix.Matrix4
( Matrix4(..)
, translate )
matrix = Matrix4
1.0 0.0 0.0 1.0
0.0 1.0 0.0 2.0
0.0 0.0 1.0 3.0
0.0 0.0 0.0 1.0
translation = Vector3 2.0 3.0 4.0
result = translate translation matrix
-- result == Matrix4
-- 1.0 0.0 0.0 3.0
-- 0.0 1.0 0.0 5.0
-- 0.0 0.0 1.0 7.0
-- 0.0 0.0 0.0 1.0
```

### Scale

```
import Data.TransformationMatrix.Matrix4
( Matrix4(..)
, scale )
matrix = Matrix4
1.0 0.0 0.0 1.0
0.0 1.0 0.0 2.0
0.0 0.0 1.0 3.0
0.0 0.0 0.0 1.0
multiplier = 2.0
result = scale multiplier matrix
-- result == Matrix4
-- 2.0 0.0 0.0 1.0
-- 0.0 2.0 0.0 2.0
-- 0.0 0.0 2.0 3.0
-- 0.0 0.0 0.0 1.0
```