{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wall #-}

-- | A 2-dimensional point.
module NumHask.Space.Point
  ( Point (..),
    rotateP,
    gridP,
    dotP,
    (<.>),
    crossP,
    flipY,
    Line (..),
    lineSolve,
    lineDistance,
    closestPoint,
    lineIntersect,
    translate,
    scaleT,
    skew,
  )
where

import Data.Distributive
import Data.Functor.Classes
import Data.Functor.Rep
import NumHask.Prelude hiding (Distributive)
import qualified NumHask.Prelude as P
import NumHask.Space.Range
import NumHask.Space.Types
import System.Random
import System.Random.Stateful

-- $setup
-- >>> import NumHask.Prelude
-- >>> import NumHask.Space
-- >>> :set -XFlexibleContexts

-- | A 2-dimensional Point of a's
--
-- In contrast with a tuple, a Point is functorial over both arguments.
--
-- >>> let p = Point 1 1
-- >>> p + p
-- Point 2 2
-- >>> (2*) <$> p
-- Point 2 2
--
-- A major reason for this bespoke treatment (compared to just using linear, say) is that Points do not have maximums and minimums but they do form a lattice, and this is useful for folding sets of points to find out the (rectangular) Space they occupy.
--
-- >>> Point 0 1 /\ Point 1 0
-- Point 0 0
-- >>> Point 0 1 \/ Point 1 0
-- Point 1 1
--
-- This is used extensively in [chart-svg](https://hackage.haskell.org/package/chart-svg) to ergonomically obtain chart areas.
--
-- > unsafeSpace1 [Point 1 0, Point 0 1] :: Rect Double
-- Rect 0.0 1.0 0.0 1.0
data Point a = Point
  { Point a -> a
_x :: a,
    Point a -> a
_y :: a
  }
  deriving (Point a -> Point a -> Bool
(Point a -> Point a -> Bool)
-> (Point a -> Point a -> Bool) -> Eq (Point a)
forall a. Eq a => Point a -> Point a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Point a -> Point a -> Bool
$c/= :: forall a. Eq a => Point a -> Point a -> Bool
== :: Point a -> Point a -> Bool
$c== :: forall a. Eq a => Point a -> Point a -> Bool
Eq, (forall x. Point a -> Rep (Point a) x)
-> (forall x. Rep (Point a) x -> Point a) -> Generic (Point a)
forall x. Rep (Point a) x -> Point a
forall x. Point a -> Rep (Point a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Point a) x -> Point a
forall a x. Point a -> Rep (Point a) x
$cto :: forall a x. Rep (Point a) x -> Point a
$cfrom :: forall a x. Point a -> Rep (Point a) x
Generic)

instance (Show a) => Show (Point a) where
  show :: Point a -> String
show (Point a
a a
b) = String
"Point " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> a -> String
forall a. Show a => a -> String
show a
a String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> a -> String
forall a. Show a => a -> String
show a
b

instance Functor Point where
  fmap :: (a -> b) -> Point a -> Point b
fmap a -> b
f (Point a
a a
b) = b -> b -> Point b
forall a. a -> a -> Point a
Point (a -> b
f a
a) (a -> b
f a
b)

instance Eq1 Point where
  liftEq :: (a -> b -> Bool) -> Point a -> Point b -> Bool
liftEq a -> b -> Bool
f (Point a
a a
b) (Point b
c b
d) = a -> b -> Bool
f a
a b
c Bool -> Bool -> Bool
&& a -> b -> Bool
f a
b b
d

instance Show1 Point where
  liftShowsPrec :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> Point a -> ShowS
liftShowsPrec Int -> a -> ShowS
sp [a] -> ShowS
_ Int
d (Point a
a a
b) = (Int -> a -> ShowS)
-> (Int -> a -> ShowS) -> String -> Int -> a -> a -> ShowS
forall a b.
(Int -> a -> ShowS)
-> (Int -> b -> ShowS) -> String -> Int -> a -> b -> ShowS
showsBinaryWith Int -> a -> ShowS
sp Int -> a -> ShowS
sp String
"Point" Int
d a
a a
b

instance Applicative Point where
  pure :: a -> Point a
pure a
a = a -> a -> Point a
forall a. a -> a -> Point a
Point a
a a
a

  (Point a -> b
fa a -> b
fb) <*> :: Point (a -> b) -> Point a -> Point b
<*> Point a
a a
b = b -> b -> Point b
forall a. a -> a -> Point a
Point (a -> b
fa a
a) (a -> b
fb a
b)

instance Monad Point where
  Point a
a a
b >>= :: Point a -> (a -> Point b) -> Point b
>>= a -> Point b
f = b -> b -> Point b
forall a. a -> a -> Point a
Point b
a' b
b'
    where
      Point b
a' b
_ = a -> Point b
f a
a
      Point b
_ b
b' = a -> Point b
f a
b

instance Foldable Point where
  foldMap :: (a -> m) -> Point a -> m
foldMap a -> m
f (Point a
a a
b) = a -> m
f a
a m -> m -> m
forall a. Monoid a => a -> a -> a
`mappend` a -> m
f a
b

instance Traversable Point where
  traverse :: (a -> f b) -> Point a -> f (Point b)
traverse a -> f b
f (Point a
a a
b) = b -> b -> Point b
forall a. a -> a -> Point a
Point (b -> b -> Point b) -> f b -> f (b -> Point b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f b
f a
a f (b -> Point b) -> f b -> f (Point b)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> a -> f b
f a
b

instance (Semigroup a) => Semigroup (Point a) where
  (Point a
a0 a
b0) <> :: Point a -> Point a -> Point a
<> (Point a
a1 a
b1) = a -> a -> Point a
forall a. a -> a -> Point a
Point (a
a0 a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
a1) (a
b0 a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b1)

instance (Semigroup a, Monoid a) => Monoid (Point a) where
  mempty :: Point a
mempty = a -> a -> Point a
forall a. a -> a -> Point a
Point a
forall a. Monoid a => a
mempty a
forall a. Monoid a => a
mempty

  mappend :: Point a -> Point a -> Point a
mappend = Point a -> Point a -> Point a
forall a. Semigroup a => a -> a -> a
(<>)

instance (Bounded a) => Bounded (Point a) where
  minBound :: Point a
minBound = a -> a -> Point a
forall a. a -> a -> Point a
Point a
forall a. Bounded a => a
minBound a
forall a. Bounded a => a
minBound

  maxBound :: Point a
maxBound = a -> a -> Point a
forall a. a -> a -> Point a
Point a
forall a. Bounded a => a
maxBound a
forall a. Bounded a => a
maxBound

instance (Additive a) => Additive (Point a) where
  (Point a
a0 a
b0) + :: Point a -> Point a -> Point a
+ (Point a
a1 a
b1) = a -> a -> Point a
forall a. a -> a -> Point a
Point (a
a0 a -> a -> a
forall a. Additive a => a -> a -> a
+ a
a1) (a
b0 a -> a -> a
forall a. Additive a => a -> a -> a
+ a
b1)
  zero :: Point a
zero = a -> a -> Point a
forall a. a -> a -> Point a
Point a
forall a. Additive a => a
zero a
forall a. Additive a => a
zero

instance (Subtractive a) => Subtractive (Point a) where
  negate :: Point a -> Point a
negate = (a -> a) -> Point a -> Point a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Subtractive a => a -> a
negate

instance (Multiplicative a) => Multiplicative (Point a) where
  (Point a
a0 a
b0) * :: Point a -> Point a -> Point a
* (Point a
a1 a
b1) = a -> a -> Point a
forall a. a -> a -> Point a
Point (a
a0 a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
a1) (a
b0 a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
b1)
  one :: Point a
one = a -> a -> Point a
forall a. a -> a -> Point a
Point a
forall a. Multiplicative a => a
one a
forall a. Multiplicative a => a
one

instance (P.Distributive a) => P.Distributive (Point a)

instance (Field a) => Field (Point a)

instance (Signed a) => Signed (Point a) where
  sign :: Point a -> Point a
sign = (a -> a) -> Point a -> Point a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Signed a => a -> a
sign
  abs :: Point a -> Point a
abs = (a -> a) -> Point a -> Point a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Signed a => a -> a
abs

instance (Divisive a) => Divisive (Point a) where
  recip :: Point a -> Point a
recip = (a -> a) -> Point a -> Point a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Divisive a => a -> a
recip

instance Distributive Point where
  collect :: (a -> Point b) -> f a -> Point (f b)
collect a -> Point b
f f a
x = f b -> f b -> Point (f b)
forall a. a -> a -> Point a
Point (Point b -> b
forall a. Point a -> a
getL (Point b -> b) -> (a -> Point b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Point b
f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f a
x) (Point b -> b
forall a. Point a -> a
getR (Point b -> b) -> (a -> Point b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Point b
f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f a
x)
    where
      getL :: Point a -> a
getL (Point a
l a
_) = a
l
      getR :: Point a -> a
getR (Point a
_ a
r) = a
r

instance (Additive a) => AdditiveAction (Point a) a where
  .+ :: a -> Point a -> Point a
(.+) a
a (Point a
x a
y) = a -> a -> Point a
forall a. a -> a -> Point a
Point (a
a a -> a -> a
forall a. Additive a => a -> a -> a
+ a
x) (a
a a -> a -> a
forall a. Additive a => a -> a -> a
+ a
y)

instance (Subtractive a) => SubtractiveAction (Point a) a where
  .- :: a -> Point a -> Point a
(.-) a
a (Point a
x a
y) = a -> a -> Point a
forall a. a -> a -> Point a
Point (a
a a -> a -> a
forall a. Subtractive a => a -> a -> a
- a
x) (a
a a -> a -> a
forall a. Subtractive a => a -> a -> a
- a
y)

instance (Multiplicative a) => MultiplicativeAction (Point a) a where
  .* :: a -> Point a -> Point a
(.*) a
a (Point a
x a
y) = a -> a -> Point a
forall a. a -> a -> Point a
Point (a
a a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
x) (a
a a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
y)

instance (Divisive a) => DivisiveAction (Point a) a where
  ./ :: a -> Point a -> Point a
(./) a
a (Point a
x a
y) = a -> a -> Point a
forall a. a -> a -> Point a
Point (a
a a -> a -> a
forall a. Divisive a => a -> a -> a
/ a
x) (a
a a -> a -> a
forall a. Divisive a => a -> a -> a
/ a
y)

instance Representable Point where
  type Rep Point = Bool

  tabulate :: (Rep Point -> a) -> Point a
tabulate Rep Point -> a
f = a -> a -> Point a
forall a. a -> a -> Point a
Point (Rep Point -> a
f Bool
Rep Point
False) (Rep Point -> a
f Bool
Rep Point
True)

  index :: Point a -> Rep Point -> a
index (Point a
l a
_) Rep Point
False = a
l
  index (Point a
_ a
r) Rep Point
True = a
r

instance (Ord a) => JoinSemiLattice (Point a) where
  \/ :: Point a -> Point a -> Point a
(\/) (Point a
x a
y) (Point a
x' a
y') = a -> a -> Point a
forall a. a -> a -> Point a
Point (a -> a -> a
forall a. Ord a => a -> a -> a
max a
x a
x') (a -> a -> a
forall a. Ord a => a -> a -> a
max a
y a
y')

instance (Ord a) => MeetSemiLattice (Point a) where
  /\ :: Point a -> Point a -> Point a
(/\) (Point a
x a
y) (Point a
x' a
y') = a -> a -> Point a
forall a. a -> a -> Point a
Point (a -> a -> a
forall a. Ord a => a -> a -> a
min a
x a
x') (a -> a -> a
forall a. Ord a => a -> a -> a
min a
y a
y')

instance
  (ExpField a, Eq a) =>
  Norm (Point a) a
  where
  norm :: Point a -> a
norm (Point a
x a
y) = a -> a
forall a. ExpField a => a -> a
sqrt (a
x a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
x a -> a -> a
forall a. Additive a => a -> a -> a
+ a
y a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
y)
  basis :: Point a -> Point a
basis Point a
p = let m :: a
m = Point a -> a
forall a b. Norm a b => a -> b
norm Point a
p in Point a -> Point a -> Bool -> Point a
forall a. a -> a -> Bool -> a
bool (Point a
p Point a -> a -> Point a
forall m a. (MultiplicativeAction m a, Divisive a) => m -> a -> m
/. a
m) Point a
forall a. Additive a => a
zero (a
m a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. Additive a => a
zero)

-- | angle formed by a vector from the origin to a Point and the x-axis (Point 1 0). Note that an angle between two points p1 & p2 is thus angle p2 - angle p1
instance (TrigField a) => Direction (Point a) a where
  angle :: Point a -> a
angle (Point a
x a
y) = a -> a -> a
forall a. TrigField a => a -> a -> a
atan2 a
y a
x
  ray :: a -> Point a
ray a
x = a -> a -> Point a
forall a. a -> a -> Point a
Point (a -> a
forall a. TrigField a => a -> a
cos a
x) (a -> a
forall a. TrigField a => a -> a
sin a
x)

instance (UniformRange a) => UniformRange (Point a) where
  uniformRM :: (Point a, Point a) -> g -> m (Point a)
uniformRM (Point a
x a
y, Point a
x' a
y') g
g =
    a -> a -> Point a
forall a. a -> a -> Point a
Point (a -> a -> Point a) -> m a -> m (a -> Point a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a, a) -> g -> m a
forall a g (m :: * -> *).
(UniformRange a, StatefulGen g m) =>
(a, a) -> g -> m a
uniformRM (a
x, a
x') g
g m (a -> Point a) -> m a -> m (Point a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (a, a) -> g -> m a
forall a g (m :: * -> *).
(UniformRange a, StatefulGen g m) =>
(a, a) -> g -> m a
uniformRM (a
y, a
y') g
g

instance (Multiplicative a, Additive a) => Affinity (Point a) a where
  transform :: Transform a -> Point a -> Point a
transform (Transform a
a a
b a
c a
d a
e a
f) (Point a
x a
y) =
    a -> a -> Point a
forall a. a -> a -> Point a
Point (a
a a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
x a -> a -> a
forall a. Additive a => a -> a -> a
+ a
b a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
y a -> a -> a
forall a. Additive a => a -> a -> a
+ a
c) (a
d a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
x a -> a -> a
forall a. Additive a => a -> a -> a
+ a
e a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
y a -> a -> a
forall a. Additive a => a -> a -> a
+ a
f)

-- | move an 'Affinity' by a 'Point'
translate :: (TrigField a) => Point a -> Transform a
translate :: Point a -> Transform a
translate (Point a
x a
y) = a -> a -> a -> a -> a -> a -> Transform a
forall a. a -> a -> a -> a -> a -> a -> Transform a
Transform a
forall a. Multiplicative a => a
one a
forall a. Additive a => a
zero a
x a
forall a. Additive a => a
zero a
forall a. Multiplicative a => a
one a
y

-- | scale an 'Affinity' by a 'Point'
scaleT :: (TrigField a) => Point a -> Transform a
scaleT :: Point a -> Transform a
scaleT (Point a
x a
y) = a -> a -> a -> a -> a -> a -> Transform a
forall a. a -> a -> a -> a -> a -> a -> Transform a
Transform a
x a
forall a. Additive a => a
zero a
forall a. Additive a => a
zero a
y a
forall a. Additive a => a
zero a
forall a. Additive a => a
zero

-- | Skew transform
--
-- x-axis skew
--
-- > skew (Point x 0)
skew :: (TrigField a) => Point a -> Transform a
skew :: Point a -> Transform a
skew (Point a
x a
y) = a -> a -> a -> a -> a -> a -> Transform a
forall a. a -> a -> a -> a -> a -> a -> Transform a
Transform a
forall a. Multiplicative a => a
one (a -> a
forall a. TrigField a => a -> a
tan a
x) a
forall a. Additive a => a
zero (a -> a
forall a. TrigField a => a -> a
tan a
y) a
forall a. Multiplicative a => a
one a
forall a. Additive a => a
zero

-- | rotate a point by x relative to the origin
--
-- >>> rotateP (pi/2) (Point 1 0)
-- Point 6.123233995736766e-17 1.0
rotateP :: (TrigField a) => a -> Point a -> Point a
rotateP :: a -> Point a -> Point a
rotateP a
d Point a
p = a -> Transform a
forall a. TrigField a => a -> Transform a
rotate a
d Transform a -> Point a -> Point a
forall a b. Affinity a b => Transform b -> a -> a
|. Point a
p

-- | Create Points for a formulae y = f(x) across an x range
--
-- >>> gridP (^^2) (Range 0 4) 4
-- [Point 0.0 0.0,Point 1.0 1.0,Point 2.0 4.0,Point 3.0 9.0,Point 4.0 16.0]
gridP :: (FieldSpace (Range a)) => (a -> a) -> Range a -> Grid (Range a) -> [Point a]
gridP :: (a -> a) -> Range a -> Grid (Range a) -> [Point a]
gridP a -> a
f Range a
r Grid (Range a)
g = (\a
x -> a -> a -> Point a
forall a. a -> a -> Point a
Point a
x (a -> a
f a
x)) (a -> Point a) -> [a] -> [Point a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Pos -> Range a -> Grid (Range a) -> [Element (Range a)]
forall s. FieldSpace s => Pos -> s -> Grid s -> [Element s]
grid Pos
OuterPos Range a
r Grid (Range a)
g

-- | dot product
dotP :: (Multiplicative a, Additive a) => Point a -> Point a -> a
dotP :: Point a -> Point a -> a
dotP (Point a
x a
y) (Point a
x' a
y') = a
x a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
x' a -> a -> a
forall a. Additive a => a -> a -> a
+ a
y a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
y'

infix 4 <.>

-- | dot product operator
(<.>) :: (Multiplicative a, Additive a) => Point a -> Point a -> a
<.> :: Point a -> Point a -> a
(<.>) = Point a -> Point a -> a
forall a. (Multiplicative a, Additive a) => Point a -> Point a -> a
dotP

-- | cross product
crossP :: (Multiplicative a, Subtractive a) => Point a -> Point a -> a
crossP :: Point a -> Point a -> a
crossP (Point a
x a
y) (Point a
x' a
y') = a
x a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
y' a -> a -> a
forall a. Subtractive a => a -> a -> a
- a
y a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
x'

-- | reflect on x-axis
flipY :: (Subtractive a) => Point a -> Point a
flipY :: Point a -> Point a
flipY (Point a
x a
y) = a -> a -> Point a
forall a. a -> a -> Point a
Point a
x (-a
y)

-- | A line is a composed of 2 'Point's
data Line a = Line
  { Line a -> Point a
lineStart :: Point a,
    Line a -> Point a
lineEnd :: Point a
  }
  deriving (Int -> Line a -> ShowS
[Line a] -> ShowS
Line a -> String
(Int -> Line a -> ShowS)
-> (Line a -> String) -> ([Line a] -> ShowS) -> Show (Line a)
forall a. Show a => Int -> Line a -> ShowS
forall a. Show a => [Line a] -> ShowS
forall a. Show a => Line a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Line a] -> ShowS
$cshowList :: forall a. Show a => [Line a] -> ShowS
show :: Line a -> String
$cshow :: forall a. Show a => Line a -> String
showsPrec :: Int -> Line a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Line a -> ShowS
Show, Line a -> Line a -> Bool
(Line a -> Line a -> Bool)
-> (Line a -> Line a -> Bool) -> Eq (Line a)
forall a. Eq a => Line a -> Line a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Line a -> Line a -> Bool
$c/= :: forall a. Eq a => Line a -> Line a -> Bool
== :: Line a -> Line a -> Bool
$c== :: forall a. Eq a => Line a -> Line a -> Bool
Eq, a -> Line b -> Line a
(a -> b) -> Line a -> Line b
(forall a b. (a -> b) -> Line a -> Line b)
-> (forall a b. a -> Line b -> Line a) -> Functor Line
forall a b. a -> Line b -> Line a
forall a b. (a -> b) -> Line a -> Line b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Line b -> Line a
$c<$ :: forall a b. a -> Line b -> Line a
fmap :: (a -> b) -> Line a -> Line b
$cfmap :: forall a b. (a -> b) -> Line a -> Line b
Functor, Line a -> Bool
(a -> m) -> Line a -> m
(a -> b -> b) -> b -> Line a -> b
(forall m. Monoid m => Line m -> m)
-> (forall m a. Monoid m => (a -> m) -> Line a -> m)
-> (forall m a. Monoid m => (a -> m) -> Line a -> m)
-> (forall a b. (a -> b -> b) -> b -> Line a -> b)
-> (forall a b. (a -> b -> b) -> b -> Line a -> b)
-> (forall b a. (b -> a -> b) -> b -> Line a -> b)
-> (forall b a. (b -> a -> b) -> b -> Line a -> b)
-> (forall a. (a -> a -> a) -> Line a -> a)
-> (forall a. (a -> a -> a) -> Line a -> a)
-> (forall a. Line a -> [a])
-> (forall a. Line a -> Bool)
-> (forall a. Line a -> Int)
-> (forall a. Eq a => a -> Line a -> Bool)
-> (forall a. Ord a => Line a -> a)
-> (forall a. Ord a => Line a -> a)
-> (forall a. Num a => Line a -> a)
-> (forall a. Num a => Line a -> a)
-> Foldable Line
forall a. Eq a => a -> Line a -> Bool
forall a. Num a => Line a -> a
forall a. Ord a => Line a -> a
forall m. Monoid m => Line m -> m
forall a. Line a -> Bool
forall a. Line a -> Int
forall a. Line a -> [a]
forall a. (a -> a -> a) -> Line a -> a
forall m a. Monoid m => (a -> m) -> Line a -> m
forall b a. (b -> a -> b) -> b -> Line a -> b
forall a b. (a -> b -> b) -> b -> Line a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: Line a -> a
$cproduct :: forall a. Num a => Line a -> a
sum :: Line a -> a
$csum :: forall a. Num a => Line a -> a
minimum :: Line a -> a
$cminimum :: forall a. Ord a => Line a -> a
maximum :: Line a -> a
$cmaximum :: forall a. Ord a => Line a -> a
elem :: a -> Line a -> Bool
$celem :: forall a. Eq a => a -> Line a -> Bool
length :: Line a -> Int
$clength :: forall a. Line a -> Int
null :: Line a -> Bool
$cnull :: forall a. Line a -> Bool
toList :: Line a -> [a]
$ctoList :: forall a. Line a -> [a]
foldl1 :: (a -> a -> a) -> Line a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Line a -> a
foldr1 :: (a -> a -> a) -> Line a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Line a -> a
foldl' :: (b -> a -> b) -> b -> Line a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Line a -> b
foldl :: (b -> a -> b) -> b -> Line a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Line a -> b
foldr' :: (a -> b -> b) -> b -> Line a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Line a -> b
foldr :: (a -> b -> b) -> b -> Line a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Line a -> b
foldMap' :: (a -> m) -> Line a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Line a -> m
foldMap :: (a -> m) -> Line a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Line a -> m
fold :: Line m -> m
$cfold :: forall m. Monoid m => Line m -> m
Foldable, Functor Line
Foldable Line
Functor Line
-> Foldable Line
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Line a -> f (Line b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Line (f a) -> f (Line a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Line a -> m (Line b))
-> (forall (m :: * -> *) a. Monad m => Line (m a) -> m (Line a))
-> Traversable Line
(a -> f b) -> Line a -> f (Line b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Line (m a) -> m (Line a)
forall (f :: * -> *) a. Applicative f => Line (f a) -> f (Line a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Line a -> m (Line b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Line a -> f (Line b)
sequence :: Line (m a) -> m (Line a)
$csequence :: forall (m :: * -> *) a. Monad m => Line (m a) -> m (Line a)
mapM :: (a -> m b) -> Line a -> m (Line b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Line a -> m (Line b)
sequenceA :: Line (f a) -> f (Line a)
$csequenceA :: forall (f :: * -> *) a. Applicative f => Line (f a) -> f (Line a)
traverse :: (a -> f b) -> Line a -> f (Line b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Line a -> f (Line b)
$cp2Traversable :: Foldable Line
$cp1Traversable :: Functor Line
Traversable)

instance (Multiplicative a, Additive a) => Affinity (Line a) a where
  transform :: Transform a -> Line a -> Line a
transform Transform a
t (Line Point a
s Point a
e) = Point a -> Point a -> Line a
forall a. Point a -> Point a -> Line a
Line (Transform a -> Point a -> Point a
forall a b. Affinity a b => Transform b -> a -> a
transform Transform a
t Point a
s) (Transform a -> Point a -> Point a
forall a b. Affinity a b => Transform b -> a -> a
transform Transform a
t Point a
e)

-- | Return the parameters (a, b, c) for the line equation @a*x + b*y + c = 0@.
lineSolve :: (ExpField a, Eq a) => Line a -> (a, a, a)
lineSolve :: Line a -> (a, a, a)
lineSolve (Line Point a
p1 Point a
p2) = (-a
my, a
mx, a
c)
  where
    m :: Point a
m@(Point a
mx a
my) = Point a -> Point a
forall a b. Norm a b => a -> a
basis (Point a
p2 Point a -> Point a -> Point a
forall a. Subtractive a => a -> a -> a
- Point a
p1)
    c :: a
c = Point a -> Point a -> a
forall a.
(Multiplicative a, Subtractive a) =>
Point a -> Point a -> a
crossP Point a
p1 Point a
m

-- | Return the signed distance from a point to the line.  If the
-- distance is negative, the point lies to the right of the line
lineDistance :: (ExpField a) => Line a -> Point a -> a
lineDistance :: Line a -> Point a -> a
lineDistance (Line (Point a
x1 a
y1) (Point a
x2 a
y2)) =
  let dy :: a
dy = a
y1 a -> a -> a
forall a. Subtractive a => a -> a -> a
- a
y2
      dx :: a
dx = a
x2 a -> a -> a
forall a. Subtractive a => a -> a -> a
- a
x1
      d :: a
d = a -> a
forall a. ExpField a => a -> a
sqrt (a
dx a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
dx a -> a -> a
forall a. Additive a => a -> a -> a
+ a
dy a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
dy)
   in a
dy a -> (Point a -> a) -> Point a -> a
`seq` a
dx a -> (Point a -> a) -> Point a -> a
`seq` a
d
        a -> (Point a -> a) -> Point a -> a
`seq` \(Point a
x a
y) -> (a
x a -> a -> a
forall a. Subtractive a => a -> a -> a
- a
x1) a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
dy a -> a -> a
forall a. Divisive a => a -> a -> a
/ a
d a -> a -> a
forall a. Additive a => a -> a -> a
+ (a
y a -> a -> a
forall a. Subtractive a => a -> a -> a
- a
y1) a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
dx a -> a -> a
forall a. Divisive a => a -> a -> a
/ a
d

-- | Return the point on the line closest to the given point.
closestPoint :: (Field a) => Line a -> Point a -> Point a
closestPoint :: Line a -> Point a -> Point a
closestPoint (Line Point a
p1 Point a
p2) Point a
p3 = a -> a -> Point a
forall a. a -> a -> Point a
Point a
px a
py
  where
    d :: Point a
d@(Point a
dx a
dy) = Point a
p2 Point a -> Point a -> Point a
forall a. Subtractive a => a -> a -> a
- Point a
p1
    u :: a
u = a
dy a -> a -> a
forall a. Multiplicative a => a -> a -> a
* Point a -> a
forall a. Point a -> a
_y Point a
p3 a -> a -> a
forall a. Additive a => a -> a -> a
+ a
dx a -> a -> a
forall a. Multiplicative a => a -> a -> a
* Point a -> a
forall a. Point a -> a
_x Point a
p3
    v :: a
v = Point a -> a
forall a. Point a -> a
_x Point a
p1 a -> a -> a
forall a. Multiplicative a => a -> a -> a
* Point a -> a
forall a. Point a -> a
_y Point a
p2 a -> a -> a
forall a. Subtractive a => a -> a -> a
- Point a -> a
forall a. Point a -> a
_x Point a
p2 a -> a -> a
forall a. Multiplicative a => a -> a -> a
* Point a -> a
forall a. Point a -> a
_y Point a
p1
    m :: a
m = Point a
d Point a -> Point a -> a
forall a. (Multiplicative a, Additive a) => Point a -> Point a -> a
<.> Point a
d
    px :: a
px = (a
dx a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
u a -> a -> a
forall a. Additive a => a -> a -> a
+ a
dy a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
v) a -> a -> a
forall a. Divisive a => a -> a -> a
/ a
m
    py :: a
py = (a
dy a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
u a -> a -> a
forall a. Subtractive a => a -> a -> a
- a
dx a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
v) a -> a -> a
forall a. Divisive a => a -> a -> a
/ a
m

-- | Calculate the intersection of two lines.  If the determinant is
-- less than tolerance (parallel or coincident lines), return Nothing.
lineIntersect :: (Ord a, Epsilon a, Signed a, Field a) => Line a -> Line a -> Maybe (Point a)
lineIntersect :: Line a -> Line a -> Maybe (Point a)
lineIntersect (Line Point a
p1 Point a
p2) (Line Point a
p3 Point a
p4)
  | a -> a
forall a. Signed a => a -> a
abs a
det a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
forall a. Epsilon a => a
epsilon = Maybe (Point a)
forall a. Maybe a
Nothing
  | Bool
otherwise = Point a -> Maybe (Point a)
forall a. a -> Maybe a
Just (Point a -> Maybe (Point a)) -> Point a -> Maybe (Point a)
forall a b. (a -> b) -> a -> b
$ (a
a a -> Point a -> Point a
forall m a. MultiplicativeAction m a => a -> m -> m
.* Point a
d2 Point a -> Point a -> Point a
forall a. Subtractive a => a -> a -> a
- a
b a -> Point a -> Point a
forall m a. MultiplicativeAction m a => a -> m -> m
.* Point a
d1) Point a -> a -> Point a
forall m a. (MultiplicativeAction m a, Divisive a) => m -> a -> m
/. a
det
  where
    d1 :: Point a
d1 = Point a
p1 Point a -> Point a -> Point a
forall a. Subtractive a => a -> a -> a
- Point a
p2
    d2 :: Point a
d2 = Point a
p3 Point a -> Point a -> Point a
forall a. Subtractive a => a -> a -> a
- Point a
p4
    det :: a
det = Point a -> Point a -> a
forall a.
(Multiplicative a, Subtractive a) =>
Point a -> Point a -> a
crossP Point a
d1 Point a
d2
    a :: a
a = Point a -> Point a -> a
forall a.
(Multiplicative a, Subtractive a) =>
Point a -> Point a -> a
crossP Point a
p1 Point a
p2
    b :: a
b = Point a -> Point a -> a
forall a.
(Multiplicative a, Subtractive a) =>
Point a -> Point a -> a
crossP Point a
p3 Point a
p4