{-# 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  = Plucker a -> Plucker a -> Bool
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   = Plucker a -> Plucker a -> Bool
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  = Plucker a -> Plucker a -> Bool
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   = Plucker a -> Plucker a -> Bool
forall a.
(Epsilon a, Fractional a, Ord a) =>
Plucker a -> Plucker a -> Bool
coincides' Plucker a
a Plucker a
b