@@ -181,72 +181,26 @@ extension Quaternion/*: ElementaryFunctions */ {
181
181
182
182
@inlinable
183
183
public static func cos( _ q: Quaternion ) -> Quaternion {
184
- // Mathematically, this operation can be expanded in terms of
185
- // trigonometric `Real` operations as follows (`let θ = ||v||`):
186
- //
187
- // ```
188
- // cos(r + v) = (exp(q * (v/θ)) + exp(-q * (v/θ))) / 2
189
- // = cos(r) cosh(θ) - (v/θ) sin(r) sinh(θ)
190
- // ```
191
- guard q. isFinite else { return q }
192
- let ( â, θ) = q. imaginary. unitAxisAndLength
193
- guard θ. magnitude < - RealType. log ( . ulpOfOne) else {
194
- let rotation = Quaternion ( halfAngle: q. real, unitAxis: â)
195
- let firstScale = RealType . exp ( θ. magnitude/ 2 )
196
- let secondScale = firstScale/ 2
197
- return rotation. multiplied ( by: firstScale) . multiplied ( by: secondScale)
198
- }
199
- return Quaternion (
200
- real: . cosh( θ) * . cos( q. real) ,
201
- imaginary: - â * . sinh( θ) * . sin( q. real)
202
- )
184
+ // cos(q) = cosh(q * (v/θ)))
185
+ let ( â, _) = q. imaginary. unitAxisAndLength
186
+ let p = Quaternion ( imaginary: â)
187
+ return cosh ( q * p)
203
188
}
204
189
205
190
@inlinable
206
191
public static func sin( _ q: Quaternion ) -> Quaternion {
207
- // Mathematically, this operation can be expanded in terms of
208
- // trigonometric `Real` operations as follows (`let θ = ||v||`):
209
- //
210
- // ```
211
- // sin(r + v) = -((exp(q * (v/θ)) - exp(-q * (v/θ))) (v/θ * 2)
212
- // = sin(r) cosh(θ) + (v/θ) cos(r) sinh(θ)
213
- // ```
214
- guard q. isFinite else { return q }
215
- let ( â, θ) = q. imaginary. unitAxisAndLength
216
- guard θ. magnitude < - RealType. log ( . ulpOfOne) else {
217
- let rotation = Quaternion ( halfAngle: q. real, unitAxis: â)
218
- let firstScale = RealType . exp ( θ. magnitude/ 2 )
219
- let secondScale = RealType ( signOf: θ, magnitudeOf: firstScale/ 2 )
220
- return rotation. multiplied ( by: firstScale) . multiplied ( by: secondScale)
221
- }
222
- return Quaternion (
223
- real: . cosh( θ) * . sin( q. real) ,
224
- imaginary: â * . sinh( θ) * . cos( q. real)
225
- )
192
+ // sin(q) = -(v/θ) * sinh(q * (v/θ)))
193
+ let ( â, _) = q. imaginary. unitAxisAndLength
194
+ let p = Quaternion ( imaginary: â)
195
+ return - p * sinh( q * p)
226
196
}
227
197
228
198
@inlinable
229
199
public static func tan( _ q: Quaternion ) -> Quaternion {
230
- // Mathematically, this operation can be expanded in terms of
231
- // trigonometric `Real` operations as follows (`let θ = ||v||`):
232
- //
233
- // ```
234
- // tan(q) = sin(q) / cos(q)
235
- // ```
236
- guard q. isFinite else { return q }
237
- // Note that when |θ| is larger than -log(.ulpOfOne),
238
- // sin(r + v) == ±cos(r + v), so tan(r + v) is just ±1.
239
- guard q. imaginary. length. magnitude < - RealType. log ( . ulpOfOne) else {
240
- let r = RealType ( signOf: q. components. w, magnitudeOf: 1 )
241
- return Quaternion (
242
- real: r,
243
- imaginary:
244
- RealType ( signOf: q. components. x, magnitudeOf: 0 ) ,
245
- RealType ( signOf: q. components. y, magnitudeOf: 0 ) ,
246
- RealType ( signOf: q. components. z, magnitudeOf: 0 )
247
- ) . multiplied ( by: r)
248
- }
249
- return sin ( q) / cos( q)
200
+ // tan(q) = -(v/θ) * tanh(q * (v/θ)))
201
+ let ( â, _) = q. imaginary. unitAxisAndLength
202
+ let p = Quaternion ( imaginary: â)
203
+ return - p * tanh( q * p)
250
204
}
251
205
252
206
// MARK: - log-like functions
0 commit comments