`Gg`

Basic types for computer graphics.

`Gg`

defines types and functions for floats, vectors, points, matrices, quaternions, sizes, axis aligned boxes, colors, color profiles, linear bigarrays and raster data.

Consult the basics.

Open the module to use it, this defines only modules and types in your scope.

`module Float : sig ... end`

Floating point number utilities.

An n-dimensional *vector* `v`

is a sequence of n, zero indexed, floating point *components*. We write `v`

_{i} the ith component of a vector.

The matrix types are defined here so that they can be used in vector modules; their modules are here.

`module type V = sig ... end`

Implemented by all vector types.

`module V2 : sig ... end`

2D vectors.

`module V3 : sig ... end`

3D vectors.

`module V4 : sig ... end`

4D vectors.

An n-dimensional *point* `p`

is a vector of the corresponding dimension. The components of the vector are the point's *coordinates*.

`type p2 = v2`

The type for 2D points.

`type p3 = v3`

The type for 3D points.

`module type P = sig ... end`

Implemented by all point types.

`module P2 : sig ... end`

2D points.

`module P3 : sig ... end`

3D points.

Unit quaternions represent rotations in 3D space. They allow to smoothly interpolate between orientations. A quaternion is a 4D vector, whose components `x`

, `y`

, `z`

, `w`

represents the quaternion `x`

i+ `y`

j + `z`

k + `w`

.

`type quat = v4`

The type for quaternions.

`module Quat : sig ... end`

Quaternions.

An *m*x*n* matrix `a`

is an array of *m* rows and *n* columns of floating point *elements*. We write `a`

_{ij} the element of `a`

located at the ith row and jth column.

Matrix constructors specify matrix elements in row-major order so that matrix definitions look mathematically natural with proper code indentation. However elements are *stored* and *iterated* over in column-major order.

`module type M = sig ... end`

Implemented by all (square) matrix types.

`module M2 : sig ... end`

2D square matrices.

`module M3 : sig ... end`

3D square matrices.

`module M4 : sig ... end`

4D square matrices.

An n-dimensional *size* `s`

represents extents in n-dimensional space.

`type size2 = v2`

The type for sizes in 2D space.

`type size3 = v3`

The type for sizes in 3D space.

`module type Size = sig ... end`

Implemented by all size types.

`module Size1 : sig ... end`

Sizes in 1D space.

`module Size2 : sig ... end`

Sizes in 2D space.

`module Size3 : sig ... end`

Sizes in 3D spaces.

An n-dimensional axis-aligned box `b`

is defined by an n-dimensional point `o`

, its *origin*, and an n-dimensional size `s`

. Operations on boxes with negative sizes are undefined.

The space S(`b`

) spanned by `b`

is [`o`

_{0}; `o`

_{0} + `s`

_{0}] x ... x [`o`

_{n-1}; `o`

_{n-1} + `s`

_{n-1}]. The extremum points of this space are the box's *corners*. There is a distinguished n-dimensional `empty`

box such that S(`empty`

) is empty.

The type for 1D axis-aligned boxes (closed intervals).

The type for 2D axis-aligned boxes (rectangles).

The type for 3D axis-aligned boxes (cuboids).

`module type Box = sig ... end`

Implemented by all axis-aligned box types.

`module Box1 : sig ... end`

1D axis-aligned boxes.

`module Box2 : sig ... end`

2D axis-aligned boxes.

`module Box3 : sig ... end`

3D axis-aligned boxes.

`module Color : sig ... end`

Colors and color profiles.

The type for linear bigarrays.

`type buffer = [ `

`| `Int8 of (int, Bigarray.int8_signed_elt) bigarray`

`| `Int16 of (int, Bigarray.int16_signed_elt) bigarray`

`| `Int32 of (int32, Bigarray.int32_elt) bigarray`

`| `Int64 of (int64, Bigarray.int64_elt) bigarray`

`| `UInt8 of (int, Bigarray.int8_unsigned_elt) bigarray`

`| `UInt16 of (int, Bigarray.int16_unsigned_elt) bigarray`

`| `UInt32 of (int32, Bigarray.int32_elt) bigarray`

`| `UInt64 of (int64, Bigarray.int64_elt) bigarray`

`| `Float16 of (int, Bigarray.int16_unsigned_elt) bigarray`

`| `Float32 of (float, Bigarray.float32_elt) bigarray`

