-
Notifications
You must be signed in to change notification settings - Fork 54
Expand file tree
/
Copy pathAffineFrames.jl
More file actions
66 lines (41 loc) · 2.21 KB
/
AffineFrames.jl
File metadata and controls
66 lines (41 loc) · 2.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
frame_transformation(a, b, pt::AbstractCoordinatePoint) = frame_transformation(a, b)(pt)
frame_transformation(a, b, pts::AbstractVector{<:AbstractCoordinatePoint}) = frame_transformation(a, b).(pts)
frame_transformation(a, b, v::AbstractCoordinateVector) = frame_transformation(a, b)(v)
frame_transformation(a, b, vs::AbstractVector{<:AbstractCoordinateVector}) = frame_transformation(a, b).(vs)
abstract type AbstractAffineFrame end
struct GlobalAffineFrame <: AbstractAffineFrame end
const global_frame = GlobalAffineFrame()
frame_transformation(::GlobalAffineFrame, ::GlobalAffineFrame) = identity
struct LocalAffineFrame{PT<:AbstractCartesianPoint,LM} <: AbstractAffineFrame
# origin in the global frame
origin::PT
# linear operator (rotation matrix, etc.) in respect to the global frame
linop::LM
end
struct AFTransformLinOpFirst{V<:CartesianVector,LM}
linop::LM
offset::V
end
function (f::AFTransformLinOpFirst)(pt::AbstractCartesianPoint)
cartesian_zero + muladd(f.linop, pt - cartesian_zero, f.offset)
end
(f::AFTransformLinOpFirst)(v::CartesianVector) = f.linop * v
(f::AFTransformLinOpFirst)(pt::CylindricalPoint) = CylindricalPoint(f(CartesianPoint(pt)))
InverseFunctions.inverse(f::AFTransformLinOpFirst) = AFTransformOffsetFirst(-f.offset, inv(f.linop))
struct AFTransformOffsetFirst{V,M}
offset::V
linop::M
end
(f::AFTransformOffsetFirst)(pt::AbstractCartesianPoint) = cartesian_zero + (f.linop * (pt - cartesian_zero + f.offset))
(f::AFTransformOffsetFirst)(v::CartesianVector) = f.linop * v
(f::AFTransformOffsetFirst)(pt::CylindricalPoint) = CylindricalPoint(f(CartesianPoint(pt)))
InverseFunctions.inverse(f::AFTransformOffsetFirst) = AFTransformLinOpFirst(inv(f.linop), -f.offset)
@inline function frame_transformation(frame::LocalAffineFrame, ::GlobalAffineFrame)
return AFTransformLinOpFirst(frame.linop, frame.origin - cartesian_zero)
end
@inline function frame_transformation(::GlobalAffineFrame, frame::LocalAffineFrame)
return AFTransformOffsetFirst(cartesian_zero - frame.origin, inv(frame.linop))
end
function frame_transformation(a::LocalAffineFrame, b::LocalAffineFrame)
return frame_transformation(a, global_frame) ∘ frame_transformation(global_frame, b)
end