Skip to content

Commit e08c2bf

Browse files
author
Andy Ferris
committed
Updated README and LICENSE
1 parent 1bf4248 commit e08c2bf

File tree

2 files changed

+48
-42
lines changed

2 files changed

+48
-42
lines changed

LICENSE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The CoordinateTransformations.jl package is licensed under the MIT "Expat" License:
22

3-
> Copyright (c) 2016: Andy Ferris.
3+
> Copyright (c) 2016: Fugro Roames, Andy Ferris, Chris Foster.
44
>
55
> Permission is hereby granted, free of charge, to any person obtaining
66
> a copy of this software and associated documentation files (the

README.md

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,33 +19,37 @@ The package provide two main pieces of functionality
1919
differentiating (`transform_deriv()` and `transform_deriv_params()`) them.
2020

2121
2. A small set of built-in, composable, primitive transformations for
22-
transforming 2D and 3D points (optionally leveraging the *FixedSizeArrays*
22+
transforming 2D and 3D points (optionally leveraging the *StaticArrays*
2323
and *Rotations* packages).
2424

2525
### Quick start
2626

27-
Let's rotate a 2D point:
27+
Let's translate a 3D point:
2828
```julia
29-
x = Point(1.0, 2.0) # Point is provided by FixedSizeArrays
30-
rot = Rotation2D(0.3) # a rotation by 0.3 radians anticlockwise about the origin
29+
using CoordinateTransformations, Rotations, StaticArrays
3130

32-
y = rot(x)
31+
x = SVector(1.0, 2.0, 3.0) # SVector is provided by StaticArrays.jl
32+
trans = Translation(3.5, 1.5, 0.0)
33+
34+
y = trans(x)
3335
```
3436

35-
We can either apply transformations in turn,
37+
We can either apply different transformations in turn,
3638
```julia
37-
trans = Translation(3.5, 1.5)
39+
rot = LinearMap(RotX(0.3)) # Rotate 0.3 radians about X-axis, from Rotations.jl
3840

3941
z = trans(rot(x))
4042
```
41-
or build a composed transformation:
43+
or build a composed transformation using the `` operator (accessible at the
44+
REPL by typing `\circ` then tab):
4245
```julia
43-
composed = trans rot # or compose(trans, rot)
46+
composed = trans rot # alternatively, use compose(trans, rot)
4447

4548
composed(x) == z
4649
```
50+
A composition of a `Translation` and a `LinearMap` results in an `AffineMap`.
4751

48-
We can invert it:
52+
We can invert the transformation:
4953
```julia
5054
composed_inv = inv(composed)
5155

@@ -67,10 +71,9 @@ rotation angle:
6771
### The interface
6872

6973
Transformations are derived from `Transformation`. As an example, we have
70-
`Translation{T} <: Transformation`. A translation will accept points in a
71-
variety of formats, such as `Vector`, `FixedVector`, `Tuple`, etc, and will try
72-
to return the same type as given (of course, type promotion may occur for the
73-
element type itself).
74+
`Translation{T} <: Transformation`. A `Translation` will accept and translate
75+
points in a variety of formats, such as `Vector` or `SVector`, but in general
76+
your custom-defined `Transformation`s could transform any Julia object.
7477

7578
Transformations can be reversed using `inv(trans)`. They can be chained
7679
together using the `` operator (`trans1 ∘ trans2`) or `compose` function (`compose(trans1, trans2)`).
@@ -130,30 +133,33 @@ transformations:
130133
#### Translations
131134

132135
Translations can be be applied to Cartesian coordinates in arbitrary dimensions,
133-
by e.g. `Translation(Δx, Δy)` or `Translation(Δx, Δy, Δz)` in 2D/3D.
134-
135-
#### Rotations
136-
137-
Rotations in 2D and 3D are treated slightly differently. The `Rotation2D(Δθ)` rotates a
138-
Cartesian point about the origin, while `RotationPolar(Δθ)` rotates a `Polar`
139-
coordinate about the origin.
140-
141-
`Rotation` performs rotations of 3D Cartesian coordinates. Rotations may be
142-
defined simply by their transformation matrix (assumed to be orthogonal),
143-
or via any of the types exported from the *Rotations* package, including
144-
`Quaternion` (originating from the *Quaternions* package), `AngleAxis`,
145-
`EulerAngles`, `ProperEulerAngles` and `SpQuat`. In these latter cases, the
146-
"parameters" differentiated by `transform_deriv_params()` come directly from the
147-
parameterization of the quaternion, Euler angles, etc. **Note:** the derivative
148-
is only guaranteed to be correct in the tangent plane of the constrained variable,
149-
such as normalized quaternions, and optimization techniques should take this
150-
into account as necessary.
151-
152-
Also included are built-in `RotationXY`, `RotationYZ` and `RotationZX` for
153-
rotating about the *z*, *x* and *y* axes, respectively. A helper function for
154-
constructing a composed transformation of Euler angles is
155-
`euler_rotation(θ₁, θ₂, θ₃, [order = EulerZXY])`, where `order` can be any of
156-
*Rotations*' orderings (`EulerXYZ`, etc). The default `EulerZXY` first rotates
157-
around the *y* axis (*z-x* plane) by `θ₃`, then the *x* axis (*y-z* plane) by
158-
`θ₂`, and finally about the *z* axis (*x-y* plane) by `θ₁`, and is therefore
159-
equivalent to `RotationXY(θ₁) ∘ RotationYZ(θ₂) ∘ RotationZX(θ₃)`.
136+
by e.g. `Translation(Δx, Δy)` or `Translation(Δx, Δy, Δz)` in 2D/3D, or by
137+
`Translation(Δv)` in general (with `Δv` an `AbstractVector`). Compositions of
138+
two `Translation`s will intelligently create a new `Translation` by adding the
139+
translation vectors.
140+
141+
#### Linear transformations
142+
143+
Linear transformations (a.k.a. linear maps), including rotations, can be
144+
encapsulated in the `LinearMap` type, which is a simple wrapper of an
145+
`AbstractMatrix`.
146+
147+
You are able to provide any matrix of your choosing, but your choice of type
148+
will have a large effect on speed. For instance, if you know the dimensionality
149+
of your points (e.g. 2D or 3D) you might consider a statically sized matrix
150+
like `SMatrix` from *StaticArrays.jl*. We recommend performing 3D rotations
151+
using those from *Rotations.jl* for their speed and flexibility. Scaling will
152+
be efficient with Julia's built-in `UniformScaling`. Also note that compositions
153+
of two `LinearMap`s will intelligently create a new `LinearMap` by multiplying
154+
the transformation matrices.
155+
156+
#### Affine maps
157+
158+
An Affine map encapsulates a more general set of transformation which are
159+
defined by a composition of a translation and a linear transformation. An
160+
`AffineMap` is constructed from an `AbstractVector` translation `v` and an
161+
`AbstractMatrix` linear transformation `M`. It will perform the mapping
162+
`x -> M*x + v`, but the order of addition and multiplication will be more obvious
163+
(and controllable) if you construct it from a composition of a linear map
164+
and a translation, e.g. `Translation(v) ∘ LinearMap(v)` (or any combination of
165+
`LinearMap`, `Translation` and `AffineMap`).

0 commit comments

Comments
 (0)