Skip to content

Commit c5d24f9

Browse files
authored
Merge pull request #95 from abhro/doc-deploy
Deploy documentation
2 parents a0b7026 + 73f365c commit c5d24f9

File tree

9 files changed

+343
-44
lines changed

9 files changed

+343
-44
lines changed

.github/workflows/ci.yml

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,20 @@ jobs:
3333
env:
3434
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
3535

36-
# Enable the below for Documenter build
37-
# docs:
38-
# name: Documentation
39-
# runs-on: ubuntu-latest
40-
# steps:
41-
# - uses: actions/checkout@v1
42-
# - uses: julia-actions/setup-julia@latest
43-
# with:
44-
# version: '1.3'
45-
# - run: julia --project=docs -e '
46-
# using Pkg;
47-
# Pkg.develop(PackageSpec(; path=pwd()));
48-
# Pkg.instantiate();'
49-
# - run: julia --project=docs docs/make.jl
50-
# env:
51-
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
52-
# # Needed due to https://github.com/JuliaDocs/Documenter.jl/issues/1177
53-
# DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
36+
docs:
37+
name: Documentation
38+
runs-on: ubuntu-latest
39+
steps:
40+
- uses: actions/checkout@v1
41+
- uses: julia-actions/setup-julia@latest
42+
with:
43+
version: '1'
44+
- uses: julia-actions/cache@v1
45+
- name: Install dependencies
46+
run: julia --project=docs -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate();'
47+
- name: Build and deploy
48+
env:
49+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
50+
# Needed due to https://github.com/JuliaDocs/Documenter.jl/issues/1177
51+
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
52+
run: julia --project=docs docs/make.jl

docs/make.jl

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
1-
using Documenter
21
using CoordinateTransformations
2+
using Documenter
3+
using Documenter.Remotes: GitHub
4+
5+
DocMeta.setdocmeta!(
6+
CoordinateTransformations,
7+
:DocTestSetup,
8+
:(using CoordinateTransformations),
9+
recursive = true,
10+
)
311

412
makedocs(
513
sitename = "CoordinateTransformations.jl",
14+
modules = [CoordinateTransformations],
15+
repo = GitHub("JuliaGeometry/CoordinateTransformations.jl"),
616
pages = [
717
"Introduction" => "index.md",
818
"API" => "api.md",
919
],
1020
)
21+
22+
deploydocs(
23+
repo = "github.com/JuliaGeometry/CoordinateTransformations.jl.git"
24+
)

docs/src/api.md

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,47 @@
1-
# CoordinateTransformations.jl documentation
1+
# API Reference
22

3-
## API Reference
3+
## Transformations
4+
```@docs
5+
Transformation
6+
CoordinateTransformations.ComposedTransformation
7+
IdentityTransformation
8+
PerspectiveMap
9+
inv
10+
cameramap
11+
compose
12+
recenter
13+
transform_deriv
14+
transform_deriv_params
15+
```
16+
17+
## Affine maps
18+
```@docs
19+
AbstractAffineMap
20+
AffineMap
21+
AffineMap(::Transformation, ::Any)
22+
AffineMap(::Pair)
23+
LinearMap
24+
Translation
25+
```
26+
27+
## 2D Coordinates
28+
```@docs
29+
Polar
30+
PolarFromCartesian
31+
CartesianFromPolar
32+
```
33+
34+
## 3D Coordinates
35+
```@docs
36+
Cylindrical
37+
Spherical
38+
```
439

