{-# LANGUAGE GADTs #-}
---------------------------------------------------------------------------------

-- |

-- Copyright   :  (C) 2012-2015 Edward Kmett

-- License     :  BSD-style (see the file LICENSE)

--

-- Maintainer  :  Edward Kmett <ekmett@gmail.com>

-- Stability   :  experimental

-- Portability :  non-portable

--

-- Utility for working with Plücker coordinates for lines in 3d homogeneous space.

----------------------------------------------------------------------------------

module Linear.Plucker.Coincides
  ( Coincides(..)
  ) where

import Linear.Epsilon
import Linear.Plucker

-- | When lines are represented as Plücker coordinates, we have the

-- ability to check for both directed and undirected

-- equality. Undirected equality between 'Line's (or a 'Line' and a

-- 'Ray') checks that the two lines coincide in 3D space. Directed

-- equality, between two 'Ray's, checks that two lines coincide in 3D,

-- and have the same direction. To accomodate these two notions of

-- equality, we use an 'Eq' instance on the 'Coincides' data type.

--

-- For example, to check the /directed/ equality between two lines,

-- @p1@ and @p2@, we write, @Ray p1 == Ray p2@.

data Coincides a where
  Line :: (Epsilon a, Fractional a) => Plucker a -> Coincides a
  Ray  :: (Epsilon a, Fractional a, Ord a) => Plucker a -> Coincides a

instance Eq (Coincides a) where
  Line Plucker a
a == :: Coincides a -> Coincides a -> Bool
== Line Plucker a
b  = forall a.
(Epsilon a, Fractional a) =>
Plucker a -> Plucker a -> Bool
coincides Plucker a
a Plucker a
b
  Line Plucker a
a == Ray Plucker a
b   = forall a.
(Epsilon a, Fractional a) =>
Plucker a -> Plucker a -> Bool
coincides Plucker a
a Plucker a
b
  Ray Plucker a
a  == Line Plucker a
b  = forall a.
(Epsilon a, Fractional a) =>
Plucker a -> Plucker a -> Bool
coincides Plucker a
a Plucker a
b
  Ray Plucker a
a  == Ray Plucker a
b   = forall a.
(Epsilon a, Fractional a, Ord a) =>
Plucker a -> Plucker a -> Bool
coincides' Plucker a
a Plucker a
b