{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Diagrams.ThreeD.Types
(
r3, unr3, mkR3
, p3, unp3, mkP3
, r3Iso, p3Iso, project
, r3SphericalIso, r3CylindricalIso
, V3 (..), P3, T3
, R1 (..), R2 (..), R3 (..)
) where
import Control.Lens (Iso', iso, _1, _2, _3)
import Diagrams.Angle
import Diagrams.Core
import Diagrams.Points
import Diagrams.TwoD.Types
import Linear.Metric
import Linear.V3 as V
type P3 = Point V3
type T3 = Transformation V3
r3Iso :: Iso' (V3 n) (n, n, n)
r3Iso = iso unr3 r3
r3 :: (n, n, n) -> V3 n
r3 (x,y,z) = V3 x y z
mkR3 :: n -> n -> n -> V3 n
mkR3 = V3
unr3 :: V3 n -> (n, n, n)
unr3 (V3 x y z) = (x,y,z)
p3 :: (n, n, n) -> P3 n
p3 = P . r3
unp3 :: P3 n -> (n, n, n)
unp3 (P (V3 x y z)) = (x,y,z)
p3Iso :: Iso' (P3 n) (n, n, n)
p3Iso = iso unp3 p3
mkP3 :: n -> n -> n -> P3 n
mkP3 x y z = p3 (x, y, z)
type instance V (V3 n) = V3
type instance N (V3 n) = n
instance Transformable (V3 n) where
transform = apply
r3SphericalIso :: RealFloat n => Iso' (V3 n) (n, Angle n, Angle n)
r3SphericalIso = iso
(\v@(V3 x y z) -> (norm v, atan2A y x, acosA (z / norm v)))
(\(r,θ,φ) -> V3 (r * cosA θ * sinA φ) (r * sinA θ * sinA φ) (r * cosA φ))
r3CylindricalIso :: RealFloat n => Iso' (V3 n) (n, Angle n, n)
r3CylindricalIso = iso
(\(V3 x y z) -> (sqrt $ x*x + y*y, atan2A y x, z))
(\(r,θ,z) -> V3 (r*cosA θ) (r*sinA θ) z)
instance HasR V3 where
_r = r3SphericalIso . _1
instance HasTheta V3 where
_theta = r3CylindricalIso . _2
instance HasPhi V3 where
_phi = r3SphericalIso . _3