    module Diagrams.ThreeD.Deform
      ( parallelX0, perspectiveX1, facingX
      , parallelY0, perspectiveY1, facingY
      , parallelZ0, perspectiveZ1, facingZ
      ) where

    import           Control.Lens

    import           Diagrams.Deform
    import           Diagrams.TwoD.Deform

    import           Linear.V3
    import           Linear.Vector

    -- | The parallel projection onto the plane z=0
    parallelZ0 :: (R3 v, Num n) => Deformation v v n
    parallelZ0 :: forall (v :: * -> *) n. (R3 v, Num n) => Deformation v v n
    parallelZ0 = (Point v n -> Point v n) -> Deformation v v n
    forall (v :: * -> *) (u :: * -> *) n.
    (Point v n -> Point u n) -> Deformation v u n
    Deformation ((n -> Identity n) -> Point v n -> Identity (Point v n)
    forall a. Lens' (Point v a) a
    forall (t :: * -> *) a. R3 t => Lens' (t a) a
    _z ((n -> Identity n) -> Point v n -> Identity (Point v n))
    -> n -> Point v n -> Point v n
    forall s t a b. ASetter s t a b -> b -> s -> t
    .~ n
    0)

    -- | The perspective division onto the plane z=1 along lines going
    --   through the origin.
    perspectiveZ1 :: (R3 v, Functor v, Fractional n) => Deformation v v n
    perspectiveZ1 :: forall (v :: * -> *) n.
    (R3 v, Functor v, Fractional n) =>
    Deformation v v n
    perspectiveZ1 = (Point v n -> Point v n) -> Deformation v v n
    forall (v :: * -> *) (u :: * -> *) n.
    (Point v n -> Point u n) -> Deformation v u n
    Deformation ((Point v n -> Point v n) -> Deformation v v n)
    -> (Point v n -> Point v n) -> Deformation v v n
    forall a b. (a -> b) -> a -> b
    $ \Point v n
    p -> Point v n
    p Point v n -> n -> Point v n
    forall (f :: * -> *) a.
    (Functor f, Fractional a) =>
    f a -> a -> f a
    ^/ (Point v n
    p Point v n -> Getting n (Point v n) n -> n
    forall s a. s -> Getting a s a -> a
    ^. Getting n (Point v n) n
    forall a. Lens' (Point v a) a
    forall (t :: * -> *) a. R3 t => Lens' (t a) a
    _z)

    facingZ :: (R3 v, Functor v, Fractional n) => Deformation v v n
    facingZ :: forall (v :: * -> *) n.
    (R3 v, Functor v, Fractional n) =>
    Deformation v v n
    facingZ = (Point v n -> Point v n) -> Deformation v v n
    forall (v :: * -> *) (u :: * -> *) n.
    (Point v n -> Point u n) -> Deformation v u n
    Deformation ((Point v n -> Point v n) -> Deformation v v n)
    -> (Point v n -> Point v n) -> Deformation v v n
    forall a b. (a -> b) -> a -> b
    $
      \Point v n
    p -> let z :: n
    z = Point v n
    p Point v n -> Getting n (Point v n) n -> n
    forall s a. s -> Getting a s a -> a
    ^. Getting n (Point v n) n
    forall a. Lens' (Point v a) a
    forall (t :: * -> *) a. R3 t => Lens' (t a) a
    _z
            in  Point v n
    p Point v n -> n -> Point v n
    forall (f :: * -> *) a.
    (Functor f, Fractional a) =>
    f a -> a -> f a
    ^/ n
    z Point v n -> (Point v n -> Point v n) -> Point v n
    forall a b. a -> (a -> b) -> b
    & (n -> Identity n) -> Point v n -> Identity (Point v n)
    forall a. Lens' (Point v a) a
    forall (t :: * -> *) a. R3 t => Lens' (t a) a
    _z ((n -> Identity n) -> Point v n -> Identity (Point v n))
    -> n -> Point v n -> Point v n
    forall s t a b. ASetter s t a b -> b -> s -> t
    .~ n
    z