Skip to content

Commit 14046f0

Browse files
author
Andy Ferris
committed
Deprecate transform(), replace with call.
1 parent 9d93999 commit 14046f0

File tree

9 files changed

+168
-175
lines changed

9 files changed

+168
-175
lines changed

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ networks of coordinate system transformations. Transformations can be easily
77
applied, inverted, composed, and differentiated (both with respect to the
88
input coordinates and with respect to transformation parameters such as rotation
99
angle). Transformations are designed to be light-weight and efficient enough
10-
for, e.g., real-time graphical applications, while support for both explicit
10+
for, e.g., real-time graphical applications, while support for both explicit
1111
and automatic differentiation makes it easy to perform optimization and
1212
therefore ideal for computer vision applications such as SLAM (simultaneous
1313
localization and mapping).
1414

1515
The package provide two main pieces of functionality
1616

1717
1. Primarily, an interface for defining `Transformation`s and applying
18-
(`transform()`), inverting (`inv()`), composing (`` or `compose()`) and
18+
(by calling), inverting (`inv()`), composing (`` or `compose()`) and
1919
differentiating (`transform_deriv()` and `transform_deriv_params()`) them.
2020

2121
2. A small set of built-in, composable, primitive transformations for
@@ -29,27 +29,27 @@ Let's rotate a 2D point:
2929
x = Point(1.0, 2.0) # Point is provided by FixedSizeArrays
3030
rot = Rotation2D(0.3) # a rotation by 0.3 radians anticlockwise about the origin
3131

32-
y = transform(rot, x)
32+
y = rot(x)
3333
```
3434

3535
We can either apply transformations in turn,
3636
```julia
3737
trans = Translation(3.5, 1.5)
3838

39-
z = transform(trans, transform(rot, x))
39+
z = trans(rot(x))
4040
```
4141
or build a composed transformation:
4242
```julia
4343
composed = trans rot # or compose(trans, rot)
4444

45-
transform(composed, x) == z
45+
composed(x) == z
4646
```
4747

4848
We can invert it:
4949
```julia
5050
composed_inv = inv(composed)
5151

