{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
--------------------------------------------------------------------------------
-- |
-- Module      :  HGeometry.Line.LineEQ
-- Copyright   :  (C) Frank Staals
-- License     :  see the LICENSE file
-- Maintainer  :  Frank Staals
--
-- Non-vertical Lines in R^2 given by the equation \(y = ax + b\)
--
--------------------------------------------------------------------------------
module HGeometry.Line.LineEQ
  ( LineEQ(LineEQ, MkLineEQ)
  , evalAt'
  , module HGeometry.Line.NonVertical.Class
  ) where

import Control.DeepSeq
import Control.Lens((^.), coerced)
import GHC.Generics(Generic)
import HGeometry.Ext
import HGeometry.HyperPlane.Class
import HGeometry.HyperPlane.Internal
import HGeometry.HyperPlane.NonVertical
import HGeometry.Intersection
import HGeometry.Line.Class
import HGeometry.Line.Intersection
import HGeometry.Line.NonVertical.Class
import HGeometry.Point
import HGeometry.Properties(NumType, Dimension)
import HGeometry.Vector
import Text.Read

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

-- | A non-vertical Line represented by its equation \(y = ax + b\)
--
-- see 'toLinearFunction' in the PointAndVector module to construct a line from a point
-- and a vector.
newtype LineEQ r = MkLineEQ (NonVerticalHyperPlane 2 r)
  deriving newtype (LineEQ r -> LineEQ r -> Bool
(LineEQ r -> LineEQ r -> Bool)
-> (LineEQ r -> LineEQ r -> Bool) -> Eq (LineEQ r)
forall r. Eq r => LineEQ r -> LineEQ r -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall r. Eq r => LineEQ r -> LineEQ r -> Bool
== :: LineEQ r -> LineEQ r -> Bool
$c/= :: forall r. Eq r => LineEQ r -> LineEQ r -> Bool
/= :: LineEQ r -> LineEQ r -> Bool
Eq,Eq (LineEQ r)
Eq (LineEQ r) =>
(LineEQ r -> LineEQ r -> Ordering)
-> (LineEQ r -> LineEQ r -> Bool)
-> (LineEQ r -> LineEQ r -> Bool)
-> (LineEQ r -> LineEQ r -> Bool)
-> (LineEQ r -> LineEQ r -> Bool)
-> (LineEQ r -> LineEQ r -> LineEQ r)
-> (LineEQ r -> LineEQ r -> LineEQ r)
-> Ord (LineEQ r)
LineEQ r -> LineEQ r -> Bool
LineEQ r -> LineEQ r -> Ordering
LineEQ r -> LineEQ r -> LineEQ r
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall r. Ord r => Eq (LineEQ r)
forall r. Ord r => LineEQ r -> LineEQ r -> Bool
forall r. Ord r => LineEQ r -> LineEQ r -> Ordering
forall r. Ord r => LineEQ r -> LineEQ r -> LineEQ r
$ccompare :: forall r. Ord r => LineEQ r -> LineEQ r -> Ordering
compare :: LineEQ r -> LineEQ r -> Ordering
$c< :: forall r. Ord r => LineEQ r -> LineEQ r -> Bool
< :: LineEQ r -> LineEQ r -> Bool
$c<= :: forall r. Ord r => LineEQ r -> LineEQ r -> Bool
<= :: LineEQ r -> LineEQ r -> Bool
$c> :: forall r. Ord r => LineEQ r -> LineEQ r -> Bool
> :: LineEQ r -> LineEQ r -> Bool
$c>= :: forall r. Ord r => LineEQ r -> LineEQ r -> Bool
>= :: LineEQ r -> LineEQ r -> Bool
$cmax :: forall r. Ord r => LineEQ r -> LineEQ r -> LineEQ r
max :: LineEQ r -> LineEQ r -> LineEQ r
$cmin :: forall r. Ord r => LineEQ r -> LineEQ r -> LineEQ r
min :: LineEQ r -> LineEQ r -> LineEQ r
Ord,LineEQ r -> ()
(LineEQ r -> ()) -> NFData (LineEQ r)
forall r. NFData r => LineEQ r -> ()
forall a. (a -> ()) -> NFData a
$crnf :: forall r. NFData r => LineEQ r -> ()
rnf :: LineEQ r -> ()
NFData)
  deriving stock ((forall x. LineEQ r -> Rep (LineEQ r) x)
-> (forall x. Rep (LineEQ r) x -> LineEQ r) -> Generic (LineEQ r)
forall x. Rep (LineEQ r) x -> LineEQ r
forall x. LineEQ r -> Rep (LineEQ r) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall r x. Rep (LineEQ r) x -> LineEQ r
forall r x. LineEQ r -> Rep (LineEQ r) x
$cfrom :: forall r x. LineEQ r -> Rep (LineEQ r) x
from :: forall x. LineEQ r -> Rep (LineEQ r) x
$cto :: forall r x. Rep (LineEQ r) x -> LineEQ r
to :: forall x. Rep (LineEQ r) x -> LineEQ r
Generic)

-- | Constructs a line in R^2, i.e. a line for the equation \(y = ax + b\)
pattern LineEQ     :: r -> r -> LineEQ r
pattern $bLineEQ :: forall r. r -> r -> LineEQ r
$mLineEQ :: forall {r} {r}. LineEQ r -> (r -> r -> r) -> ((# #) -> r) -> r
LineEQ a b = MkLineEQ (NonVerticalHyperPlane (Vector2 a b))
{-# COMPLETE LineEQ #-}

type instance NumType   (LineEQ r) = r
type instance Dimension (LineEQ r) = 2


-- deriving instance Eq  (VectorFamily' 2 r) => Eq  (LineEQ r)
-- deriving instance Ord (VectorFamily' 2 r) => Ord (LineEQ r)

-- instance Constrained LineEQ where
--   type Dom LineEQ r = OptCVector_ 2 r
-- instance CFunctor LineEQ where
--   cmap f (LineEQ a b) = LineEQ (f a) (f b)
-- instance CTraversable LineEQ where
--   ctraverse f (LineEQ a b) = LineEQ <$> f a <*> f b
-- instance CFoldable LineEQ where
--   cfoldMap f (LineEQ a b) = f a <> f b


instance (Show r) => Show (LineEQ r) where
  showsPrec :: Int -> LineEQ r -> ShowS
showsPrec Int
k (LineEQ r
a r
b) = Bool -> ShowS -> ShowS
showParen (Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
appPrec) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
                              String -> ShowS
showString String
"LineEQ "
                            ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> r -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) r
a
                            ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
                            ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> r -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) r
b

appPrec :: Int
appPrec :: Int
appPrec = Int
10

instance (Read r) => Read (LineEQ r) where
  readPrec :: ReadPrec (LineEQ r)
readPrec = ReadPrec (LineEQ r) -> ReadPrec (LineEQ r)
forall a. ReadPrec a -> ReadPrec a
parens (Int -> ReadPrec (LineEQ r) -> ReadPrec (LineEQ r)
forall a. Int -> ReadPrec a -> ReadPrec a
prec Int
appPrec (ReadPrec (LineEQ r) -> ReadPrec (LineEQ r))
-> ReadPrec (LineEQ r) -> ReadPrec (LineEQ r)
forall a b. (a -> b) -> a -> b
$ do
                          Ident "LineEQ" <- ReadPrec Lexeme
lexP
                          a <- step readPrec
                          b <- step readPrec
                          return (LineEQ a b))

instance ( MkHyperPlaneConstraints 2 r
         ) => HyperPlane_ (LineEQ r) 2 r where
  onHyperPlane :: forall point.
(Point_ point 2 r, Eq r, Num r) =>
point -> LineEQ r -> Bool
onHyperPlane = point -> LineEQ r -> Bool
forall line (d :: Nat) point r.
(HasOnLine line d, Point_ point d r, Num r, Eq r, r ~ NumType line,
 d ~ Dimension line) =>
point -> line -> Bool
forall point r.
(Point_ point 2 r, Num r, Eq r, r ~ NumType (LineEQ r),
 2 ~ Dimension (LineEQ r)) =>
point -> LineEQ r -> Bool
onLine

instance ( MkHyperPlaneConstraints 2 r
         , Fractional r, Eq r
         ) => ConstructableHyperPlane_ (LineEQ r) 2 r where
  -- | pre: the last component is not zero
  hyperPlaneFromEquation :: HyperPlaneFromEquationConstraint (LineEQ r) 2 r =>
Vector (2 + 1) r -> LineEQ r
hyperPlaneFromEquation = NonVerticalHyperPlane 2 r -> LineEQ r
forall r. NonVerticalHyperPlane 2 r -> LineEQ r
MkLineEQ
                         (NonVerticalHyperPlane 2 r -> LineEQ r)
-> (Vector 3 r -> NonVerticalHyperPlane 2 r)
-> Vector 3 r
-> LineEQ r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall hyperPlane (d :: Nat) r.
(ConstructableHyperPlane_ hyperPlane d r,
 HyperPlaneFromEquationConstraint hyperPlane d r) =>
Vector (d + 1) r -> hyperPlane
hyperPlaneFromEquation @(NonVerticalHyperPlane 2 r)
  {-# INLINE hyperPlaneFromEquation #-}
  fromPointAndNormal :: forall point.
(Point_ point 2 r, Num r) =>
point -> Vector 2 r -> LineEQ r
fromPointAndNormal point
p = NonVerticalHyperPlane 2 r -> LineEQ r
forall r. NonVerticalHyperPlane 2 r -> LineEQ r
MkLineEQ (NonVerticalHyperPlane 2 r -> LineEQ r)
-> (Vector 2 r -> NonVerticalHyperPlane 2 r)
-> Vector 2 r
-> LineEQ r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. point -> Vector 2 r -> NonVerticalHyperPlane 2 r
forall point.
(Point_ point 2 r, Num r) =>
point -> Vector 2 r -> NonVerticalHyperPlane 2 r
forall hyperPlane (d :: Nat) r point.
(ConstructableHyperPlane_ hyperPlane d r, Point_ point d r,
 Num r) =>
point -> Vector d r -> hyperPlane
fromPointAndNormal point
p
  {-# INLINE fromPointAndNormal #-}

instance ( MkHyperPlaneConstraints 2 r, Num r
         ) => NonVerticalHyperPlane_ (LineEQ r) 2 r where
  evalAt :: forall point.
(Num r, 1 <= 2, Point_ point (2 - 1) r) =>
point -> LineEQ r -> r
evalAt point
p = r -> LineEQ r -> r
forall r. Num r => r -> LineEQ r -> r
evalAt' (r -> LineEQ r -> r) -> r -> LineEQ r -> r
forall a b. (a -> b) -> a -> b
$ point
ppoint -> Getting r point r -> r
forall s a. s -> Getting a s a -> a
^.Getting r point r
forall (d :: Nat) point r.
(1 <= d, Point_ point d r) =>
IndexedLens' Int point r
IndexedLens' Int point r
xCoord
  hyperPlaneCoefficients :: Lens' (LineEQ r) (Vector 2 r)
hyperPlaneCoefficients = (Vector 2 r -> f (Vector 2 r)) -> LineEQ r -> f (LineEQ r)
forall s t a b. (Coercible s a, Coercible t b) => Iso s t a b
Iso (LineEQ r) (LineEQ r) (Vector 2 r) (Vector 2 r)
coerced

instance HasOnLine (LineEQ r) 2 where
  onLine :: forall point r.
(Point_ point 2 r, Num r, Eq r, r ~ NumType (LineEQ r),
 2 ~ Dimension (LineEQ r)) =>
point -> LineEQ r -> Bool
onLine point
q LineEQ r
l = r -> LineEQ r -> r
forall r. Num r => r -> LineEQ r -> r
evalAt' (point
qpoint -> Getting r point r -> r
forall s a. s -> Getting a s a -> a
^.Getting r point r
forall (d :: Nat) point r.
(1 <= d, Point_ point d r) =>
IndexedLens' Int point r
IndexedLens' Int point r
xCoord) LineEQ r
l r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== point
qpoint -> Getting r point r -> r
forall s a. s -> Getting a s a -> a
^.Getting r point r
forall (d :: Nat) point r.
(2 <= d, Point_ point d r) =>
IndexedLens' Int point r
IndexedLens' Int point r
yCoord
  {-# INLINE onLine #-}

-- instance Fractional r => Line_ (LineEQ r) 2 r where
--   fromPointAndVec (Point2_ px py) (Vector2 vx vy) = let a = vy/vx
--                                                     in LineEQ a (py-px*a)
--   -- in principle we get py = a*px + b, with a = (vy/vx), and thus b=py - px*(vy/vx)

  -- FIMXE: I guess this function will be partial; i.e. when vx = 0 this does not work.



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

-- | The intersection of two lines is either: NoIntersection, a point or a line.
type instance Intersection (LineEQ r) (LineEQ r) =
  Maybe (LineLineIntersection (LineEQ r))


instance (Eq r) => HasIntersectionWith (LineEQ r) (LineEQ r) where
  (LineEQ r
a r
b) intersects :: LineEQ r -> LineEQ r -> Bool
`intersects` (LineEQ r
a' r
b') = r
a r -> r -> Bool
forall a. Eq a => a -> a -> Bool
/= r
a' Bool -> Bool -> Bool
|| r
b r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
b'
  -- in case the slope are different, we certainly intersect. If the slopes are equal
  -- ( and thus  a /= b == False ) the lines only intersect if their intercepts are also equal.

instance (Eq r, Fractional r)
         => IsIntersectableWith (LineEQ r) (LineEQ r) where
  l :: LineEQ r
l@(LineEQ r
a r
b) intersect :: LineEQ r -> LineEQ r -> Intersection (LineEQ r) (LineEQ r)
`intersect` (LineEQ r
a' r
b')
    | r
a r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
a'   = if r
b r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
b' then LineLineIntersectionG r (LineEQ r)
-> Maybe (LineLineIntersectionG r (LineEQ r))
forall a. a -> Maybe a
Just (LineEQ r -> LineLineIntersectionG r (LineEQ r)
forall r line. line -> LineLineIntersectionG r line
Line_x_Line_Line LineEQ r
l) else Maybe (LineLineIntersectionG r (LineEQ r))
Intersection (LineEQ r) (LineEQ r)
forall a. Maybe a
Nothing
    | Bool
otherwise = let x :: r
x = (r
b'r -> r -> r
forall a. Num a => a -> a -> a
-r
b) r -> r -> r
forall a. Fractional a => a -> a -> a
/ (r
ar -> r -> r
forall a. Num a => a -> a -> a
-r
a')
                  in LineLineIntersectionG r (LineEQ r)
-> Maybe (LineLineIntersectionG r (LineEQ r))
LineLineIntersectionG r (LineEQ r)
-> Intersection (LineEQ r) (LineEQ r)
forall a. a -> Maybe a
Just (LineLineIntersectionG r (LineEQ r)
 -> Intersection (LineEQ r) (LineEQ r))
-> (Point 2 r -> LineLineIntersectionG r (LineEQ r))
-> Point 2 r
-> Intersection (LineEQ r) (LineEQ r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Point 2 r -> LineLineIntersectionG r (LineEQ r)
forall r line. Point 2 r -> LineLineIntersectionG r line
Line_x_Line_Point (Point 2 r -> Intersection (LineEQ r) (LineEQ r))
-> Point 2 r -> Intersection (LineEQ r) (LineEQ r)
forall a b. (a -> b) -> a -> b
$ r -> r -> Point 2 r
forall r. r -> r -> Point 2 r
Point2 r
x (r -> LineEQ r -> r
forall r. Num r => r -> LineEQ r -> r
evalAt' r
x LineEQ r
l)


type instance Intersection (LineEQ r :+ extra) (LineEQ r :+ extra') =
  Maybe (LineLineIntersection (LineEQ r :+ extra))

-- instance (Eq r) => HasIntersectionWith (LineEQ r :+ extra) (LineEQ r :+ extra') where
--   l `intersects` m = (l^.core) `intersects` (m^.core)

instance (HasIntersectionWith (LineEQ r :+ extra) (LineEQ r :+ extra'), Fractional r, Eq r)
          => IsIntersectableWith (LineEQ r :+ extra) (LineEQ r :+ extra') where
  LineEQ r :+ extra
l intersect :: (LineEQ r :+ extra)
-> (LineEQ r :+ extra')
-> Intersection (LineEQ r :+ extra) (LineEQ r :+ extra')
`intersect` LineEQ r :+ extra'
m = LineLineIntersectionG r (LineEQ r)
-> LineLineIntersectionG r (LineEQ r :+ extra)
tag (LineLineIntersectionG r (LineEQ r)
 -> LineLineIntersectionG r (LineEQ r :+ extra))
-> Maybe (LineLineIntersectionG r (LineEQ r))
-> Maybe (LineLineIntersectionG r (LineEQ r :+ extra))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (LineEQ r :+ extra
l(LineEQ r :+ extra)
-> Getting (LineEQ r) (LineEQ r :+ extra) (LineEQ r) -> LineEQ r
forall s a. s -> Getting a s a -> a
^.Getting (LineEQ r) (LineEQ r :+ extra) (LineEQ r)
forall core extra core' (f :: * -> *).
Functor f =>
(core -> f core') -> (core :+ extra) -> f (core' :+ extra)
core) LineEQ r -> LineEQ r -> Intersection (LineEQ r) (LineEQ r)
forall g h. IsIntersectableWith g h => g -> h -> Intersection g h
`intersect` (LineEQ r :+ extra'
m(LineEQ r :+ extra')
-> Getting (LineEQ r) (LineEQ r :+ extra') (LineEQ r) -> LineEQ r
forall s a. s -> Getting a s a -> a
^.Getting (LineEQ r) (LineEQ r :+ extra') (LineEQ r)
forall core extra core' (f :: * -> *).
Functor f =>
(core -> f core') -> (core :+ extra) -> f (core' :+ extra)
core)
    where
      tag :: LineLineIntersectionG r (LineEQ r)
-> LineLineIntersectionG r (LineEQ r :+ extra)
tag = \case
        Line_x_Line_Point Point 2 r
p     -> Point 2 r -> LineLineIntersectionG r (LineEQ r :+ extra)
forall r line. Point 2 r -> LineLineIntersectionG r line
Line_x_Line_Point Point 2 r
p
        Line_x_Line_Line LineEQ r
_lCore -> (LineEQ r :+ extra) -> LineLineIntersectionG r (LineEQ r :+ extra)
forall r line. line -> LineLineIntersectionG r line
Line_x_Line_Line LineEQ r :+ extra
l -- the line we return is the left line

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

type instance Intersection (LineEQ r) (HyperPlane 2 r) =
  Maybe (LineLineIntersection (LineEQ r))

instance (Eq r, Fractional r
         ) => HasIntersectionWith (LineEQ r) (HyperPlane 2 r) where
  (LineEQ r
a r
_) intersects :: LineEQ r -> HyperPlane 2 r -> Bool
`intersects` (HyperPlane (Vector3 r
_ r
a' r
b'))
    = r
b' r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
0 Bool -> Bool -> Bool
|| r
a r -> r -> Bool
forall a. Eq a => a -> a -> Bool
/= (r
a'r -> r -> r
forall a. Fractional a => a -> a -> a
/ (-r
b'))

instance (Eq r, Fractional r)
         => IsIntersectableWith (LineEQ r) (HyperPlane 2 r) where
  l :: LineEQ r
l@(LineEQ r
a r
b) intersect :: LineEQ r
-> HyperPlane 2 r -> Intersection (LineEQ r) (HyperPlane 2 r)
`intersect` (HyperPlane (Vector3 r
c' r
a' r
b'))
      | r
b' r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
0   = r -> Maybe (LineLineIntersectionG r (LineEQ r))
point (r -> Maybe (LineLineIntersectionG r (LineEQ r)))
-> r -> Maybe (LineLineIntersectionG r (LineEQ r))
forall a b. (a -> b) -> a -> b
$ r
c'r -> r -> r
forall a. Fractional a => a -> a -> a
/ (-r
a')
      | r
a r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
d'   = if r
b r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
e' then LineLineIntersectionG r (LineEQ r)
-> Maybe (LineLineIntersectionG r (LineEQ r))
forall a. a -> Maybe a
Just (LineEQ r -> LineLineIntersectionG r (LineEQ r)
forall r line. line -> LineLineIntersectionG r line
Line_x_Line_Line LineEQ r
l) else Maybe (LineLineIntersectionG r (LineEQ r))
Intersection (LineEQ r) (HyperPlane 2 r)
forall a. Maybe a
Nothing
      | Bool
otherwise = r -> Maybe (LineLineIntersectionG r (LineEQ r))
point (r -> Maybe (LineLineIntersectionG r (LineEQ r)))
-> r -> Maybe (LineLineIntersectionG r (LineEQ r))
forall a b. (a -> b) -> a -> b
$ (r
e'r -> r -> r
forall a. Num a => a -> a -> a
-r
b) r -> r -> r
forall a. Fractional a => a -> a -> a
/ (r
ar -> r -> r
forall a. Num a => a -> a -> a
-r
d')
    where
      d' :: r
d' = r
a'r -> r -> r
forall a. Fractional a => a -> a -> a
/(-r
b')
      e' :: r
e' = r
c'r -> r -> r
forall a. Fractional a => a -> a -> a
/(-r
b')

      point :: r -> Maybe (LineLineIntersectionG r (LineEQ r))
point r
x = LineLineIntersectionG r (LineEQ r)
-> Maybe (LineLineIntersectionG r (LineEQ r))
forall a. a -> Maybe a
Just (LineLineIntersectionG r (LineEQ r)
 -> Maybe (LineLineIntersectionG r (LineEQ r)))
-> (Point 2 r -> LineLineIntersectionG r (LineEQ r))
-> Point 2 r
-> Maybe (LineLineIntersectionG r (LineEQ r))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Point 2 r -> LineLineIntersectionG r (LineEQ r)
forall r line. Point 2 r -> LineLineIntersectionG r line
Line_x_Line_Point (Point 2 r -> Maybe (LineLineIntersectionG r (LineEQ r)))
-> Point 2 r -> Maybe (LineLineIntersectionG r (LineEQ r))
forall a b. (a -> b) -> a -> b
$ r -> r -> Point 2 r
forall r. r -> r -> Point 2 r
Point2 r
x (r -> LineEQ r -> r
forall r. Num r => r -> LineEQ r -> r
evalAt' r
x LineEQ r
l)


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

type instance Intersection (HyperPlane 2 r) (HyperPlane 2 r) =
  Maybe (LineLineIntersection (HyperPlane 2 r))


-- instance ( Num r, Eq r
--          ) => HasIntersectionWith (HyperPlane 2 r) (HyperPlane 2 r) where
--   l `intersects` h = not (isParallelTo l h) || l == h
-- see Hyperplane.Intersection instance
  -- two dimensional hyperplanes are lines; they intersect if they are not parallel, and in
  -- case they are parallel they better be same line

  -- l@(HyperPlane2 c1 a1 b1) `intersects` h@(HyperPlane2 c2 a2 b2)
  --   | b1 == b2  = if a1 == a2 then c1 == c2 else True
  --   | otherwise = True

    -- if b1 == b2, then

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

-- | Evaluate the line at at given position.
evalAt'                :: Num r => r -> LineEQ r -> r
evalAt' :: forall r. Num r => r -> LineEQ r -> r
evalAt' r
x (LineEQ r
a r
b) = r
ar -> r -> r
forall a. Num a => a -> a -> a
*r
x r -> r -> r
forall a. Num a => a -> a -> a
+ r
b
-- TODO: it would be nice if this was actually just evalAt from the typeclass ....

-- evalAt''   :: Fractional r => r -> LineEQ r -> r
-- evalAt'' p = evalAt (Point1 p)

-- evalAt''   :: ( Fractional r, OptCVector_ 2 r
--               , OptCVector_ 3 r, OptMetric_ 2 r
--               ) => r -> LineEQ r -> r
-- evalAt'' x = evalAt (Point1 x)


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


-- -- | Lines are transformable, via line segments
-- instance ( Fractional r
--          , TransformationConstraints 2 r
--          , OptCVector_ 2 r, OptMetric_ 2 r, OptCVector_ 3 r
--          ) => IsTransformable (LineEQ r) where
--   -- | Warning, this may create vertical lines, which cannot be
--   -- represented by this type. So be careful.
--   transformBy t (LineEQ a b) = lineThrough p' q'
--     where
--       p' = transformBy t (Point2 0 b)
--       q' = transformBy t (Point2 1 (a + b))



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