    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Diagrams.TwoD.Vector
    -- Copyright   :  (c) 2011 diagrams-lib team (see LICENSE)
    -- License     :  BSD-style (see LICENSE)
    -- Maintainer  :  diagrams-discuss@googlegroups.com
    --
    -- Two-dimensional vectors.
    --
    -----------------------------------------------------------------------------
    module Diagrams.TwoD.Vector
           ( -- * Special 2D vectors
             unitX, unitY, unit_X, unit_Y
           , xDir, yDir

             -- * Converting between vectors and angles
           , angleV, angleDir, e, signedAngleBetween, signedAngleBetweenDirs

             -- * 2D vector utilities
           , perp, leftTurn, cross2

           ) where

    import           Control.Lens        (view, (&), (.~), (^.))

    import           Diagrams.Angle
    import           Diagrams.Direction
    import           Diagrams.TwoD.Types

    import           Linear.Metric
    import           Linear.V2
    import           Linear.Vector

    -- | The unit vector in the positive X direction.
    unitX :: (R1 v, Additive v, Num n) => v n
    unitX :: forall (v :: * -> *) n. (R1 v, Additive v, Num n) => v n
    unitX = v n
    forall a. Num a => v a
    forall (f :: * -> *) a. (Additive f, Num a) => f a
    zero v n -> (v n -> v n) -> v n
    forall a b. a -> (a -> b) -> b
    & (n -> Identity n) -> v n -> Identity (v n)
    forall a. Lens' (v a) a
    forall (t :: * -> *) a. R1 t => Lens' (t a) a
    _x ((n -> Identity n) -> v n -> Identity (v n)) -> n -> v n -> v n
    forall s t a b. ASetter s t a b -> b -> s -> t
    .~ n
    1

    -- | The unit vector in the negative X direction.
    unit_X :: (R1 v, Additive v, Num n) => v n
    unit_X :: forall (v :: * -> *) n. (R1 v, Additive v, Num n) => v n
    unit_X = v n
    forall a. Num a => v a
    forall (f :: * -> *) a. (Additive f, Num a) => f a
    zero v n -> (v n -> v n) -> v n
    forall a b. a -> (a -> b) -> b
    & (n -> Identity n) -> v n -> Identity (v n)
    forall a. Lens' (v a) a
    forall (t :: * -> *) a. R1 t => Lens' (t a) a
    _x ((n -> Identity n) -> v n -> Identity (v n)) -> n -> v n -> v n
    forall s t a b. ASetter s t a b -> b -> s -> t
    .~ (-n
    1)

    -- | The unit vector in the positive Y direction.
    unitY :: (R2 v, Additive v, Num n) => v n
    unitY :: forall (v :: * -> *) n. (R2 v, Additive v, Num n) => v n
    unitY = v n
    forall a. Num a => v a
    forall (f :: * -> *) a. (Additive f, Num a) => f a
    zero v n -> (v n -> v n) -> v n
    forall a b. a -> (a -> b) -> b
    & (n -> Identity n) -> v n -> Identity (v n)
    forall a. Lens' (v a) a
    forall (t :: * -> *) a. R2 t => Lens' (t a) a
    _y ((n -> Identity n) -> v n -> Identity (v n)) -> n -> v n -> v n
    forall s t a b. ASetter s t a b -> b -> s -> t
    .~ n
    1

    -- | The unit vector in the negative Y direction.
    unit_Y :: (R2 v, Additive v, Num n) => v n
    unit_Y :: forall (v :: * -> *) n. (R2 v, Additive v, Num n) => v n
    unit_Y = v n
    forall a. Num a => v a
    forall (f :: * -> *) a. (Additive f, Num a) => f a
    zero v n -> (v n -> v n) -> v n
    forall a b. a -> (a -> b) -> b
    & (n -> Identity n) -> v n -> Identity (v n)
    forall a. Lens' (v a) a
    forall (t :: * -> *) a. R2 t => Lens' (t a) a
    _y ((n -> Identity n) -> v n -> Identity (v n)) -> n -> v n -> v n
    forall s t a b. ASetter s t a b -> b -> s -> t
    .~ (-n
    1)

    -- | A 'Direction' pointing in the X direction.
    xDir :: (R1 v, Additive v, Num n) => Direction v n
    xDir :: forall (v :: * -> *) n. (R1 v, Additive v, Num n) => Direction v n
    xDir = v n -> Direction v n
    forall (v :: * -> *) n. v n -> Direction v n
    dir v n
    forall (v :: * -> *) n. (R1 v, Additive v, Num n) => v n
    unitX

    -- | A 'Direction' pointing in the Y direction.
    yDir :: (R2 v, Additive v, Num n) => Direction v n
    yDir :: forall (v :: * -> *) n. (R2 v, Additive v, Num n) => Direction v n
    yDir = v n -> Direction v n
    forall (v :: * -> *) n. v n -> Direction v n
    dir v n
    forall (v :: * -> *) n. (R2 v, Additive v, Num n) => v n
    unitY

    -- | A direction at a specified angle counter-clockwise from the 'xDir'.
    angleDir :: Floating n => Angle n -> Direction V2 n
    angleDir :: forall n. Floating n => Angle n -> Direction V2 n
    angleDir = V2 n -> Direction V2 n
    forall (v :: * -> *) n. v n -> Direction v n
    dir (V2 n -> Direction V2 n)
    -> (Angle n -> V2 n) -> Angle n -> Direction V2 n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Angle n -> V2 n
    forall n. Floating n => Angle n -> V2 n
    angleV

    -- | A unit vector at a specified angle counter-clockwise from the
    --   positive x-axis
    angleV :: Floating n => Angle n -> V2 n
    angleV :: forall n. Floating n => Angle n -> V2 n
    angleV = n -> V2 n
    forall a. Floating a => a -> V2 a
    angle (n -> V2 n) -> (Angle n -> n) -> Angle n -> V2 n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Getting n (Angle n) n -> Angle n -> n
    forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
    view Getting n (Angle n) n
    forall n (p :: * -> * -> *) (f :: * -> *).
    (Profunctor p, Functor f) =>
    p n (f n) -> p (Angle n) (f (Angle n))
    rad

    -- | A unit vector at a specified angle counter-clockwise from the
    --   positive X axis.
    e :: Floating n => Angle n -> V2 n
    e :: forall n. Floating n => Angle n -> V2 n
    e = Angle n -> V2 n
    forall n. Floating n => Angle n -> V2 n
    angleV

    -- | @leftTurn v1 v2@ tests whether the direction of @v2@ is a left
    --   turn from @v1@ (that is, if the direction of @v2@ can be obtained
    --   from that of @v1@ by adding an angle 0 <= theta <= tau/2).
    leftTurn :: (Num n, Ord n) => V2 n -> V2 n -> Bool
    leftTurn :: forall n. (Num n, Ord n) => V2 n -> V2 n -> Bool
    leftTurn V2 n
    v1 V2 n
    v2 = (V2 n
    v1 V2 n -> V2 n -> n
    forall a. Num a => V2 a -> V2 a -> a
    forall (f :: * -> *) a. (Metric f, Num a) => f a -> f a -> a
    `dot` V2 n -> V2 n
    forall a. Num a => V2 a -> V2 a
    perp V2 n
    v2) n -> n -> Bool
    forall a. Ord a => a -> a -> Bool
    < n
    0

    -- | Cross product on vectors in R2.
    cross2 :: Num n => V2 n -> V2 n -> n
    cross2 :: forall a. Num a => V2 a -> V2 a -> a
    cross2 (V2 n
    x1 n
    y1) (V2 n
    x2 n
    y2) = n
    x1 n -> n -> n
    forall a. Num a => a -> a -> a
    * n
    y2 n -> n -> n
    forall a. Num a => a -> a -> a
    - n
    y1 n -> n -> n
    forall a. Num a => a -> a -> a
    * n
    x2

    -- | Signed angle between two vectors. Currently defined as
    --
    -- @
    -- signedAngleBetween u v = (u ^. _theta) ^-^ (v ^. _theta)
    -- @
    signedAngleBetween :: RealFloat n => V2 n -> V2 n -> Angle n
    signedAngleBetween :: forall n. RealFloat n => V2 n -> V2 n -> Angle n
    signedAngleBetween V2 n
    u V2 n
    v = (V2 n
    u V2 n -> Getting (Angle n) (V2 n) (Angle n) -> Angle n
    forall s a. s -> Getting a s a -> a
    ^. Getting (Angle n) (V2 n) (Angle n)
    forall n. RealFloat n => Lens' (V2 n) (Angle n)
    Lens' (V2 n) (Angle n)
    forall (t :: * -> *) n.
    (HasTheta t, RealFloat n) =>
    Lens' (t n) (Angle n)
    _theta) Angle n -> Angle n -> Angle n
    forall a. Num a => Angle a -> Angle a -> Angle a
    forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
    ^-^ (V2 n
    v V2 n -> Getting (Angle n) (V2 n) (Angle n) -> Angle n
    forall s a. s -> Getting a s a -> a
    ^. Getting (Angle n) (V2 n) (Angle n)
    forall n. RealFloat n => Lens' (V2 n) (Angle n)
    Lens' (V2 n) (Angle n)
    forall (t :: * -> *) n.
    (HasTheta t, RealFloat n) =>
    Lens' (t n) (Angle n)
    _theta)

    -- | Same as 'signedAngleBetween' but for 'Directions's.
    signedAngleBetweenDirs :: RealFloat n => Direction V2 n -> Direction V2 n -> Angle n
    signedAngleBetweenDirs :: forall n.
    RealFloat n =>
    Direction V2 n -> Direction V2 n -> Angle n
    signedAngleBetweenDirs Direction V2 n
    u Direction V2 n
    v = (Direction V2 n
    u Direction V2 n
    -> Getting (Angle n) (Direction V2 n) (Angle n) -> Angle n
    forall s a. s -> Getting a s a -> a
    ^. Getting (Angle n) (Direction V2 n) (Angle n)
    forall n. RealFloat n => Lens' (Direction V2 n) (Angle n)
    Lens' (Direction V2 n) (Angle n)
    forall (t :: * -> *) n.
    (HasTheta t, RealFloat n) =>
    Lens' (t n) (Angle n)
    _theta) Angle n -> Angle n -> Angle n
    forall a. Num a => Angle a -> Angle a -> Angle a
    forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
    ^-^ (Direction V2 n
    v Direction V2 n
    -> Getting (Angle n) (Direction V2 n) (Angle n) -> Angle n
    forall s a. s -> Getting a s a -> a
    ^. Getting (Angle n) (Direction V2 n) (Angle n)
    forall n. RealFloat n => Lens' (Direction V2 n) (Angle n)
    Lens' (Direction V2 n) (Angle n)
    forall (t :: * -> *) n.
    (HasTheta t, RealFloat n) =>
    Lens' (t n) (Angle n)
    _theta)