{-# LANGUAGE DataKinds                  #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MagicHash                  #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE StandaloneDeriving         #-}
{-# LANGUAGE TypeFamilies               #-}
{-# LANGUAGE TypeInType                 #-}
{-# LANGUAGE UnboxedTuples              #-}
{-# LANGUAGE UndecidableInstances       #-}
{-# LANGUAGE ViewPatterns               #-}
{-# OPTIONS_GHC -fno-warn-orphans       #-}
module Numeric.Quaternion.Internal.QFloat
    ( QFloat, Quater (..)
    ) where

import qualified Control.Monad.ST                     as ST
import           Data.Coerce                          (coerce)
import           Numeric.Basics
import           Numeric.DataFrame.Internal.PrimArray
import qualified Numeric.DataFrame.ST                 as ST
import           Numeric.DataFrame.Type
import           Numeric.Quaternion.Internal
import           Numeric.Vector.Internal

type QFloat = Quater Float

deriving instance PrimBytes (Quater Float)
deriving instance PrimArray Float (Quater Float)

instance Quaternion Float where
    newtype Quater Float = QFloat (Vector Float 4)
    {-# INLINE packQ #-}
    packQ :: Float -> Float -> Float -> Float -> Quater Float
packQ = (Float -> Float -> Float -> Float -> Vector Float 4)
-> Float -> Float -> Float -> Float -> Quater Float
coerce (Float -> Float -> Float -> Float -> Vector Float 4
forall t. Vector4 t => t -> t -> t -> t -> Vector t 4
vec4 :: Float -> Float -> Float -> Float -> Vector Float 4)
    {-# INLINE unpackQ# #-}
    unpackQ# :: Quater Float -> (# Float, Float, Float, Float #)
unpackQ# = (Vector Float 4 -> (# Float, Float, Float, Float #))
-> Quater Float -> (# Float, Float, Float, Float #)
coerce (Vector Float 4 -> (# Float, Float, Float, Float #)
forall t. Vector4 t => Vector t 4 -> (# t, t, t, t #)
unpackV4# :: Vector Float 4 -> (# Float, Float, Float, Float #))
    {-# INLINE fromVecNum #-}
    fromVecNum :: Vector Float 3 -> Float -> Quater Float
fromVecNum (Vector Float 3 -> (# Float, Float, Float #)
forall t. Vector3 t => Vector t 3 -> (# t, t, t #)
unpackV3# -> (# Float
x, Float
y, Float
z #))  = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z
    {-# INLINE fromVec4 #-}
    fromVec4 :: Vector Float 4 -> Quater Float
fromVec4 = Vector Float 4 -> Quater Float
coerce
    {-# INLINE toVec4 #-}
    toVec4 :: Quater Float -> Vector Float 4
toVec4 = Quater Float -> Vector Float 4
coerce
    {-# INLINE square #-}
    square :: Quater Float -> Float
square (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #)) = (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w)
    {-# INLINE im #-}
    im :: Quater Float -> Quater Float
im (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
_ #)) = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z Float
0.0
    {-# INLINE re #-}
    re :: Quater Float -> Quater Float
re (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
_, Float
_, Float
_, Float
w #)) = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
0 Float
0 Float
0 Float
w
    {-# INLINE imVec #-}
    imVec :: Quater Float -> Vector Float 3
imVec (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
_ #)) = Float -> Float -> Float -> Vector Float 3
forall t. Vector3 t => t -> t -> t -> Vector t 3
vec3 Float
x Float
y Float
z
    {-# INLINE taker #-}
    taker :: Quater Float -> Float
taker (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
_, Float
_, Float
_, Float
w #)) = Float
w
    {-# INLINE takei #-}
    takei :: Quater Float -> Float
takei (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
_, Float
_, Float
_ #)) = Float
x
    {-# INLINE takej #-}
    takej :: Quater Float -> Float
takej (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
_, Float
y, Float
_, Float
_ #)) = Float
y
    {-# INLINE takek #-}
    takek :: Quater Float -> Float
takek (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
_, Float
_, Float
z, Float
_ #)) = Float
z
    {-# INLINE conjugate #-}
    conjugate :: Quater Float -> Quater Float
conjugate (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
      = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float -> Float
forall a. Num a => a -> a
negate Float
x) (Float -> Float
forall a. Num a => a -> a
negate Float
y) (Float -> Float
forall a. Num a => a -> a
negate Float
z) Float
w
    {-# INLINE rotScale #-}
    rotScale :: Quater Float -> Vector Float 3 -> Vector Float 3
rotScale (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
i, Float
j, Float
k, Float
t #))
             (Vector Float 3 -> (# Float, Float, Float #)
forall t. Vector3 t => Vector t 3 -> (# t, t, t #)
unpackV3# -> (# Float
x, Float
y, Float
z #))
      = let l :: Float
l = Float
tFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
t Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
iFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
i Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
jFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
j Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
kFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
k
            d :: Float
d = Float
2.0 Float -> Float -> Float
forall a. Num a => a -> a -> a
* ( Float
iFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
jFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
kFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
z)
            t2 :: Float
t2 = Float
t Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
2.0
        in Float -> Float -> Float -> Vector Float 3
forall t. Vector3 t => t -> t -> t -> Vector t 3
vec3 (Float
lFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
dFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
i Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
t2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
zFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
j Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
yFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
k))
                (Float
lFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
dFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
j Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
t2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
xFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
k Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
zFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
i))
                (Float
lFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
dFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
k Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
t2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
yFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
i Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
xFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
j))
    {-# INLINE getRotScale #-}
    getRotScale :: Vector Float 3 -> Vector Float 3 -> Quater Float
getRotScale Vector Float 3
a Vector Float 3
b = case (# Vector Float 3 -> (# Float, Float, Float #)
forall t. Vector3 t => Vector t 3 -> (# t, t, t #)
unpackV3# Vector Float 3
a, Vector Float 3 -> (# Float, Float, Float #)
forall t. Vector3 t => Vector t 3 -> (# t, t, t #)
unpackV3# Vector Float 3
b #) of
      (# (# Float, Float, Float #)
_, (# Float
0, Float
0, Float
0 #) #) -> Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
0 Float
0 Float
0 Float
0
      (# (# Float
0, Float
0, Float
0 #), (# Float, Float, Float #)
_ #) -> let x :: Float
x = (Float
1 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
0 :: Float) in Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
x Float
x Float
x
      (# (# Float
a1, Float
a2, Float
a3 #), (# Float
b1, Float
b2, Float
b3 #) #) ->
        let ma :: Float
ma = Float -> Float
forall a. Floating a => a -> a
sqrt (Float
a1Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
a1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a2Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
a2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a3Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
a3)
            mb :: Float
mb = Float -> Float
forall a. Floating a => a -> a
sqrt (Float
b1Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
b1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
b2Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
b2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
b3Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
b3)
            d :: Float
d  = Float
a1Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
b1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a2Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
b2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a3Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
b3
            c :: Float
c  = Float -> Float
forall a. Floating a => a -> a
sqrt (Float
maFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
mb Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
d)
            ma2 :: Float
ma2 = Float
ma Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
1.4142135623730951 -- sqrt 2.0
            r :: Float
r  = Float -> Float
forall a. Fractional a => a -> a
recip (Float
ma2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c)
            c' :: Float
c' = Float -> Float
forall a. Floating a => a -> a
sqrt (Float
mb Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
ma) -- ratio of a and b for corner cases
            r' :: Float
r' = Float -> Float
forall a. Fractional a => a -> a
recip (Float -> Float
forall a. Floating a => a -> a
sqrt ( Float -> Float
forall a. Num a => a -> a
negate (Float
a1Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
b1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a2Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
b2) ))
        in case Vector Float 3 -> (# Float, Float, Float #)
forall t. Vector3 t => Vector t 3 -> (# t, t, t #)
unpackV3# (Vector Float 3 -> Vector Float 3 -> Vector Float 3
forall t.
(Num t, PrimBytes t) =>
Vector t 3 -> Vector t 3 -> Vector t 3
cross Vector Float 3
a Vector Float 3
b) of
          (# Float
0, Float
0, Float
0 #)
              -- if a and b face the same direction, q is fully real
            | Float
d Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= Float
0       -> Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
0 Float
0 Float
0 Float
c'
              -- if a and b face opposite directions, find an orthogonal vector
              -- prerequisites: w == 0  and  a·(x,y,z) == 0
              -- corner cases: only one vector component is non-zero
            | Float
b1 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0      -> Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
c' Float
0 Float
0 Float
0
              -- otherwise set the last component to zero,
              -- and get an orthogonal vector in 2D.
            | Bool
otherwise    -> Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (-Float
b2Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
r') (Float
b1Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
r') Float
0 Float
0
              -- NB: here we have some precision troubles
              --     when a and b are close to parallel and opposite.
          (# Float
t1, Float
t2, Float
t3 #) -> Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
t1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r) (Float
t2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r) (Float
t3 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r) (Float
c Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
ma2)
    {-# INLINE axisRotation #-}
    axisRotation :: Vector Float 3 -> Float -> Quater Float
axisRotation Vector Float 3
v Float
a = case Vector Float 3 -> (# Float, Float, Float #)
forall t. Vector3 t => Vector t 3 -> (# t, t, t #)
unpackV3# Vector Float 3
v of
      (# Float
0, Float
0, Float
0 #) -> Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
0 Float
0 Float
0 (Bool -> Float -> Float
forall t. Num t => Bool -> t -> t
negateUnless (Float -> Float
forall a. Num a => a -> a
abs Float
a Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Float
forall a. (Eq a, Fractional a, Fractional a) => a
M_PI) Float
1)
      (# Float
x, Float
y, Float
z #) ->
        let c :: Float
c = Float -> Float
forall a. Floating a => a -> a
cos (Float
a Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
0.5)
            s :: Float
s = Float -> Float
forall a. Floating a => a -> a
sin (Float
a Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
0.5)
                Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float -> Float
forall a. Floating a => a -> a
sqrt (Float
xFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
yFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
zFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
z)
        in Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s) (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s) (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s) Float
c
    {-# INLINE qArg #-}
    qArg :: Quater Float -> Float
qArg (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #)) = Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float -> Float
forall a. RealFloat a => a -> a -> a
atan2 (Float -> Float
forall a. Floating a => a -> a
sqrt (Float
xFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
yFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
zFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
z)) Float
w
    {-# INLINE fromMatrix33 #-}
    fromMatrix33 :: Matrix Float 3 3 -> Quater Float
fromMatrix33 Matrix Float 3 3
m = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Quater Float
fromM Float
1
      (Int# -> Matrix Float 3 3 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
0# Matrix Float 3 3
m) (Int# -> Matrix Float 3 3 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
1# Matrix Float 3 3
m) (Int# -> Matrix Float 3 3 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
2# Matrix Float 3 3
m)
      (Int# -> Matrix Float 3 3 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
3# Matrix Float 3 3
m) (Int# -> Matrix Float 3 3 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
4# Matrix Float 3 3
m) (Int# -> Matrix Float 3 3 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
5# Matrix Float 3 3
m)
      (Int# -> Matrix Float 3 3 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
6# Matrix Float 3 3
m) (Int# -> Matrix Float 3 3 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
7# Matrix Float 3 3
m) (Int# -> Matrix Float 3 3 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
8# Matrix Float 3 3
m)

    {-# INLINE fromMatrix44 #-}
    fromMatrix44 :: Matrix Float 4 4 -> Quater Float
fromMatrix44 Matrix Float 4 4
m = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Quater Float
fromM (Int# -> Matrix Float 4 4 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
15# Matrix Float 4 4
m)
      (Int# -> Matrix Float 4 4 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
0# Matrix Float 4 4
m) (Int# -> Matrix Float 4 4 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
1# Matrix Float 4 4
m) (Int# -> Matrix Float 4 4 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
2# Matrix Float 4 4
m)
      (Int# -> Matrix Float 4 4 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
4# Matrix Float 4 4
m) (Int# -> Matrix Float 4 4 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
5# Matrix Float 4 4
m) (Int# -> Matrix Float 4 4 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
6# Matrix Float 4 4
m)
      (Int# -> Matrix Float 4 4 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
8# Matrix Float 4 4
m) (Int# -> Matrix Float 4 4 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
9# Matrix Float 4 4
m) (Int# -> Matrix Float 4 4 -> Float
forall t a. PrimArray t a => Int# -> a -> t
ix# Int#
10# Matrix Float 4 4
m)

    {-# INLINE toMatrix33 #-}
    toMatrix33 :: Quater Float -> Matrix Float 3 3
toMatrix33 (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
0.0, Float
0.0, Float
0.0, Float
w #))
      = let x :: Float
x = Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w
            f :: Int -> (# Int, Float #)
f Int
0 = (# Int
3 :: Int , Float
x #)
            f Int
k = (# Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1, Float
0 #)
        in case CumulDims
-> (Int -> (# Int, Float #)) -> Int -> (# Int, Matrix Float 3 3 #)
forall t a s.
PrimArray t a =>
CumulDims -> (s -> (# s, t #)) -> s -> (# s, a #)
gen# ([Word] -> CumulDims
CumulDims [Word
9,Word
3,Word
1]) Int -> (# Int, Float #)
f Int
0 of
            (# Int
_, Matrix Float 3 3
m #) -> Matrix Float 3 3
m -- diag (scalar (w * w))
    toMatrix33 (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x', Float
y', Float
z', Float
w' #)) =
      let x :: DataFrame Float '[]
x = Float -> DataFrame Float '[]
forall t. t -> DataFrame t '[]
scalar Float
x'
          y :: DataFrame Float '[]
y = Float -> DataFrame Float '[]
forall t. t -> DataFrame t '[]
scalar Float
y'
          z :: DataFrame Float '[]
z = Float -> DataFrame Float '[]
forall t. t -> DataFrame t '[]
scalar Float
z'
          w :: DataFrame Float '[]
w = Float -> DataFrame Float '[]
forall t. t -> DataFrame t '[]
scalar Float
w'
          x2 :: DataFrame Float '[]
x2 = DataFrame Float '[]
x DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
* DataFrame Float '[]
x
          y2 :: DataFrame Float '[]
y2 = DataFrame Float '[]
y DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
* DataFrame Float '[]
y
          z2 :: DataFrame Float '[]
z2 = DataFrame Float '[]
z DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
* DataFrame Float '[]
z
          w2 :: DataFrame Float '[]
w2 = DataFrame Float '[]
w DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
* DataFrame Float '[]
w
          l2 :: DataFrame Float '[]
l2 = DataFrame Float '[]
x2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
y2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
z2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
w2
      in (forall s. ST s (Matrix Float 3 3)) -> Matrix Float 3 3
forall a. (forall s. ST s a) -> a
ST.runST ((forall s. ST s (Matrix Float 3 3)) -> Matrix Float 3 3)
-> (forall s. ST s (Matrix Float 3 3)) -> Matrix Float 3 3
forall a b. (a -> b) -> a -> b
$ do
        STDataFrame s Float '[3, 3]
df <- ST s (STDataFrame s Float '[3, 3])
forall k t (ns :: [k]) s.
(PrimBytes t, Dimensions ns) =>
ST s (STDataFrame s t ns)
ST.newDataFrame
        STDataFrame s Float '[3, 3]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[3, 3]
df Int
0 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
l2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
- DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
z2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
y2)
        STDataFrame s Float '[3, 3]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[3, 3]
df Int
1 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
xDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
y DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
zDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
w)
        STDataFrame s Float '[3, 3]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[3, 3]
df Int
2 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
xDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
z DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
- DataFrame Float '[]
yDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
w)
        STDataFrame s Float '[3, 3]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[3, 3]
df Int
3 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
xDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
y DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
- DataFrame Float '[]
zDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
w)
        STDataFrame s Float '[3, 3]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[3, 3]
df Int
4 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
l2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
- DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
z2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
x2)
        STDataFrame s Float '[3, 3]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[3, 3]
df Int
5 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
yDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
z DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
xDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
w)
        STDataFrame s Float '[3, 3]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[3, 3]
df Int
6 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
xDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
z DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
yDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
w)
        STDataFrame s Float '[3, 3]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[3, 3]
df Int
7 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
yDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
z DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
- DataFrame Float '[]
xDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
w)
        STDataFrame s Float '[3, 3]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[3, 3]
df Int
8 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
l2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
- DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
y2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
x2)
        STDataFrame s Float '[3, 3] -> ST s (Matrix Float 3 3)
forall k t (ns :: [k]) s.
PrimArray t (DataFrame t ns) =>
STDataFrame s t ns -> ST s (DataFrame t ns)
ST.unsafeFreezeDataFrame STDataFrame s Float '[3, 3]
df
    {-# INLINE toMatrix44 #-}
    toMatrix44 :: Quater Float -> Matrix Float 4 4
toMatrix44 (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
0.0, Float
0.0, Float
0.0, Float
w #)) = (forall s. ST s (Matrix Float 4 4)) -> Matrix Float 4 4
forall a. (forall s. ST s a) -> a
ST.runST ((forall s. ST s (Matrix Float 4 4)) -> Matrix Float 4 4)
-> (forall s. ST s (Matrix Float 4 4)) -> Matrix Float 4 4
forall a b. (a -> b) -> a -> b
$ do
      STDataFrame s Float '[4, 4]
df <- ST s (STDataFrame s Float '[4, 4])
forall k t (ns :: [k]) s.
(PrimBytes t, Dimensions ns) =>
ST s (STDataFrame s t ns)
ST.newDataFrame
      (Int -> ST s ()) -> [Int] -> ST s ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ((Int -> DataFrame Float '[] -> ST s ())
-> DataFrame Float '[] -> Int -> ST s ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip (STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df) DataFrame Float '[]
0) [Int
0..Int
15]
      let w2 :: DataFrame Float '[]
w2 = Float -> DataFrame Float '[]
forall t. t -> DataFrame t '[]
scalar (Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w)
      STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
0 DataFrame Float '[]
w2
      STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
5 DataFrame Float '[]
w2
      STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
10 DataFrame Float '[]
w2
      STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
15 DataFrame Float '[]
1
      STDataFrame s Float '[4, 4] -> ST s (Matrix Float 4 4)
forall k t (ns :: [k]) s.
PrimArray t (DataFrame t ns) =>
STDataFrame s t ns -> ST s (DataFrame t ns)
ST.unsafeFreezeDataFrame STDataFrame s Float '[4, 4]
df
    toMatrix44 (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x', Float
y', Float
z', Float
w' #)) =
      let x :: DataFrame Float '[]
x = Float -> DataFrame Float '[]
forall t. t -> DataFrame t '[]
scalar Float
x'
          y :: DataFrame Float '[]
y = Float -> DataFrame Float '[]
forall t. t -> DataFrame t '[]
scalar Float
y'
          z :: DataFrame Float '[]
z = Float -> DataFrame Float '[]
forall t. t -> DataFrame t '[]
scalar Float
z'
          w :: DataFrame Float '[]
w = Float -> DataFrame Float '[]
forall t. t -> DataFrame t '[]
scalar Float
w'
          x2 :: DataFrame Float '[]
x2 = DataFrame Float '[]
x DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
* DataFrame Float '[]
x
          y2 :: DataFrame Float '[]
y2 = DataFrame Float '[]
y DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
* DataFrame Float '[]
y
          z2 :: DataFrame Float '[]
z2 = DataFrame Float '[]
z DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
* DataFrame Float '[]
z
          w2 :: DataFrame Float '[]
w2 = DataFrame Float '[]
w DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
* DataFrame Float '[]
w
          l2 :: DataFrame Float '[]
l2 = DataFrame Float '[]
x2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
y2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
z2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
w2
      in (forall s. ST s (Matrix Float 4 4)) -> Matrix Float 4 4
forall a. (forall s. ST s a) -> a
ST.runST ((forall s. ST s (Matrix Float 4 4)) -> Matrix Float 4 4)
-> (forall s. ST s (Matrix Float 4 4)) -> Matrix Float 4 4
forall a b. (a -> b) -> a -> b
$ do
        STDataFrame s Float '[4, 4]
df <- ST s (STDataFrame s Float '[4, 4])
forall k t (ns :: [k]) s.
(PrimBytes t, Dimensions ns) =>
ST s (STDataFrame s t ns)
ST.newDataFrame
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
0 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
l2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
- DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
z2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
y2)
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
1 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
xDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
y DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
zDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
w)
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
2 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
xDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
z DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
- DataFrame Float '[]
yDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
w)
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
3 DataFrame Float '[]
0
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
4 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
xDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
y DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
- DataFrame Float '[]
zDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
w)
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
5 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
l2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
- DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
z2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
x2)
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
6 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
yDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
z DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
xDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
w)
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
7 DataFrame Float '[]
0
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
8 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
xDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
z DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
yDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
w)
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
9 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
yDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
z DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
- DataFrame Float '[]
xDataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*DataFrame Float '[]
w)
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
10 (DataFrame Float '[] -> ST s ()) -> DataFrame Float '[] -> ST s ()
forall a b. (a -> b) -> a -> b
$ DataFrame Float '[]
l2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
- DataFrame Float '[]
2DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
*(DataFrame Float '[]
y2 DataFrame Float '[] -> DataFrame Float '[] -> DataFrame Float '[]
forall a. Num a => a -> a -> a
+ DataFrame Float '[]
x2)
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
11 DataFrame Float '[]
0
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
12 DataFrame Float '[]
0
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
13 DataFrame Float '[]
0
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
14 DataFrame Float '[]
0
        STDataFrame s Float '[4, 4]
-> Int -> DataFrame Float '[] -> ST s ()
forall k t (ns :: [k]) s.
PrimBytes (DataFrame t '[]) =>
STDataFrame s t ns -> Int -> DataFrame t '[] -> ST s ()
ST.writeDataFrameOff STDataFrame s Float '[4, 4]
df Int
15 DataFrame Float '[]
1
        STDataFrame s Float '[4, 4] -> ST s (Matrix Float 4 4)
forall k t (ns :: [k]) s.
PrimArray t (DataFrame t ns) =>
STDataFrame s t ns -> ST s (DataFrame t ns)
ST.unsafeFreezeDataFrame STDataFrame s Float '[4, 4]
df


{- Calculate quaternion from a 3x3 matrix.

   First argument is a constant; it is either 1 for a 3x3 matrix,
   or m44 for a 4x4 matrix. I just need to multiply all components by
   this number.

   Further NB for the formulae:

   d == square q == det m ** (1/3)
   t == trace m  == 4 w w - d
   m01 - m10 == 4 z w
   m20 - m02 == 4 y w
   m12 - m21 == 4 x w
   m01 + m10 == 4 x y
   m20 + m02 == 4 x z
   m12 + m21 == 4 y z
   m00 == + x x - y y - z z + w w
   m11 == - x x + y y - z z + w w
   m22 == - x x - y y + z z + w w
   4 x x == d + m00 - m11 - m22
   4 y y == d - m00 + m11 - m22
   4 z z == d - m00 - m11 + m22
   4 w w == d + m00 + m11 + m22
 -}
fromM :: Float
      -> Float -> Float -> Float
      -> Float -> Float -> Float
      -> Float -> Float -> Float
      -> QFloat
fromM :: Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Quater Float
fromM Float
c'
  Float
m00 Float
m01 Float
m02
  Float
m10 Float
m11 Float
m12
  Float
m20 Float
m21 Float
m22
    | Float
t Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
> Float
0
      = let dd :: Float
dd = Float -> Float
forall a. Floating a => a -> a
sqrt ( Float
d Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
t )
            is :: Float
is = Float
c Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
dd
        in Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ ((Float
m12 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m21)Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
is) ((Float
m20 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m02)Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
is) ((Float
m01 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m10)Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
is) (Float
cFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
dd)
    | Float
m00 Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
> Float
m11 Bool -> Bool -> Bool
&& Float
m00 Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
> Float
m22
      = let dd :: Float
dd = Float -> Float
forall a. Floating a => a -> a
sqrt ( Float
d Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m00 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m11 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m22 )
            is :: Float
is = Float
c Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
dd
        in Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
cFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
dd) ((Float
m01 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m10)Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
is) ((Float
m02 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m20)Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
is) ((Float
m12 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m21)Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
is)
    | Float
m11 Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
> Float
m22
      = let dd :: Float
dd = Float -> Float
forall a. Floating a => a -> a
sqrt ( Float
d Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m00 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m11 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m22 )
            is :: Float
is = Float
c Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
dd
        in Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ ((Float
m01 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m10)Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
is) (Float
cFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
dd) ((Float
m12 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m21)Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
is) ((Float
m20 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m02)Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
is)
    | Bool
otherwise
      = let dd :: Float
dd = Float -> Float
forall a. Floating a => a -> a
sqrt ( Float
d Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m00 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m11 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m22 )
            is :: Float
is = Float
c Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
dd
        in Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ ((Float
m02 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m20)Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
is) ((Float
m12 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m21)Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
is) (Float
cFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
dd) ((Float
m01 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m10)Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
is)

  where
    -- normalizing constant
    c :: Float
c = Float -> Float
forall a. Fractional a => a -> a
recip (Float -> Float) -> Float -> Float
forall a b. (a -> b) -> a -> b
$ Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
sqrt Float
c'
    -- trace
    t :: Float
t = Float
m00 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m11 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m22
    -- cubic root of determinant
    d :: Float
d = ( Float
m00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* ( Float
m11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m22 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m21 )
        Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* ( Float
m10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m22 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m20 )
        Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* ( Float
m10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m21 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m20 )
        ) Float -> Float -> Float
forall a. Floating a => a -> a -> a
** Float
0.33333333333333333333333333333333




instance Num QFloat where
    QFloat a + :: Quater Float -> Quater Float -> Quater Float
+ QFloat b
      = Vector Float 4 -> Quater Float
QFloat (Vector Float 4
a Vector Float 4 -> Vector Float 4 -> Vector Float 4
forall a. Num a => a -> a -> a
+ Vector Float 4
b)
    {-# INLINE (+) #-}
    QFloat a - :: Quater Float -> Quater Float -> Quater Float
- QFloat b
      = Vector Float 4 -> Quater Float
QFloat (Vector Float 4
a Vector Float 4 -> Vector Float 4 -> Vector Float 4
forall a. Num a => a -> a -> a
- Vector Float 4
b)
    {-# INLINE (-) #-}
    (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
a1, Float
a2, Float
a3, Float
a4 #)) * :: Quater Float -> Quater Float -> Quater Float
* (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
b1, Float
b2, Float
b3, Float
b4 #))
      = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ ((Float
a4 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b1) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
a1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b4) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
a2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b3) Float -> Float -> Float
forall a. Num a => a -> a -> a
- (Float
a3 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b2))
              ((Float
a4 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b2) Float -> Float -> Float
forall a. Num a => a -> a -> a
- (Float
a1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b3) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
a2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b4) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
a3 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b1))
              ((Float
a4 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b3) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
a1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b2) Float -> Float -> Float
forall a. Num a => a -> a -> a
- (Float
a2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b1) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
a3 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b4))
              ((Float
a4 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b4) Float -> Float -> Float
forall a. Num a => a -> a -> a
- (Float
a1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b1) Float -> Float -> Float
forall a. Num a => a -> a -> a
- (Float
a2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b2) Float -> Float -> Float
forall a. Num a => a -> a -> a
- (Float
a3 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b3))
    {-# INLINE (*) #-}
    negate :: Quater Float -> Quater Float
negate (QFloat a) = Vector Float 4 -> Quater Float
QFloat (Vector Float 4 -> Vector Float 4
forall a. Num a => a -> a
negate Vector Float 4
a)
    {-# INLINE negate #-}
    abs :: Quater Float -> Quater Float
abs = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
0 Float
0 Float
0 (Float -> Quater Float)
-> (Quater Float -> Float) -> Quater Float -> Quater Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Float
forall a. Floating a => a -> a
sqrt (Float -> Float)
-> (Quater Float -> Float) -> Quater Float -> Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Quater Float -> Float
forall t. Quaternion t => Quater t -> t
square
    {-# INLINE abs #-}
    signum :: Quater Float -> Quater Float
signum q :: Quater Float
q@(Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
      | Float
qd Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0   = Quater Float
q
      | Bool
otherwise = case Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
iy Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
iz Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
iw Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
nn of
        Int
0 -> Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l)
        Int
1 -> Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float -> Float -> Float
forall a. RealExtras a => a -> a -> a
copysign Float
1 Float
x) Float
0 Float
0 Float
0
        Int
2 -> Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
0 (Float -> Float -> Float
forall a. RealExtras a => a -> a -> a
copysign Float
1 Float
y) Float
0 Float
0
        Int
4 -> Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
0 Float
0 (Float -> Float -> Float
forall a. RealExtras a => a -> a -> a
copysign Float
1 Float
z) Float
0
        Int
8 -> Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
0 Float
0 Float
0 (Float -> Float -> Float
forall a. RealExtras a => a -> a -> a
copysign Float
1 Float
w)
        Int
_ -> Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
n Float
n Float
n Float
n
      where
        n :: Float
n  = Float
0 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
0 :: Float
        qd :: Float
qd = Float
xFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
yFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
zFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
wFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
w
        ix :: Int
ix = if Float -> Bool
forall a. RealFloat a => a -> Bool
isInfinite Float
x then Int
1 else Int
0 :: Int
        iy :: Int
iy = if Float -> Bool
forall a. RealFloat a => a -> Bool
isInfinite Float
y then Int
2 else Int
0 :: Int
        iz :: Int
iz = if Float -> Bool
forall a. RealFloat a => a -> Bool
isInfinite Float
z then Int
4 else Int
0 :: Int
        iw :: Int
iw = if Float -> Bool
forall a. RealFloat a => a -> Bool
isInfinite Float
w then Int
8 else Int
0 :: Int
        nn :: Int
nn = if Float -> Bool
forall a. RealFloat a => a -> Bool
isNaN Float
x Bool -> Bool -> Bool
|| Float -> Bool
forall a. RealFloat a => a -> Bool
isNaN Float
y Bool -> Bool -> Bool
|| Float -> Bool
forall a. RealFloat a => a -> Bool
isNaN Float
z Bool -> Bool -> Bool
|| Float -> Bool
forall a. RealFloat a => a -> Bool
isNaN Float
w then Int
16 else Int
0 :: Int
        l :: Float
l  = Float -> Float
forall a. Fractional a => a -> a
recip (Float -> Float
forall a. Floating a => a -> a
sqrt Float
qd)
    {-# INLINE signum #-}
    fromInteger :: Integer -> Quater Float
fromInteger = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
0 Float
0 Float
0 (Float -> Quater Float)
-> (Integer -> Float) -> Integer -> Quater Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Float
forall a. Num a => Integer -> a
fromInteger
    {-# INLINE fromInteger #-}


instance Fractional QFloat where
    {-# INLINE recip #-}
    recip :: Quater Float -> Quater Float
recip q :: Quater Float
q@(Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #)) = case Float -> Float
forall a. Num a => a -> a
negate (Float -> Float
forall a. Fractional a => a -> a
recip (Quater Float -> Float
forall t. Quaternion t => Quater t -> t
square Quater Float
q)) of
      Float
c -> Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c) (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c) (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c) (Float -> Float
forall a. Num a => a -> a
negate (Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c))
    {-# INLINE (/) #-}
    Quater Float
a / :: Quater Float -> Quater Float -> Quater Float
/ Quater Float
b = Quater Float
a Quater Float -> Quater Float -> Quater Float
forall a. Num a => a -> a -> a
* Quater Float -> Quater Float
forall a. Fractional a => a -> a
recip Quater Float
b
    {-# INLINE fromRational #-}
    fromRational :: Rational -> Quater Float
fromRational = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
0 Float
0 Float
0 (Float -> Quater Float)
-> (Rational -> Float) -> Rational -> Quater Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Float
forall a. Fractional a => Rational -> a
fromRational


instance Floating QFloat where
    {-# INLINE pi #-}
    pi :: Quater Float
pi = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
0 Float
0 Float
0 Float
forall a. (Eq a, Fractional a, Fractional a) => a
M_PI
    {-# INLINE exp #-}
    exp :: Quater Float -> Quater Float
exp (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
      | Float
mv2 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0  = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z Float
ew
      | Bool
otherwise = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) Float
arg
      where
        mv2 :: Float
mv2 = (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z)
        mv :: Float
mv  = Float -> Float
forall a. Floating a => a -> a
sqrt Float
mv2
        ew :: Float
ew  = Float -> Float
forall a. Floating a => a -> a
exp Float
w
        l :: Float
l   = Float
ew Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
sin Float
mv Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
mv
        arg :: Float
arg = Float
ew Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
cos Float
mv
    {-# INLINE log #-}
    log :: Quater Float -> Quater Float
log = Vector Float 3 -> Quater Float -> Quater Float
log' (Float -> Float -> Float -> Vector Float 3
forall t. Vector3 t => t -> t -> t -> Vector t 3
Vec3 Float
1 Float
0 Float
0)
    {-# INLINE sqrt #-}
    sqrt :: Quater Float -> Quater Float
sqrt = Vector Float 3 -> Quater Float -> Quater Float
sqrt' (Float -> Float -> Float -> Vector Float 3
forall t. Vector3 t => t -> t -> t -> Vector t 3
Vec3 Float
1 Float
0 Float
0)
    {-# INLINE sin #-}
    sin :: Quater Float -> Quater Float
sin (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
      | Float
mv2 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0  = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z (Float -> Float
forall a. Floating a => a -> a
sin Float
w)
      | Bool
otherwise = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) Float
arg
      where
        mv2 :: Float
mv2 = (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z)
        mv :: Float
mv  = Float -> Float
forall a. Floating a => a -> a
sqrt Float
mv2
        l :: Float
l   = Float -> Float
forall a. Floating a => a -> a
cos Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
sinh Float
mv Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
mv
        arg :: Float
arg = Float -> Float
forall a. Floating a => a -> a
sin Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
cosh Float
mv
    {-# INLINE cos #-}
    cos :: Quater Float -> Quater Float
cos (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
      | Float
mv2 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0  = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z (Float -> Float
forall a. Floating a => a -> a
cos Float
w)
      | Bool
otherwise = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) Float
arg
      where
        mv2 :: Float
mv2 = (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z)
        mv :: Float
mv  = Float -> Float
forall a. Floating a => a -> a
sqrt Float
mv2
        l :: Float
l   = Float -> Float
forall a. Floating a => a -> a
sin Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
sinh Float
mv Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float -> Float
forall a. Num a => a -> a
negate Float
mv
        arg :: Float
arg = Float -> Float
forall a. Floating a => a -> a
cos Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
cosh Float
mv
    {-# INLINE tan #-}
    tan :: Quater Float -> Quater Float
tan (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
      | Float
mv2 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0       = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z (Float -> Float
forall a. Floating a => a -> a
tan Float
w)
      | Float -> Bool
forall a. RealFloat a => a -> Bool
isInfinite Float
mv2 = Quater Float -> Quater Float
forall a. Num a => a -> a
signum (Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z Float
0)
      | Bool
otherwise      = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) Float
arg
      where
        mv2 :: Float
mv2 = (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z)
        mv :: Float
mv = Float -> Float
forall a. Floating a => a -> a
sqrt Float
mv2
        b :: Float
b = Float
2Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
mv
        a :: Float
a = Float
2Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
w
        sina :: Float
sina = Float -> Float
forall a. Floating a => a -> a
sin Float
a
        eb :: Float
eb = Float -> Float
forall a. Floating a => a -> a
exp (-Float
b)
        eb2 :: Float
eb2 = Float
ebFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
eb
        d :: Float
d = Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
eb2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
eb Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
cos Float
a
        rd :: Float
rd = Float -> Float
forall a. Fractional a => a -> a
recip Float
d
        pa :: Float
pa = Float
forall a. (Eq a, Fractional a, Fractional a) => a
M_PI Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float -> Float
forall a. Num a => a -> a
abs Float
a
        rd' :: Float
rd' = Float
2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ (Float
bFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
b Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
paFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
pa)
        (Float
l, Float
arg) =
          if Float
d Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= Float
forall a. Epsilon a => a
M_EPS
          then ((Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
eb2) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
rd Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
mv, Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sina Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
eb Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
rd)
          else (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
rd' , Float -> Float
forall a. Num a => a -> a
negate Float
sina Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
rd')
    {-# INLINE sinh #-}
    sinh :: Quater Float -> Quater Float
sinh (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
      | Float
mv2 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0  = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z (Float -> Float
forall a. Floating a => a -> a
sinh Float
w)
      | Bool
otherwise = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) Float
arg
      where
        mv2 :: Float
mv2 = (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z)
        mv :: Float
mv  = Float -> Float
forall a. Floating a => a -> a
sqrt Float
mv2
        l :: Float
l   = Float -> Float
forall a. Floating a => a -> a
cosh Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
sin Float
mv Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
mv
        arg :: Float
arg = Float -> Float
forall a. Floating a => a -> a
sinh Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
cos Float
mv
    {-# INLINE cosh #-}
    cosh :: Quater Float -> Quater Float
cosh (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
      | Float
mv2 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0  = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z (Float -> Float
forall a. Floating a => a -> a
cosh Float
w)
      | Bool
otherwise = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) Float
arg
      where
        mv2 :: Float
mv2 = (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z)
        mv :: Float
mv  = Float -> Float
forall a. Floating a => a -> a
sqrt Float
mv2
        l :: Float
l   = Float -> Float
forall a. Floating a => a -> a
sinh Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
sin Float
mv Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
mv
        arg :: Float
arg = Float -> Float
forall a. Floating a => a -> a
cosh Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
cos Float
mv
    {-# INLINE tanh #-}
    tanh :: Quater Float -> Quater Float
tanh (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
      | Float
mv2 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0       = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z (Float -> Float
forall a. Floating a => a -> a
tanh Float
w)
      | Float -> Bool
forall a. RealFloat a => a -> Bool
isInfinite Float
mv2 = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
0 Float
0 Float
0 (Float -> Float
forall a. Num a => a -> a
signum Float
w)
      | Bool
otherwise      = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) Float
arg
      where
        mv2 :: Float
mv2 = (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z)
        mv :: Float
mv = Float -> Float
forall a. Floating a => a -> a
sqrt Float
mv2
        b :: Float
b = Float
2Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
w
        a :: Float
a = Float
2Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
mv
        eb :: Float
eb = Float -> Float
forall a. Floating a => a -> a
exp (- Float -> Float
forall a. Num a => a -> a
abs Float
b)
        eb2 :: Float
eb2 = Float
ebFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
eb
        d :: Float
d = Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
eb2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
eb Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
cos Float
a
        rd :: Float
rd = Float -> Float
forall a. Fractional a => a -> a
recip Float
d
        pa :: Float
pa = Float
forall a. (Eq a, Fractional a, Fractional a) => a
M_PI Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a
        rd' :: Float
rd' = Float
2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ (Float
bFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
b Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
paFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
pa)
        (Float
l, Float
arg) =
          if Float
d Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= Float
forall a. Epsilon a => a
M_EPS
          then (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
sin Float
a Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
eb Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
rd Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
mv, Float -> Float -> Float
forall a. RealExtras a => a -> a -> a
copysign (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
eb2) Float
b Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
rd)
          else (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
rd' , Float
b Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
rd')
    {-# INLINE asin #-}
    -- The original formula:
    -- asin q = -i * log (i*q + sqrt (1 - q*q))
    -- below is a more numerically stable version.
    asin :: Quater Float -> Quater Float
asin (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
      | Float
v2 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0   = if Float
w2 Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
<= Float
1
                    then Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z (Float -> Float
forall a. Floating a => a -> a
asin Float
w)
                    else Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
l Float
0 Float
0 Float
arg
      | Bool
otherwise  = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
xFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c) (Float
yFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c) (Float
zFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c) Float
arg
      where
        v2 :: Float
v2 = (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z)
        v :: Float
v = Float -> Float
forall a. Floating a => a -> a
sqrt Float
v2
        w2 :: Float
w2 = Float
wFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
w
        w1qq :: Float
w1qq = Float
0.5 Float -> Float -> Float
forall a. Num a => a -> a -> a
*(Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
w2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
v2)       -- real part of (1 - q*q)/2
        l1qq :: Float
l1qq = Float -> Float
forall a. Floating a => a -> a
sqrt (Float
w1qqFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
w1qq Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w2Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
v2) -- length of (1 - q*q)/2
        sp2 :: Float
sp2 = Float
l1qq Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w1qq
        sn2 :: Float
sn2 = Float
l1qq Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
w1qq
        sp :: Float
sp = Float -> Float
forall a. Floating a => a -> a
sqrt Float
sp2
        sn :: Float
sn = Float -> Float -> Float
forall a. RealExtras a => a -> a -> a
copysign (Float -> Float
forall a. Floating a => a -> a
sqrt Float
sn2) Float
w
        -- choose a more stable (symbolically equiv) version
        dp :: Float
dp = if Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
v2 Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
<= Float
sp2 then Float
sp Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
v else Float
v2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ ((Float
sp Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
v)Float -> Float -> Float
forall a. Num a => a -> a -> a
*(Float
sn2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
v2))
        dn :: Float
dn = if Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w2 Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
<= Float
sn2 then Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
sn else Float
w2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ ((Float
sn Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w)Float -> Float -> Float
forall a. Num a => a -> a -> a
*(Float
sp2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w2))
        (Float
wD, Float
vD) = case Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Float
w1qq Float
0 of
            Ordering
GT -> (Float
dp, Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
dp Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
sp)
            Ordering
LT -> (Float
v Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
dn Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
sn, Float
dn)
            Ordering
EQ -> (-Float
v, Float
w)
        l :: Float
l = -Float
0.5 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
log (Float
wDFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
wD Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
vDFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
vD)
        c :: Float
c = Float
l Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
v
        arg :: Float
arg = Float -> Float -> Float
forall a. RealFloat a => a -> a -> a
atan2 Float
vD Float
wD
    {-# INLINE acos #-}
    acos :: Quater Float -> Quater Float
acos Quater Float
q = Quater Float
forall a. (Eq a, Fractional a, Fractional a) => a
M_PI_2 Quater Float -> Quater Float -> Quater Float
forall a. Num a => a -> a -> a
- Quater Float -> Quater Float
forall a. Floating a => a -> a
asin Quater Float
q
    {-# INLINE atan #-}
    -- atan q = i / 2 * log ( (i + q) / (i - q) )
    atan :: Quater Float -> Quater Float
atan (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
      | Float
v2 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0   = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z (Float -> Float
forall a. Floating a => a -> a
atan Float
w)
      | Bool
otherwise = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
xFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c) (Float
yFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c) (Float
zFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c) Float
arg
      where
        v2 :: Float
v2 = (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z)
        v :: Float
v = Float -> Float
forall a. Floating a => a -> a
sqrt Float
v2
        w2 :: Float
w2 = Float
wFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
w
        q2 :: Float
q2 = Float
w2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
v2
        v' :: Float
v' = Float
v Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
1
        mzero :: Float
mzero = Float
w2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
v'Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
v'
        (Float
c, Float
arg) =
          if Float
mzero Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0
          then ( Float -> Float
forall a. Floating a => a -> a
sqrt Float
forall a. RealFloatExtras a => a
maxFinite Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
v, Float
0)
          else ( Float
0.25 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float -> Float
forall a. Floating a => a -> a
log (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
q2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
2Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
v) Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float -> Float
forall a. Floating a => a -> a
log Float
mzero) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
v
               , Float
0.5 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float -> Float
forall a. RealFloat a => a -> a -> a
atan2 (Float
2Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
w) (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
q2) )
    {-# INLINE asinh #-}
    -- The original formula:
    -- asinh q = log (q + sqrt (q*q + 1))
    -- below is a more numerically stable version.
    asinh :: Quater Float -> Quater Float
asinh (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
      | Float
v2 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0   = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z (Float -> Float
forall a. Floating a => a -> a
asinh Float
w)
      | Bool
otherwise = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
xFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c) (Float
yFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c) (Float
zFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c) Float
arg
      where
        v2 :: Float
v2 = (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z)
        v :: Float
v = Float -> Float
forall a. Floating a => a -> a
sqrt Float
v2
        w2 :: Float
w2 = Float
wFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
w
        w1qq :: Float
w1qq = Float
0.5 Float -> Float -> Float
forall a. Num a => a -> a -> a
*(Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w2 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
v2)       -- real part of (1 + q*q)/2
        l1qq :: Float
l1qq = Float -> Float
forall a. Floating a => a -> a
sqrt (Float
w1qqFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
w1qq Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w2Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
v2) -- length of (1 + q*q)/2
        sp2 :: Float
sp2 = Float
l1qq Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w1qq
        sn2 :: Float
sn2 = Float
l1qq Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
w1qq
        sp :: Float
sp = Float -> Float
forall a. Floating a => a -> a
sqrt Float
sp2
        sn :: Float
sn = Float -> Float -> Float
forall a. RealExtras a => a -> a -> a
copysign (Float -> Float
forall a. Floating a => a -> a
sqrt Float
sn2) Float
w
        -- choose a more stable (symbolically equiv) version
        dp :: Float
dp = if Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= - Float
sp then Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
sp else Float
w2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ ((Float
sp Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
w)Float -> Float -> Float
forall a. Num a => a -> a -> a
*(Float
w2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
sn2))
        dn :: Float
dn = if Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
v Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
<= - Float
sn Bool -> Bool -> Bool
|| Float
sn Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= Float
0
                              then Float
v Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
sn else Float
v2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ ((Float
v Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
sn)Float -> Float -> Float
forall a. Num a => a -> a -> a
*(Float
v2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
sp2))
        (Float
wD, Float
vD) = case Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Float
w1qq Float
0 of
            Ordering
GT -> (Float
dp, Float
v Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
dp Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
sp)
            Ordering
LT -> (Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
dn Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
sn, Float
dn)
            Ordering
EQ -> (Float
w, Float
v)
        c :: Float
c = Float -> Float -> Float
forall a. RealFloat a => a -> a -> a
atan2 Float
vD Float
wD Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
v
        arg :: Float
arg = Float
0.5 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
log (Float
wDFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
wD Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
vDFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
vD)
    {-# INLINE acosh #-}
    -- The original formula:
    -- asinh q = log (q + sqrt (q + 1) * sqrt (q - 1))
    -- below is a more numerically stable version.
    -- note, log (q + sqrt (q*q - 1)) would not work, because that would not
    -- be the principal value.
    acosh :: Quater Float -> Quater Float
acosh (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
      | Float
v2 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0   = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z (Float -> Float
forall a. Floating a => a -> a
acosh Float
w)
      | Bool
otherwise = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
xFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c) (Float
yFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c) (Float
zFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c) Float
arg
      where
        v2 :: Float
v2 = (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z)
        v :: Float
v = Float -> Float
forall a. Floating a => a -> a
sqrt Float
v2
        w2 :: Float
w2 = Float
wFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
w
        w1qq :: Float
w1qq = Float
0.5 Float -> Float -> Float
forall a. Num a => a -> a -> a
*(Float
w2 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
v2 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
1)       -- real part of (q*q - 1)/2
        l1qq :: Float
l1qq = Float -> Float
forall a. Floating a => a -> a
sqrt (Float
w1qqFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
w1qq Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w2Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
v2) -- length of (q*q - 1)/2
        sp2 :: Float
sp2 = Float
l1qq Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w1qq
        sn2 :: Float
sn2 = Float
l1qq Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
w1qq
        sp :: Float
sp = Float -> Float
forall a. Floating a => a -> a
sqrt Float
sp2
        sn :: Float
sn = Float -> Float -> Float
forall a. RealExtras a => a -> a -> a
copysign (Float -> Float
forall a. Floating a => a -> a
sqrt Float
sn2) Float
w
        -- choose a more stable (symbolically equiv) version
        dp :: Float
dp = if Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= - Float
sp then Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
sp else Float
w2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ ((Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
sp)Float -> Float -> Float
forall a. Num a => a -> a -> a
*(Float
w2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
sn2))
        dn :: Float
dn = if Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
v Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
<= - Float
sn Bool -> Bool -> Bool
|| Float
sn Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= Float
0
                              then Float
v Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
sn else Float
v2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ ((Float
sn Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
v)Float -> Float -> Float
forall a. Num a => a -> a -> a
*(Float
v2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
sp2))
        (Float
wD, Float
vD) = case Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Float
w1qq Float
0 of
            Ordering
GT -> (Float
dp, Float
v Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
dp Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
sp)
            Ordering
LT -> (Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
dn Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
sn, Float
dn)
            Ordering
EQ -> (Float
w, Float
v)
        c :: Float
c = Float -> Float -> Float
forall a. RealFloat a => a -> a -> a
atan2 Float
vD Float
wD Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
v
        arg :: Float
arg = Float
0.5 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
log (Float
wDFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
wD Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
vDFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
vD)
    {-# INLINE atanh #-}
    -- atanh q = 0.5 * log ( (1 + q) / (1 - q) )
    atanh :: Quater Float -> Quater Float
atanh (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
      | Float
v2 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
==  Float
0  = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z (Float -> Float
forall a. Floating a => a -> a
atanh Float
w)
      | Bool
otherwise = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
xFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c) (Float
yFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c) (Float
zFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c) (Float -> Float -> Float
forall a. RealExtras a => a -> a -> a
copysign Float
arg Float
w)
      where
        v2 :: Float
v2 = (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z)
        v :: Float
v = Float -> Float
forall a. Floating a => a -> a
sqrt Float
v2
        w2 :: Float
w2 = Float
wFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
w
        q2 :: Float
q2 = Float
w2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
v2
        w' :: Float
w' = Float -> Float
forall a. Num a => a -> a
abs Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
1
        c :: Float
c  = Float
0.5 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float -> Float
forall a. RealFloat a => a -> a -> a
atan2 (Float
2Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
v) (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
q2) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
v
        arg :: Float
arg = if Float
w' Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0
              then (Float
1Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
0)
              else Float
0.25 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float -> Float
forall a. Floating a => a -> a
log (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
q2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Num a => a -> a
abs Float
w) Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float -> Float
forall a. Floating a => a -> a
log (Float
v2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w'Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
w'))


-- If q is negative real, provide a fallback axis to align log.
log' :: Vector Float 3 -> QFloat -> QFloat
log' :: Vector Float 3 -> Quater Float -> Quater Float
log' Vector Float 3
r (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
  = case (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z) of
    Float
0.0 | Float
w Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= Float
0
           -> Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
0 Float
0 Float
0 (Float -> Float
forall a. Floating a => a -> a
log Float
w)
        | Vec3 Float
rx Float
ry Float
rz <- Vector Float 3
r
           ->  Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
forall a. (Eq a, Fractional a, Fractional a) => a
M_PIFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
rx) (Float
forall a. (Eq a, Fractional a, Fractional a) => a
M_PIFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
ry) (Float
forall a. (Eq a, Fractional a, Fractional a) => a
M_PIFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
rz) (Float -> Float
forall a. Floating a => a -> a
log (Float -> Float
forall a. Num a => a -> a
negate Float
w))
    Float
mv2 -> case (# Float
mv2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w, Float -> Float
forall a. Floating a => a -> a
sqrt Float
mv2 #) of
      (# Float
q2, Float
mv #) -> case Float -> Float -> Float
forall a. RealFloat a => a -> a -> a
atan2 Float
mv Float
w Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
mv of
        Float
l -> Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
l) (Float
0.5 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
log Float
q2)


-- If q is negative real, provide a fallback axis to align sqrt.
sqrt' :: Vector Float 3 -> QFloat -> QFloat
sqrt' :: Vector Float 3 -> Quater Float -> Quater Float
sqrt' Vector Float 3
r (Quater Float -> (# Float, Float, Float, Float #)
forall t. Quaternion t => Quater t -> (# t, t, t, t #)
unpackQ# -> (# Float
x, Float
y, Float
z, Float
w #))
  | Float
v2 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0 Bool -> Bool -> Bool
&& Float
w Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= Float
0
    = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ Float
x Float
y Float
z (Float -> Float
forall a. Floating a => a -> a
sqrt Float
w)
  | Float
v2 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0
  , Vec3 Float
rx Float
ry Float
rz <- Vector Float 3
r
  , Float
sw <- Float -> Float
forall a. Floating a => a -> a
sqrt (Float -> Float
forall a. Num a => a -> a
negate Float
w)
    = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
swFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
rx) (Float
swFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
ry) (Float
swFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
rz) Float
0
  | Bool
otherwise
    = Float -> Float -> Float -> Float -> Quater Float
forall t. Quaternion t => t -> t -> t -> t -> Quater t
packQ (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c) (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c) (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c) Float
arg
  where
    v2 :: Float
v2 = (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z)
    mq :: Float
mq = Float -> Float
forall a. Floating a => a -> a
sqrt (Float
v2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w)
    arg :: Float
arg = Float -> Float
forall a. Floating a => a -> a
sqrt (Float -> Float) -> Float -> Float
forall a b. (a -> b) -> a -> b
$ Float
0.5 Float -> Float -> Float
forall a. Num a => a -> a -> a
* if Float
w Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= Float
0 then Float
mq Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w else Float
v2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ (Float
mq Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
w)
    c :: Float
c = Float
0.5 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
arg

instance Eq QFloat where
    {-# INLINE (==) #-}
    QFloat a == :: Quater Float -> Quater Float -> Bool
== QFloat b = Vector Float 4
a Vector Float 4 -> Vector Float 4 -> Bool
forall a. Eq a => a -> a -> Bool
== Vector Float 4
b
    {-# INLINE (/=) #-}
    QFloat a /= :: Quater Float -> Quater Float -> Bool
/= QFloat b = Vector Float 4
a Vector Float 4 -> Vector Float 4 -> Bool
forall a. Eq a => a -> a -> Bool
/= Vector Float 4
b