`| `Float64 of (float, Bigarray.float64_elt) bigarray`

` ]`

The type for linear bigarray buffers.

`module Ba : sig ... end`

Linear bigarrays and bigarray buffers.

`module Raster : sig ... end`

Raster data.

`Gg`

is designed to be opened in your module. This defines only types and modules in your scope, no values. Thus to use `Gg`

start with :

`open Gg`

In the toplevel enter:

`> #require "gg.top";;`

to automatically open `Gg`

and install printers for the types.

Most types and their functions are defined with the following conventions. The type is first defined in `Gg`

, like `v2`

for 2D vectors, a module for it follows. The name of the module is the type name capitalized, e.g. `V2`

for 2D vectors and it has the following definitions:

- a type
`t`

equal to the original toplevel type (`V2.t`

). `dim`

, an`int`

value that indicates the dimensionality of the type (`V2.dim`

).`v`

, a constructor for the type (`V2.v`

).`pp`

to convert values to a textual representation for debugging purposes and toplevel interaction`V2.pp`

).`equal`

and`compare`

the standard functions that make a module a good functor argument (`V2.equal`

,`V2.compare`

).`equal_f`

and`compare_f`

which compare like`equal`

and`compare`

but allow to use a client provided function to compare floats (`V2.equal_f`

,`V2.compare_f`

).`ltr`

and`tr`

to apply linear and affine transforms on the type (`V2.ltr`

,`V2.tr`

).- Other accessors (e.g.
`V2.x`

), constants (e.g.`V2.zero`

), functions (e.g.`V2.dot`

) and predicates (e.g.`V2.exists`

) specific to the type. - Modules that represent the same object but for different dimensions, like
`V2`

,`V3`

,`V4`

for vectors, usually share a common signature. This common signature is collected in a module type defined in`Gg`

, this signature is`V`

for vectors.

Some types are defined as simple abreviations. For example the type `p2`

for 2D points is equal to `v2`

. These types also have a module whose name is the type name capitalized, `P2`

in our example. However this module only provides alternate constructors, constants and accessors and the extended functionality specific to the type. You should fallback on the module of the abreviated type (`V2`

in our example) for other operations. The aim of these types is to make your code and signatures semantically clearer without the burden of explicit conversions.

Finally there are some types and modules like `Color`

whose structure is different because they provide specific functionality.

Here are a few other conventions :

- Numbers in names indicate dimensionality. For example
`M4.scale3`

indicates scale in 3D space while`M4.scale4`

scale in 4D space. - Most functions take the value they act upon first. But exceptions abound, to match OCaml conventions, to have your curry or to match mathematical notation (e.g.
`V2.tr`

). - Conversion functions follow the
`of_`

conventions. Thus to convert a value of type`t'`

to a value of type`t`

look for the function named`T.of_t'`

.

To conclude note that it is sometimes hard to find the right place for a function. If you cannot find a function look into each of the modules of the types you want to act upon.

- In 3D space we assume a right-handed coordinate system.
- Angles are always given in radians (except in this function...).
- In 2D space positive angles determine counter clockwise rotations.
- In 3D space positive angles determine rotations directed according to the right hand rule.

Values of type `color`

are in a *linear* sRGB space as this is the space to work in if you want to process colors correctly (e.g. for blending). The constructor `Color.v_srgb`

takes its parameters from a *non-linear* sRGB space and converts them to *linear* sRGB.

```
# let c = Color.v_srgb 0.5 0.5 0.5 1.0;;
- : Gg.color = (0.214041 0.214041 0.214041 1)
```

This is the constructor you are likely to use when you specify color constants (e.g. to specify a color value matching a CSS color). If you need an sRGB color back from a `color`

value use `Color.to_srgb`

:

```
# Color.to_srgba c;;
- : Gg.Color.srgba = (0.5 0.5 0.5 1)
```

- Everything is tail-recursive.
- Do not rely on the output of printer functions, they are subject to change. The only exception is the function
`Float.pp`

that output a lossless textual representation of floats. While the actual format is subject to change it will remain compatible with`float_of_string`

. - All modules can be directly given as arguments to
`Set.Make`

and`Map.Make`

. However this will use`Stdlib.compare`

and thus binary comparison between floats. Depending on the intended use this may be sensible or not. Comparisons with alternate functions to compare floats can be defined by using the functions named`compare_f`

(e.g.`V2.compare_f`

). An alternate float comparison function is`Float.compare_tol`

that combines relative and absolute float comparison in a single test, see`Float.equal_tol`

for the details. - For performance reasons some functions of the
`Float`

module are undefined on certain arguments but do not raise`Invalid_argument`

on those. As usual do not rely on the behaviour of functions on undefined arguments, these are subject to change.