5-
```@autodocs
6-
Modules = [CoordinateTransformations]
40+
```@docs
41+
CartesianFromCylindrical
42+
CartesianFromSpherical
43+
CylindricalFromCartesian
44+
CylindricalFromSpherical
45+
SphericalFromCartesian
46+
SphericalFromCylindrical
747
```

docs/src/index.md

Lines changed: 219 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,219 @@
1-
# CoordinateTransformations.jl
1+
```@meta
2+
DocTestSetup = quote
3+
using CoordinateTransformations
4+
end
5+
```
6+
# CoordinateTransformations
7+
8+
[![Build Status](https://github.com/JuliaGeometry/CoordinateTransformations.jl/workflows/CI/badge.svg)](https://github.com/JuliaGeometry/CoordinateTransformations.jl/actions?query=workflow%3ACI)
9+
10+
**CoordinateTransformations** is a Julia package to manage simple or complex
11+
networks of coordinate system transformations. Transformations can be easily
12+
applied, inverted, composed, and differentiated (both with respect to the
13+
input coordinates and with respect to transformation parameters such as rotation
14+
angle). Transformations are designed to be light-weight and efficient enough
15+
for, e.g., real-time graphical applications, while support for both explicit
16+
and automatic differentiation makes it easy to perform optimization and
17+
therefore ideal for computer vision applications such as SLAM (simultaneous
18+
localization and mapping).
19+
20+
The package provide two main pieces of functionality
21+
22+
1. Primarily, an interface for defining `Transformation`s and applying
23+
(by calling), inverting (`inv()`), composing (`` or `compose()`) and
24+
differentiating (`transform_deriv()` and `transform_deriv_params()`) them.
25+
26+
2. A small set of built-in, composable, primitive transformations for
27+
transforming 2D and 3D points (optionally leveraging the *StaticArrays*
28+
and *Rotations* packages).
29+
30+
## Quick start
31+
32+
Let's translate a 3D point:
33+
```julia
34+
using CoordinateTransformations, Rotations, StaticArrays
35+
36+
x = SVector(1.0, 2.0, 3.0) # SVector is provided by StaticArrays.jl
37+
trans = Translation(3.5, 1.5, 0.0)
38+
39+
y = trans(x)
40+
```
41+
42+
We can either apply different transformations in turn,
43+
```julia
44+
rot = LinearMap(RotX(0.3)) # Rotate 0.3 radians about X-axis, from Rotations.jl
45+
46+
z = trans(rot(x))
47+
```
48+
or build a composed transformation using the `` operator (accessible at the
49+
REPL by typing `\circ` then tab):
50+
```julia
51+
composed = trans rot # alternatively, use compose(trans, rot)
52+
53+
composed(x) == z
54+
```
55+
A composition of a `Translation` and a `LinearMap` results in an `AffineMap`.
56+
57+
We can invert the transformation:
58+
```julia
59+
composed_inv = inv(composed)
60+
61+
composed_inv(z) == x
62+
```
63+
64+
For any transformation, we can shift the origin to a new point using `recenter`:
65+
```julia
66+
rot_around_x = recenter(rot, x)
67+
```
68+
Now `rot_around_x` is a rotation around the point `x = SVector(1.0, 2.0, 3.0)`.
69+
70+
71+
Finally, we can construct a matrix describing how the components of `z`
72+
differentiates with respect to components of `x`:
73+
```julia
74+
# In general, the transform may be non-linear, and thus we require
75+
# the value of x to compute the derivative
76+
∂z_∂x = transform_deriv(composed, x)
77+
```
78+
79+
Or perhaps we want to know how `y` will change with respect to changes of
80+
to the translation parameters:
81+
```julia
82+
∂y_∂θ = transform_deriv_params(trans, x)
83+
```
84+
85+
## Interface
86+
87+
Transformations are derived from `Transformation`. As an example, we have
88+
`Translation{T} <: Transformation`. A `Translation` will accept and translate
89+
points in a variety of formats, such as `Vector` or `SVector`, but in general
90+
your custom-defined `Transformation`s could transform any Julia object.
91+
92+
Transformations can be reversed using `inv(trans)`. They can be chained
93+
together using the `` operator (`trans1 ∘ trans2`) or `compose` function (`compose(trans1, trans2)`).
94+
In this case, `trans2` is applied first to the data, before `trans1`.
95+
Composition may be intelligent, for instance by precomputing a new `Translation`
96+
by summing the elements of two existing `Translation`s, and yet other
97+
transformations may compose to the `IdentityTransformation`. But by default,
98+
composition will result in a `ComposedTransformation` object which simply
99+
dispatches to apply the transformations in the correct order.
100+
101+
Finally, the matrix describing how differentials propagate through a transform
102+
can be calculated with the `transform_deriv(trans, x)` method. The derivatives
103+
of how the output depends on the transformation parameters is accessed via
104+
`transform_deriv_params(trans, x)`. Users currently have to overload these methods,
105+
as no fall-back automatic differentiation is currently included. Alternatively,
106+
all the built-in types and transformations are compatible with automatic differentiation
107+
techniques, and can be parameterized by *DualNumbers*' `DualNumber` or *ForwardDiff*'s `Dual`.
108+
109+
## Built-in transformations
110+
111+
A small number of 2D and 3D coordinate systems and transformations are included.
112+
We also have `IdentityTransformation` and `ComposedTransformation`, which allows us
113+
to nest together arbitrary transformations to create a complex yet efficient
114+
transformation chain.
115+
116+
### Coordinate types
117+
118+
The package accepts any `AbstractVector` type for Cartesian coordinates. For speed, we recommend
119+
using a statically-sized container such as `SVector{N}` from *StaticArrays*.
120+
121+
We do provide a few specialist coordinate types. The `Polar(r, θ)` type is a 2D
122+
polar representation of a point, and similarly in 3D we have defined
123+
`Spherical(r, θ, ϕ)` and `Cylindrical(r, θ, z)`.
124+
125+
### Coordinate system transformations
126+
127+
Two-dimensional coordinates may be converted using these parameterless (singleton)
128+
transformations:
129+
130+
1. [`PolarFromCartesian()`](@ref)
131+
2. [`CartesianFromPolar()`](@ref)
132+
133+
Three-dimensional coordinates may be converted using these parameterless
134+
transformations:
135+
136+
1. [`SphericalFromCartesian()`](@ref)
137+
2. [`CartesianFromSpherical()`](@ref)
138+
3. [`SphericalFromCylindrical()`](@ref)
139+
4. [`CylindricalFromSpherical()`](@ref)
140+
5. [`CartesianFromCylindrical()`](@ref)
141+
6. [`CylindricalFromCartesian()`](@ref)
142+
143+
However, you may find it simpler to use the convenience constructors like
144+
`Polar(SVector(1.0, 2.0))`.
145+
146+
### Translations
147+
148+
Translations can be be applied to Cartesian coordinates in arbitrary dimensions,
149+
by e.g. `Translation(Δx, Δy)` or `Translation(Δx, Δy, Δz)` in 2D/3D, or by
150+
`Translation(Δv)` in general (with `Δv` an `AbstractVector`). Compositions of
151+
two `Translation`s will intelligently create a new `Translation` by adding the
152+
translation vectors.
153+
154+
### Linear transformations
155+
156+
Linear transformations (a.k.a. linear maps), including rotations, can be
157+
encapsulated in the `LinearMap` type, which is a simple wrapper of an
158+
`AbstractMatrix`.
159+
160+
You are able to provide any matrix of your choosing, but your choice of type
161+
will have a large effect on speed. For instance, if you know the dimensionality
162+
of your points (e.g. 2D or 3D) you might consider a statically sized matrix
163+
like `SMatrix` from *StaticArrays.jl*. We recommend performing 3D rotations
164+
using those from *Rotations.jl* for their speed and flexibility. Scaling will
165+
be efficient with Julia's built-in `UniformScaling`. Also note that compositions
166+
of two `LinearMap`s will intelligently create a new `LinearMap` by multiplying
167+
the transformation matrices.
168+
169+
### Affine maps
170+
171+
An Affine map encapsulates a more general set of transformation which are
172+
defined by a composition of a translation and a linear transformation. An
173+
`AffineMap` is constructed from an `AbstractVector` translation `v` and an
174+
`AbstractMatrix` linear transformation `M`. It will perform the mapping
175+
`x -> M*x + v`, but the order of addition and multiplication will be more obvious
176+
(and controllable) if you construct it from a composition of a linear map
177+
and a translation, e.g. `Translation(v) ∘ LinearMap(v)` (or any combination of
178+
`LinearMap`, `Translation` and `AffineMap`).
179+
180+
`AffineMap`s can be constructed to fit point pairs `from_points => to_points`:
181+
182+
```jldoctest
183+
julia> from_points = [[0, 0], [1, 0], [0, 1]];
184+
185+
julia> to_points = [[1, 1], [3, 1], [1.5, 3]];
186+
187+
julia> AffineMap(from_points => to_points)
188+
AffineMap([1.9999999999999996 0.5; -5.551115123125783e-16 2.0], [0.9999999999999999, 1.0000000000000002])
189+
```
190+
191+
The points can be supplied as a collection of vectors or as a matrix with points as columns.
192+
193+
### Perspective transformations
194+
195+
The perspective transformation maps real-space coordinates to those on a virtual
196+
"screen" of one lesser dimension. For instance, this process is used to render
197+
3D scenes to 2D images in computer generated graphics and games. It is an ideal
198+
model of how a pinhole camera operates and is a good approximation of the modern
199+
photography process.
200+
201+
The `PerspectiveMap()` command creates a `Transformation` to perform the
202+
projective mapping. It can be applied individually, but is particularly
203+
powerful when composed with an `AffineMap` containing the position and
204+
orientation of the camera in your scene. For example, to transfer `points` in 3D
205+
space to 2D `screen_points` giving their projected locations on a virtual camera
206+
image, you might use the following code:
207+
208+
```julia
209+
cam_transform = PerspectiveMap() inv(AffineMap(cam_rotation, cam_position))
210+
screen_points = map(cam_transform, points)
211+
```
212+
213+
There is also a `cameramap()` convenience function that can create a composed
214+
transformation that includes the intrinsic scaling (e.g. focal length and pixel
215+
size) and offset (defining which pixel is labeled `(0,0)`) of an imaging system.
216+
217+
## Acknowledgements
218+
219+
- The [Fugro Roames organization](https://github.com/FugroRoames)

src/affine.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
"""
2+
abstract type AbstractAffineMap <: Transformation
3+
4+
`AbstractAffineMap` is the supertype of all affine transformations,
5+
including linear transformations.
6+
"""
17
abstract type AbstractAffineMap <: Transformation end
28

39
"""
@@ -114,7 +120,7 @@ end
114120
"""
115121
AffineMap(trans::Transformation, x0)
116122
117-
Create an Affine transformation corresponding to the differential transformation
123+
Create an affine transformation corresponding to the differential transformation
118124
of `x0 + dx` according to `trans`, i.e. the Affine transformation that is
119125
locally most accurate in the vicinity of `x0`.
120126
"""

0 commit comments

Comments
 (0)