summaryrefslogtreecommitdiff
path: root/bindgen/ocaml/lib/maths.ml
blob: 8810f483157dc59cc55360238f6a0b04b2b10983 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
(** Maths and linear algebra.
    Ideally we should avoid doing large amounts of math computation in OCaml,
    and so exposing more functionality for batch processing via Core is preferred *)

(** Base functions that a 2D Vector must support *)
module type Vector = sig
  type t

  val add : t -> t -> t
  val sub : t -> t -> t
  val scalar_mul : float -> t -> t
  val dot : t -> t -> float
end

(** Functor that takes a module implementing the Vector signature and returns
    a module that implements most vector space operations *)
module VectorSpace (V : Vector) = struct
  include V

  let scalar_div s v = scalar_mul (1. /. s) v
  let neg v = scalar_mul (-1.0) v
  let length_squared v = dot v v
  let length v = sqrt (dot v v)
  let magnitude = length

  let normalize v =
    let len = length v in
    if len > 0.0 then scalar_mul (1.0 /. len) v else v

  let distance u v = sub u v |> length
end

module Vec3Float = struct
  type t = { x : float; y : float; z : float }

  let add u v = { x = u.x +. v.x; y = u.y +. v.y; z = u.z +. v.z }
  let sub u v = { x = u.x -. v.x; y = u.y -. v.y; z = u.z -. v.z }
  let scalar_mul k v = { x = k *. v.x; y = k *. v.y; z = k *. v.z }
  let dot u v = (u.x *. v.x) +. (u.y *. v.y) +. (u.z *. v.z)
end

module Vec3 = VectorSpace (Vec3Float)