module Diagrams.ThreeD.Vector
(
unitX, unitY, unitZ, unit_X, unit_Y, unit_Z,
direction, fromDirection, angleBetween, angleBetweenDirs
) where
import Control.Lens (op)
import Data.VectorSpace
import Data.Cross
import Diagrams.ThreeD.Types
import Diagrams.Coordinates
unitX :: R3
unitX = 1 ^& 0 ^& 0
unitY :: R3
unitY = 0 ^& 1 ^& 0
unitZ :: R3
unitZ = 0 ^& 0 ^& 1
unit_X :: R3
unit_X = (1) ^& 0 ^& 0
unit_Y :: R3
unit_Y = 0 ^& (1) ^& 0
unit_Z :: R3
unit_Z = 0 ^& 0 ^& (1)
direction :: Direction d => R3 -> d
direction v
| r == 0 = fromSpherical $ Spherical zero zero
| otherwise = fromSpherical $ Spherical θ φ where
r = magnitude v
(x,y,z) = unr3 v
φ = Rad . asin $ z / r
θ = Rad . atan2 y $ x
zero = Rad $ 0
fromDirection :: Direction d => d -> R3
fromDirection (toSpherical -> (Spherical θ' φ')) = r3 (x,y,z) where
θ = op Rad $ θ'
φ = op Rad $ φ'
x = cos θ * cos φ
y = sin θ * cos φ
z = sin φ
angleBetween :: (Angle a, Num a, Ord a) => R3 -> R3 -> a
angleBetween v1 v2 = convertAngle . Rad $
atan2 (magnitude $ cross3 v1 v2) (v1 <.> v2)
angleBetweenDirs :: (Direction d, Angle a, Num a, Ord a) => d -> d -> a
angleBetweenDirs d1 d2 = angleBetween (fromDirection d1) (fromDirection d2)