1
+ """
2
+ Quaternion{T<:Real} <: Number
3
+
4
+ Quaternion number type with real and imaginary parts of type `T`.
5
+
6
+ `QuaternionF16`, `QuaternionF32`, and `QuaternionF64` are aliases for
7
+ `Quaternion{Float16}`, `Quaternion{Float32}`, and `Quaternion{Float64}`, respectively.
8
+
9
+ See also: [`quat`](@ref), [`real`](@ref), [`imag_part`](@ref).
10
+ """
1
11
struct Quaternion{T<: Real } <: Number
2
12
s:: T
3
13
v1:: T
@@ -18,25 +28,116 @@ Quaternion(s::Real, v1::Real, v2::Real, v3::Real, n::Bool = false) =
18
28
Quaternion (x:: Real ) = Quaternion (x, zero (x), zero (x), zero (x), abs (x) == one (x))
19
29
Quaternion (z:: Complex ) = Quaternion (z. re, z. im, zero (z. re), zero (z. re), abs (z) == one (z. re))
20
30
Quaternion (s:: Real , a:: AbstractVector ) = Quaternion (s, a[1 ], a[2 ], a[3 ])
21
- Quaternion (a:: AbstractVector ) = Quaternion (0 , a[1 ], a[2 ], a[3 ])
31
+ function Quaternion (a:: AbstractVector )
32
+ Base. depwarn (" `Quaternion(::AbstractVector)` is deprecated and will be removed in the next breaking release (v0.7.0). Please use Quaternion(0, a[1], a[2], a[3]) instead." , :Quaternion )
33
+ Quaternion (0 , a[1 ], a[2 ], a[3 ])
34
+ end
22
35
23
36
Base. promote_rule (:: Type{Quaternion{T}} , :: Type{S} ) where {T <: Real , S <: Real } = Quaternion{promote_type (T, S)}
24
37
Base. promote_rule (:: Type{Quaternion{T}} , :: Type{Complex{S}} ) where {T <: Real , S <: Real } = Quaternion{promote_type (T, S)}
25
38
Base. promote_rule (:: Type{Quaternion{T}} , :: Type{Quaternion{S}} ) where {T <: Real , S <: Real } = Quaternion{promote_type (T, S)}
26
39
40
+ """
41
+ quat(r, [i, j, k])
42
+
43
+ Convert real numbers or arrays to quaternion. `i, j, k` defaults to zero.
44
+
45
+ # Examples
46
+ ```jldoctest
47
+ julia> quat(7)
48
+ Quaternion{Int64}(7, 0, 0, 0, false)
49
+
50
+ julia> quat(1.0, 2, 3, 4)
51
+ QuaternionF64(1.0, 2.0, 3.0, 4.0, false)
52
+
53
+ julia> quat([1, 2, 3]) # This output will be changed in the next breaking release for consistency. (#94)
54
+ Quaternion{Int64}(0, 1, 2, 3, false)
55
+ ```
56
+ """
57
+ quat
58
+
27
59
quat (p, v1, v2, v3) = Quaternion (p, v1, v2, v3)
28
60
quat (p, v1, v2, v3, n) = Quaternion (p, v1, v2, v3, n)
29
61
quat (x) = Quaternion (x)
30
62
quat (s, a) = Quaternion (s, a)
31
63
64
+ """
65
+ real(T::Type{<:Quaternion})
66
+
67
+ Return the type that represents the real part of a value of type `T`.
68
+ e.g: for `T == Quaternion{R}`, returns `R`.
69
+ Equivalent to `typeof(real(zero(T)))`.
70
+
71
+ # Examples
72
+ ```jldoctest
73
+ julia> real(Quaternion{Int})
74
+ Int64
75
+ ```
76
+ """
32
77
Base. real (:: Type{Quaternion{T}} ) where {T} = T
78
+
79
+ """
80
+ real(q::Quaternion)
81
+
82
+ Return the real part of the quaternion `q`.
83
+
84
+ See also: [`imag_part`](@ref), [`quat`](@ref)
85
+
86
+ # Examples
87
+ ```jldoctest
88
+ julia> real(quat(1,2,3,4))
89
+ 1
90
+ ```
91
+ """
33
92
Base. real (q:: Quaternion ) = q. s
93
+
94
+ """
95
+ real(A::AbstractArray{<:Quaternion})
96
+
97
+ Return an array containing the real part of each quaternion in `A`.
98
+
99
+ # Examples
100
+ ```jldoctest
101
+ julia> real([quat(5,6,7,8), 9])
102
+ 2-element Vector{Int64}:
103
+ 5
104
+ 9
105
+ ```
106
+ """
107
+ Base. real (:: AbstractArray{<:Quaternion} )
108
+
109
+ """
110
+ imag_part(q::Quaternion{T}) -> NTuple{3, T}
111
+
112
+ Return the imaginary part of the quaternion `q`.
113
+
114
+ Note that this function is different from `Base.imag`, which returns `Real` for complex numbers.
115
+
116
+ See also: [`real`](@ref), [`conj`](@ref).
117
+
118
+ # Examples
119
+ ```jldoctest
120
+ julia> imag_part(Quaternion(1,2,3,4))
121
+ (2, 3, 4)
122
+ ```
123
+ """
34
124
imag_part (q:: Quaternion ) = (q. v1, q. v2, q. v3)
35
125
36
126
Base.:/ (q:: Quaternion , x:: Real ) = Quaternion (q. s / x, q. v1 / x, q. v2 / x, q. v3 / x)
37
127
Base.:* (q:: Quaternion , x:: Real ) = Quaternion (q. s * x, q. v1 * x, q. v2 * x, q. v3 * x)
38
128
Base.:* (x:: Real , q:: Quaternion ) = q * x
39
129
130
+ """
131
+ conj(q::Quaternion)
132
+
133
+ Compute the quaternion conjugate of a quaternion `q`.
134
+
135
+ # Examples
136
+ ```jldoctest
137
+ julia> conj(Quaternion(1,2,3,4))
138
+ Quaternion{Int64}(1, -2, -3, -4, false)
139
+ ```
140
+ """
40
141
Base. conj (q:: Quaternion ) = Quaternion (q. s, - q. v1, - q. v2, - q. v3, q. norm)
41
142
Base. abs (q:: Quaternion ) = sqrt (abs2 (q))
42
143
Base. float (q:: Quaternion{T} ) where T = convert (Quaternion{float (T)}, q)
@@ -127,9 +228,9 @@ is the extension of `f` to the quaternions, where ``z = a + s i`` is a complex a
127
228
128
229
See Theorem 5 of [^Sudbery1970] for details.
129
230
130
- [^Sudbery1970]
231
+ [^Sudbery1970]:
131
232
Sudbery (1979). Quaternionic analysis. Mathematical Proceedings of the Cambridge
132
- Philosophical Society,85, pp 199225
233
+ Philosophical Society,85, pp 199225
133
234
doi:[10.1017/S030500410005563](https://doi.org/10.1017/S0305004100055638)
134
235
"""
135
236
function extend_analytic (f, q:: Quaternion )
@@ -284,6 +385,29 @@ function rotationmatrix_normalized(q::Quaternion)
284
385
xz - sy yz + sx 1 - (xx + yy)]
285
386
end
286
387
388
+ """
389
+ slerp(qa::Quaternion, qb::Quaternion, t::Real)
390
+
391
+ Spherical linear interpolation (Slerp) between the inputs `qa` and `qb`.
392
+ Since the input is normalized inside the function, the absolute value of the return value will be 1.
393
+
394
+ # Examples
395
+ ```jldoctest
396
+ julia> using Quaternions
397
+
398
+ julia> qa = Quaternion(1,0,0,0)
399
+ Quaternion{Int64}(1, 0, 0, 0, false)
400
+
401
+ julia> qb = Quaternion(0,1,0,0)
402
+ Quaternion{Int64}(0, 1, 0, 0, false)
403
+
404
+ julia> slerp(qa, qb, 0.6)
405
+ QuaternionF64(0.5877852522924731, 0.8090169943749475, 0.0, 0.0, true)
406
+
407
+ julia> ans ≈ Quaternion(cospi(0.3), sinpi(0.3), 0, 0)
408
+ true
409
+ ```
410
+ """
287
411
@inline function slerp (qa0:: Quaternion{T} , qb0:: Quaternion{T} , t:: T ) where T<: Real
288
412
# http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
289
413
iszero (qa0) && throw (DomainError (qa0, " The input quaternion must be non-zero." ))
0 commit comments