1
- abstract AbstractAffineTransformation <: Transformation
2
- abstract AbstractLinearTransformation <: AbstractAffineTransformation
1
+ """
2
+ abstract AbstractAffineTransformation <: Transformation
3
3
4
- # Helper to compute a zeroed input point for an affine transformation
5
- # FIXME : deal with general input dimension and type.
6
- zeroed_input (trans:: AbstractAffineTransformation ) = Vec (0 ,0 ,0 )
4
+ Provides an interface for implementing Affine transformations of Cartesian
5
+ coordinates. To implement an AbstractAffineTransformation, you must define
7
6
8
- # transform_deriv for AbstractAffineTransformation is independent of the point
9
- # about which we're linearizing.
10
- function transform_deriv (trans:: AbstractAffineTransformation )
11
- transform_deriv (trans, zeroed_input (trans))
12
- end
7
+ matrix(trans)
8
+ translation(trans)
13
9
10
+ where the resulting transformation is (equivalent to)
14
11
15
- # -------------------------------------------------------------------------------
16
- # Linear Transformations
12
+ trans(x) -> matrix(trans) * x + translation(trans)
17
13
18
- """
19
- LinearTransformation <: AbstractLinearTransformation
14
+ Specific implementations may provide equivalent specializations of `call`, etc,
15
+ for optimization purposes. The function `translation_reverse()` is provided,
16
+ such that
20
17
21
- A general linear transformation, constructed using `LinearTransformation(M)`
22
- for any matrix `M`. Other abstract linear transformations can be converted
23
- into a general linear transformation using `LinearTransformation(trans)`
18
+ trans(x) -> matrix(trans) * (x + translation_reverse(trans))
19
+
20
+ (See also AffineTransformation, AbstractLinearTransformation, Translation)
24
21
"""
25
- immutable LinearTransformation{MatrixT} <: AbstractLinearTransformation
26
- M:: MatrixT
22
+ abstract AbstractAffineTransformation <: Transformation
23
+
24
+ matrix (:: AbstractAffineTransform ) = error (" AbstractAffineTransformation's must implement matrix()" )
25
+ translation (:: AbstractAffineTransform ) = error (" AbstractAffineTransformation's must implement translation()" )
26
+ translation_reverse (:: AbstractAffineTransformation ) = matrix (trans) \ translation (trans)
27
+
28
+ # Default implementations
29
+ @compat function (trans:: AbstractAffineTransformation )(x)
30
+ matrix (trans) * x + translation (trans)
27
31
end
28
32
29
- LinearTransformation (trans:: LinearTransformation ) = trans
33
+ transform_deriv (trans:: AbstractAffineTransformation ) = matrix (trans)
34
+
35
+ # Could try do similar for transform_deriv_params()?
30
36
31
- function LinearTransformation (trans:: AbstractLinearTransformation )
32
- LinearTransformation ( transform_deriv ( trans, zeroed_input (trans)) )
37
+ @compat function (trans:: AbstractAffineTransformation )(x )
38
+ matrix ( trans) * x + translation (x )
33
39
end
34
40
35
- Base. show (io:: IO , trans:: LinearTransformation ) = print (io, " LinearTransformation($(trans. M) )" )
41
+ function Base. inv (trans:: AbstractAffineTransformation )
42
+ Minv = inv (matrix (trans))
43
+ AffineTransformation (Minv, - Minv * translation (trans))
44
+ end
36
45
37
- @compat function (trans :: LinearTransformation )(x )
38
- trans . M * x
46
+ function compose (t1 :: AbstractAffineTransformation , t2 :: AbstractAffineTransformation )
47
+ AffineTransformation ( matrix (t1) * matrix (t2), translation (t1) + matrix (t1) * translation (t2))
39
48
end
40
49
41
- Base. inv (trans:: LinearTransformation ) = LinearTransformation (inv (trans. M))
42
50
43
- compose (t1:: LinearTransformation , t2:: LinearTransformation ) = LinearTransformation (t1. M* t2. M)
51
+ """
52
+ abstract AbstractLinearTransformation <: AbstractAffineTransformation
53
+
54
+ Provides an interface for implementing linear transformations of Cartesian
55
+ coordinates. To implement an AbstractLinearTransformation, you must define
56
+
57
+ matrix(trans)
58
+
59
+ where the resulting transformation is (equivalent to)
60
+
61
+ trans(x) -> matrix(trans) * x
44
62
45
- transform_deriv (trans:: LinearTransformation , x) = trans. M
63
+ Specific implementations may provide equivalent specializations of `call`, etc,
64
+ for optimization purposes.
46
65
66
+ (See also LinearTransformation, AbstractAffineTransformation)
67
+ """
68
+ abstract AbstractLinearTransformation <: AbstractAffineTransformation
47
69
48
- function compose (t1:: AbstractLinearTransformation , t2:: AbstractLinearTransformation )
49
- LinearTransformation (t1) ∘ LinearTransformation (t2)
70
+ matrix (:: AbstractLinearTransformation ) = error (" AbstractLinearTransformation's must implement matrix()" )
71
+ @inline translation (:: AbstractLinearTransformation ) = 0 # Does this make sense?
72
+ @inline translation_reverse (:: AbstractLinearTransformation ) = 0
73
+
74
+ # Default implementations
75
+ @compat function (trans:: AbstractLinearTransformation )(x)
76
+ matrix (trans) * x
50
77
end
51
78
79
+ # transform_deriv() provided by AbstractAffineTransformation
80
+
81
+ Base. inv (trans:: AbstractLinearTransformation ) = LinearTransformation (inv (matrix (trans))
82
+
83
+ compose (t1:: AbstractLinearTransformation , t2:: AbstractLinearTransformation ) = LinearTransformation (matrix (t1) * matrix (t2))
84
+
85
+
86
+ """
87
+ LinearTransformation <: AbstractLinearTransformation
88
+
89
+ A general linear transformation, constructed using `LinearTransformation(M)`
90
+ for any matrix-like object `M`. Other abstract linear transformations can be
91
+ converted into a general linear transformation using `LinearTransformation(trans)`
92
+ """
93
+ immutable LinearTransformation{MatrixT} <: AbstractLinearTransformation
94
+ M:: MatrixT
95
+ end
96
+
97
+ LinearTransformation (trans:: AbstractLinearTransformation ) = LinearTransformation (matrix (trans))
98
+
99
+ Base. show (io:: IO , trans:: LinearTransformation ) = print (io, " LinearTransformation($(trans. M) )" ) # TODO make this output more petite
100
+
101
+ @inline matrix (trans:: LinearTransformation ) = trans. M
102
+
52
103
53
- # -------------------------------------------------------------------------------
54
- # General Affine Transformations
55
104
"""
56
105
AffineTransformation <: AbstractAffineTransformation
57
106
58
- A concrete affine transformation. To construct the mapping `v + M*x`, use
107
+ A concrete affine transformation. To construct the mapping `x -> M*x + v `, use
59
108
60
109
AffineTransformation(M, v)
61
110
@@ -72,67 +121,17 @@ immutable AffineTransformation{MatrixT, VectorT} <: AbstractAffineTransformation
72
121
end
73
122
74
123
function AffineTransformation (trans:: AbstractAffineTransformation )
75
- x = zeroed_input (trans)
76
- AffineTransformation (transform_deriv (trans, x), trans (x))
124
+ AffineTransformation (matrix (trans), translation (trans))
77
125
end
78
126
79
- function AffineTransformation (trans:: AbstractLinearTransformation )
80
- x = zeroed_input (trans)
81
- AffineTransformation (transform_deriv (trans, x), x)
82
- end
83
-
84
- function AffineTransformation (trans:: Transformation , x)
127
+ # We can create an Affine transformation corresponding to the differential
128
+ # transformation of x + dx
129
+ function AffineTransformation (trans:: AbstractTransformation , x)
85
130
AffineTransformation (transform_deriv (trans, x), trans (x))
86
131
end
87
132
88
- Base. show (io:: IO , trans:: AffineTransformation ) = print (io, " AffineTransformation($(trans. M) , $(trans. v) )" )
89
-
90
- @compat function (trans:: AffineTransformation )(x)
91
- trans. M* x + trans. v
92
- end
93
-
94
- function Base. inv (trans:: AffineTransformation )
95
- Minv = inv (trans. M)
96
- AffineTransformation (Minv, - Minv* trans. v)
97
- end
133
+ Base. show (io:: IO , trans:: AffineTransformation ) = print (io, " AffineTransformation($(trans. M) , $(trans. v) )" ) # TODO make this output more petite
98
134
99
- function transform_deriv (trans:: AffineTransformation , x)
100
- trans. M
101
- end
102
-
103
- function compose (t1:: AffineTransformation , t2:: AffineTransformation )
104
- AffineTransformation (t1. M* t2. M, t1. v + t1. M* t2. v)
105
- end
106
-
107
- function compose (t1:: AbstractAffineTransformation , t2:: AbstractAffineTransformation )
108
- AffineTransformation (t1) ∘ AffineTransformation (t2)
109
- end
110
-
111
- """
112
- affine_decomposition_T_of_L(trans)
113
-
114
- Decompose an affine transformation into a translation and linear part,
115
- returning `(v,M)` such that
116
-
117
- trans(p) == (Translation(v) ∘ LinearTransformation(M))(p)
118
- """
119
- function affine_decomposition_T_of_L (trans:: AbstractAffineTransformation )
120
- A = AffineTransformation (trans)
121
- (A. v, A. M)
122
- end
123
-
124
- """
125
- affine_decomposition_L_of_T(trans)
126
-
127
- Decompose an affine transformation into a translation and linear part,
128
- returning `(M,v)` such that
129
-
130
- trans(x) == LinearTransformation(M) ∘ Translation(v)
131
- """
132
- function affine_decomposition_L_of_T (trans:: AbstractAffineTransformation )
133
- A = AffineTransformation (trans)
134
- (A. M, A. M\ A. v)
135
- end
136
135
137
136
138
137
# ##################
@@ -153,6 +152,10 @@ Translation(x,y) = Translation(Vec(x,y))
153
152
Translation (x,y,z) = Translation (Vec (x,y,z))
154
153
Base. show (io:: IO , trans:: Translation ) = print (io, " Translation$((trans. dx... )) " )
155
154
155
+ @inline matrix (:: Translation ) = I
156
+ @inline translation (trans:: Translation ) = trans. dx
157
+ @inline translation (trans:: Translation ) = trans. dx
158
+
156
159
@compat function (trans:: Translation )(x)
157
160
x + trans. dx
158
161
end
@@ -165,10 +168,6 @@ function compose(trans1::Translation, trans2::Translation)
165
168
Translation (trans1. dx + trans2. dx)
166
169
end
167
170
168
- function transform_deriv (trans:: Translation , x)
169
- I
170
- end
171
-
172
171
function transform_deriv_params (trans:: Translation , x)
173
172
I
174
173
end
608
607
function euler_rotation (θ₁, θ₂, θ₃, order:: Union{Rotations.EulerXZX, Type{Rotations.EulerXZX}} )
609
608
RotationYZ (θ₁) ∘ RotationXY (θ₂) ∘ RotationYZ (θ₃)
610
609
end
611
-
612
-
0 commit comments