52-
transform(composed_inv, z) == x
52+
composed_inv(z) == x
5353
```
5454

5555
Finally, we can construct a matrix describing how the components of `z`

REQUIRE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
julia 0.4
2+
Compat
23
FixedSizeArrays 0.2.2
34
Rotations

src/CoordinateTransformations.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module CoordinateTransformations
22

3+
using Compat
34
using FixedSizeArrays
45
export Point # Use Point{N, T} from FixedSizedArrays for Cartesian frames
56

src/commontransformations.jl

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ Translation(x,y) = Translation(Vec(x,y))
1616
Translation(x,y,z) = Translation(Vec(x,y,z))
1717
Base.show(io::IO, trans::Translation) = print(io, "Translation$((trans.dx...))")
1818

19-
function transform(trans::Translation, x)
19+
@compat function (trans::Translation)(x)
2020
x + trans.dx
2121
end
2222

23-
transform(trans::Translation, x::Tuple) = Tuple(Vec(x) + trans.dx)
23+
@compat (trans::Translation)(x::Tuple) = Tuple(Vec(x) + trans.dx)
2424

2525
Base.inv(trans::Translation) = Translation(-trans.dx)
2626

@@ -60,28 +60,28 @@ function Rotation2D(a)
6060
end
6161

6262
# A variety of specializations for all occassions!
63-
function transform(trans::Rotation2D, x::FixedVector{2})
63+
@compat function (trans::Rotation2D)(x::FixedVector{2})
6464
(sincos, x2) = promote(Vec(trans.sin, trans.cos), x)
6565
(typeof(x2))(x[1]*sincos[2] - x[2]*sincos[1], x[1]*sincos[1] + x[2]*sincos[2])
6666
end
6767

68-
transform(trans::Rotation2D, x::NTuple{2}) = (x[1]*trans.cos - x[2]*trans.sin, x[1]*trans.sin + x[2]*trans.cos)
69-
transform{T1,T2}(trans::Rotation2D{T1}, x::Vector{T2}) = [x[1]*trans.cos - x[2]*trans.sin, x[1]*trans.sin + x[2]*trans.cos]
68+
@compat (trans::Rotation2D)(x::NTuple{2}) = (x[1]*trans.cos - x[2]*trans.sin, x[1]*trans.sin + x[2]*trans.cos)
69+
@compat (trans::Rotation2D{T1}){T1,T2}(x::Vector{T2}) = [x[1]*trans.cos - x[2]*trans.sin, x[1]*trans.sin + x[2]*trans.cos]
7070

7171
# E.g. for ArrayFire, this might work better than the below?
72-
function transform{T1,T2}(trans::Rotation2D{T1}, x::AbstractVector{T2})
72+
@compat function (trans::Rotation2D{T1}){T1,T2}(x::AbstractVector{T2})
7373
out = similar(x, promote_type(T1,T2))
7474
out[1] = x[1]*trans.cos - x[2]*trans.sin
7575
out[2] = x[1]*trans.sin + x[2]*trans.cos
7676
return out
7777
end
7878

79-
function transform(trans::Rotation2D, x)
79+
@compat function (trans::Rotation2D)(x)
8080
[ trans.cos -trans.sin;
8181
trans.sin trans.cos ] * x
8282
end
8383

84-
function transform(trans::Rotation2D, x::Polar)
84+
@compat function (trans::Rotation2D)(x::Polar)
8585
Polar(x.r, x.θ + trans.angle)
8686
end
8787

@@ -163,16 +163,16 @@ Base.isapprox(a::Rotation, b::Rotation; kwargs...) = isapprox(a.matrix, b.matrix
163163
Base.isapprox{T}(a::Rotation{T}, b::Rotation{T}; kwargs...) = isapprox(a.matrix, b.matrix; kwargs...) && isapprox(a.rotation, b.rotation; kwargs...)
164164
Base.isapprox(a::Rotation{Void}, b::Rotation{Void}; kwargs...) = isapprox(a.matrix, b.matrix; kwargs...)
165165

166-
function transform(trans::Rotation, x)
166+
@compat function (trans::Rotation)(x)
167167
trans.matrix * x
168168
end
169169

170-
function transform(trans::Rotation, x::FixedVector{3})
170+
@compat function (trans::Rotation)(x::FixedVector{3})
171171
(m, x2) = promote(trans.matrix, x)
172172
(typeof(x2))(m * Vec(x2))
173173
end
174174

175-
transform(trans::Rotation, x::Tuple) = Tuple(transform(trans, Vec(x)))
175+
@compat (trans::Rotation)(x::Tuple) = Tuple(trans(Vec(x)))
176176

177177
transform_deriv(trans::Rotation, x) = trans.matrix # It's a linear transformation, so this is easy!
178178

@@ -323,13 +323,13 @@ Base.show(io::IO, r::RotationYZ) = print(io, "RotationYZ($(r.angle))")
323323
Base.show(io::IO, r::RotationZX) = print(io, "RotationZX($(r.angle))")
324324

325325
# It's a little fiddly to support all possible point container types, but this should do a good majority of them!
326-
transform(trans::RotationXY, x::Vector) = [x[1]*trans.cos - x[2]*trans.sin, x[1]*trans.sin + x[2]*trans.cos, x[3]]
327-
transform(trans::RotationXY, x::NTuple{3}) = (x[1]*trans.cos - x[2]*trans.sin, x[1]*trans.sin + x[2]*trans.cos, x[3])
328-
function transform(trans::RotationXY, x::FixedVector{3})
326+
@compat (trans::RotationXY)(x::Vector) = [x[1]*trans.cos - x[2]*trans.sin, x[1]*trans.sin + x[2]*trans.cos, x[3]]
327+
@compat (trans::RotationXY)(x::NTuple{3}) = (x[1]*trans.cos - x[2]*trans.sin, x[1]*trans.sin + x[2]*trans.cos, x[3])
328+
@compat function (trans::RotationXY)(x::FixedVector{3})
329329
(sincos, x2) = promote(Vec(trans.sin, trans.cos), x)
330330
(typeof(x2))(x[1]*sincos[2] - x[2]*sincos[1], x[1]*sincos[1] + x[2]*sincos[2], x2[3])
331331
end
332-
function transform{T}(trans::RotationXY{T}, x)
332+
@compat function (trans::RotationXY{T}){T}(x)
333333
Z = zero(T)
334334
I = one(T)
335335

@@ -338,13 +338,13 @@ function transform{T}(trans::RotationXY{T}, x)
338338
Z Z I ] * x
339339
end
340340

341-
transform(trans::RotationYZ, x::Vector) = [x[1], x[2]*trans.cos - x[3]*trans.sin, x[2]*trans.sin + x[3]*trans.cos]
342-
transform(trans::RotationYZ, x::NTuple{3}) = (x[1], x[2]*trans.cos - x[3]*trans.sin, x[2]*trans.sin + x[3]*trans.cos)
343-
function transform(trans::RotationYZ, x::FixedVector{3})
341+
@compat (trans::RotationYZ)(x::Vector) = [x[1], x[2]*trans.cos - x[3]*trans.sin, x[2]*trans.sin + x[3]*trans.cos]
342+
@compat (trans::RotationYZ)(x::NTuple{3}) = (x[1], x[2]*trans.cos - x[3]*trans.sin, x[2]*trans.sin + x[3]*trans.cos)
343+
@compat function (trans::RotationYZ)(x::FixedVector{3})
344344
(sincos, x2) = promote(Vec(trans.sin, trans.cos), x)
345345
(typeof(x2))(x2[1], x[2]*sincos[2] - x[3]*sincos[1], x[2]*sincos[1] + x[3]*sincos[2])
346346
end
347-
function transform{T}(trans::RotationYZ{T}, x)
347+
@compat function (trans::RotationYZ{T}){T}(x)
348348
Z = zero(T)
349349
I = one(T)
350350

@@ -353,13 +353,13 @@ function transform{T}(trans::RotationYZ{T}, x)
353353
Z trans.sin trans.cos] * x
354354
end
355355

356-
transform(trans::RotationZX, x::Vector) = [x[3]*trans.sin + x[1]*trans.cos, x[2], x[3]*trans.cos - x[1]*trans.sin]
357-
transform(trans::RotationZX, x::NTuple{3}) = (x[3]*trans.sin + x[1]*trans.cos, x[2], x[3]*trans.cos - x[1]*trans.sin)
358-
function transform(trans::RotationZX, x::FixedVector{3})
356+
@compat (trans::RotationZX)(x::Vector) = [x[3]*trans.sin + x[1]*trans.cos, x[2], x[3]*trans.cos - x[1]*trans.sin]
357+
@compat (trans::RotationZX)(x::NTuple{3}) = (x[3]*trans.sin + x[1]*trans.cos, x[2], x[3]*trans.cos - x[1]*trans.sin)
358+
@compat function (trans::RotationZX)(x::FixedVector{3})
359359
(sincos, x2) = promote(Vec(trans.sin, trans.cos), x)
360360
(typeof(x2))(x[3]*sincos[1] + x[1]*sincos[2], x2[2], x[3]*sincos[2] - x[1]*sincos[1])
361361
end
362-
function transform{T}(trans::RotationZX{T}, x)
362+
@compat function (trans::RotationZX{T}){T}(x)
363363
Z = zero(T)
364364
I = one(T)
365365

src/coordinatesystems.jl

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ immutable CartesianFromPolar <: Transformation; end
2121
Base.show(io::IO, trans::PolarFromCartesian) = print(io, "PolarFromCartesian()")
2222
Base.show(io::IO, trans::CartesianFromPolar) = print(io, "CartesianFromPolar()")
2323

24-
function transform(::PolarFromCartesian, x)
24+
@compat function (::PolarFromCartesian)(x)
2525
length(x) == 2 || error("Polar transform takes a 2D coordinate")
2626

2727
Polar(sqrt(x[1]*x[1] + x[2]*x[2]), atan2(x[2], x[1]))
@@ -38,7 +38,7 @@ function transform_deriv(::PolarFromCartesian, x)
3838
end
3939
transform_deriv_params(::PolarFromCartesian, x) = error("PolarFromCartesian has no parameters")
4040

41-
function transform(::CartesianFromPolar, x::Polar)
41+
@compat function (::CartesianFromPolar)(x::Polar)
4242
Point(x.r * cos(x.θ), x.r * sin(x.θ))
4343
end
4444
function transform_deriv(::CartesianFromPolar, x::Polar)
@@ -105,7 +105,7 @@ Base.show(io::IO, trans::CylindricalFromSpherical) = print(io, "CylindricalFromS
105105
Base.show(io::IO, trans::SphericalFromCylindrical) = print(io, "SphericalFromCylindrical()")
106106

107107
# Cartesian <-> Spherical
108-
function transform(::SphericalFromCartesian, x)
108+
@compat function (::SphericalFromCartesian)(x)
109109
length(x) == 3 || error("Spherical transform takes a 3D coordinate")
110110

111111
Spherical(sqrt(x[1]*x[1] + x[2]*x[2] + x[3]*x[3]), atan2(x[2],x[1]), atan(x[3]/sqrt(x[1]*x[1] + x[2]*x[2])))
@@ -126,7 +126,7 @@ function transform_deriv(::SphericalFromCartesian, x)
126126
end
127127
transform_deriv_params(::SphericalFromCartesian, x) = error("SphericalFromCartesian has no parameters")
128128

129-
function transform(::CartesianFromSpherical, x::Spherical)
129+
@compat function (::CartesianFromSpherical)(x::Spherical)
130130
Point(x.r * cos(x.θ) * cos(x.ϕ), x.r * sin(x.θ) * cos(x.ϕ), x.r * sin(x.ϕ))
131131
end
132132
function transform_deriv{T}(::CartesianFromSpherical, x::Spherical{T})
@@ -142,7 +142,7 @@ end
142142
transform_deriv_params(::CartesianFromSpherical, x::Spherical) = error("CartesianFromSpherical has no parameters")
143143

144144
# Cartesian <-> Cylindrical
145-
function transform(::CylindricalFromCartesian, x)
145+
@compat function (::CylindricalFromCartesian)(x)
146146
length(x) == 3 || error("Cylindrical transform takes a 3D coordinate")
147147

148148
Cylindrical(sqrt(x[1]*x[1] + x[2]*x[2]), atan2(x[2],x[1]), x[3])
@@ -161,7 +161,7 @@ function transform_deriv(::CylindricalFromCartesian, x)
161161
end
162162
transform_deriv_params(::CylindricalFromCartesian, x) = error("CylindricalFromCartesian has no parameters")
163163

164-
function transform(::CartesianFromCylindrical, x::Cylindrical)
164+
@compat function (::CartesianFromCylindrical)(x::Cylindrical)
165165
Point(x.r * cos(x.θ), x.r * sin(x.θ), x.z)
166166
end
167167
function transform_deriv{T}(::CartesianFromCylindrical, x::Cylindrical{T})
@@ -174,21 +174,21 @@ end
174174
transform_deriv_params(::CartesianFromPolar, x::Cylindrical) = error("CartesianFromCylindrical has no parameters")
175175

176176
# Spherical <-> Cylindrical (TODO direct would be faster)
177-
function transform(::CylindricalFromSpherical, x::Spherical)
178-
transform(CylindricalFromCartesian() , transform(CartesianFromSpherical(), x))
177+
@compat function (::CylindricalFromSpherical)(x::Spherical)
178+
CylindricalFromCartesian()(CartesianFromSpherical()(x))
179179
end
180180
function transform_deriv(::CylindricalFromSpherical, x::Spherical)
181-
M1 = transform_deriv(CylindricalFromCartesian(), transform(CartesianFromSpherical(), x))
181+
M1 = transform_deriv(CylindricalFromCartesian(), CartesianFromSpherical()(x))
182182
M2 = transform_deriv(CartesianFromSpherical(), x)
183183
return M1*M2
184184
end
185185
transform_deriv_params(::CylindricalFromSpherical, x::Spherical) = error("CylindricalFromSpherical has no parameters")
186186

187-
function transform(::SphericalFromCylindrical, x::Cylindrical)
188-
transform(SphericalFromCartesian() , transform(CartesianFromCylindrical(), x))
187+
@compat function (::SphericalFromCylindrical)(x::Cylindrical)
188+
SphericalFromCartesian()(CartesianFromCylindrical()(x))
189189
end
190190
function transform_deriv(::SphericalFromCylindrical, x::Cylindrical)
191-
M1 = transform_deriv(SphericalFromCartesian(), transform(CartesianFromCylindrical(), x))
191+
M1 = transform_deriv(SphericalFromCartesian(), CartesianFromCylindrical()(x))
192192
M2 = transform_deriv(CartesianFromCylindrical(), x)
193193
return M1*M2
194194
end

src/core.jl

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,21 @@
88
"""
99
The `Transformation` supertype defines a simple interface for performing
1010
transformations. Subtypes should be able to apply a coordinate system
11-
transformation on the correct data types by overloading `transform()`, and
11+
transformation on the correct data types by overloading the call method, and
1212
usually would have the corresponding inverse transformation defined by `Base.inv()`.
1313
Efficient compositions can optionally be defined by `compose()` (equivalently `∘`).
1414
"""
1515
abstract Transformation
1616

17+
Base.@deprecate transform(transformation::Transformation, x) transformation(x)
18+
1719
"""
1820
The `IdentityTransformation` is a singleton `Transformation` that returns the
1921
input unchanged, similar to `identity`.
2022
"""
2123
immutable IdentityTransformation <: Transformation; end
2224

23-
"""
24-
transform(trans::Transformation, x)
25-
26-
A transformation `trans` is explicitly applied to data x, returning the
27-
coordinates in the new coordinate system.
28-
"""
29-
function transform(trans::Transformation, x)
30-
error("The transform of datatype $(typeof(x)) is not defined for transformation $trans.")
31-
end
32-
33-
@inline transform(::IdentityTransformation, x) = x
34-
25+
@compat @inline (::IdentityTransformation)(x) = x
3526

3627
"""
3728
A `ComposedTransformation` simply executes two transformations successively, and
@@ -44,8 +35,8 @@ end
4435

4536
Base.show(io::IO, trans::ComposedTransformation) = print(io, "($(trans.t1)$(trans.t2))")
4637

47-
@inline function transform(trans::ComposedTransformation, x)
48-
transform(trans.t1, transform(trans.t2, x))
38+
@compat @inline function (trans::ComposedTransformation)(x)
39+
trans.t1(trans.t2(x))
4940
end
5041

5142
"""
@@ -66,7 +57,7 @@ compose(trans::IdentityTransformation, ::IdentityTransformation) = trans
6657
compose(::IdentityTransformation, trans::Transformation) = trans
6758
compose(trans::Transformation, ::IdentityTransformation) = trans
6859

69-
const = compose
60+
const = compose # TODO watch JuliaLang/julia#17184 and #17155 for v0.5 compatibility
7061

7162

7263
"""
@@ -93,7 +84,7 @@ transform_deriv(::Transformation, x) = error("Differential matrix of transform $
9384
transform_deriv(::IdentityTransformation, x) = I
9485

9586
function transform_deriv(trans::ComposedTransformation, x)
96-
x2 = transform(trans.t2, x)
87+
x2 = trans.t2(x)
9788
m1 = transform_deriv(trans.t1, x2)
9889
m2 = transform_deriv(trans.t2, x)
9990
return m1 * m2
@@ -111,7 +102,7 @@ transform_deriv(::Transformation, x) = error("Differential matrix of parameters
111102
transform_deriv_params(::IdentityTransformation, x) = error("IdentityTransformation has no parameters")
112103

113104
function transform_deriv_params(trans::ComposedTransformation, x)
114-
x2 = transform(trans.t2, x)
105+
x2 = trans.t2(x)
115106
m1 = transform_deriv(trans.t1, x2)
116107
p2 = transform_deriv_params(trans.t2, x)
117108
p1 = transform_deriv_params(trans.t1, x2)

0 commit comments

Comments
 (0)