{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}

-- | Specialized and inlined @V2 Float@.

module Geomancy.Vec2
  ( Vec2
  , vec2
  , withVec2
  , pattern WithVec2
  , fromTuple
  , convert

  , (^*)
  , (^/)
  , lerp

  , dot
  , normalize
  ) where

import Control.DeepSeq (NFData(rnf))
import Data.Coerce (Coercible, coerce)
import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
import Data.VectorSpace (VectorSpace)
import Foreign (Storable(..))
import Foreign.Ptr.Diff (peekDiffOff, pokeDiffOff)
import qualified Data.VectorSpace as VectorSpace

import Geomancy.Elementwise (Elementwise(..))
import Graphics.Gl.Block (Block(..))
import Geomancy.Gl.Funs (GlModf(..), GlNearest)

data Vec2 = Vec2
  {-# UNPACK #-} !Float
  {-# UNPACK #-} !Float
  deriving (Vec2 -> Vec2 -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Vec2 -> Vec2 -> Bool
$c/= :: Vec2 -> Vec2 -> Bool
== :: Vec2 -> Vec2 -> Bool
$c== :: Vec2 -> Vec2 -> Bool
Eq, Eq Vec2
Vec2 -> Vec2 -> Bool
Vec2 -> Vec2 -> Ordering
Vec2 -> Vec2 -> Vec2
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
min :: Vec2 -> Vec2 -> Vec2
$cmin :: Vec2 -> Vec2 -> Vec2
max :: Vec2 -> Vec2 -> Vec2
$cmax :: Vec2 -> Vec2 -> Vec2
>= :: Vec2 -> Vec2 -> Bool
$c>= :: Vec2 -> Vec2 -> Bool
> :: Vec2 -> Vec2 -> Bool
$c> :: Vec2 -> Vec2 -> Bool
<= :: Vec2 -> Vec2 -> Bool
$c<= :: Vec2 -> Vec2 -> Bool
< :: Vec2 -> Vec2 -> Bool
$c< :: Vec2 -> Vec2 -> Bool
compare :: Vec2 -> Vec2 -> Ordering
$ccompare :: Vec2 -> Vec2 -> Ordering
Ord, Int -> Vec2 -> ShowS
[Vec2] -> ShowS
Vec2 -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Vec2] -> ShowS
$cshowList :: [Vec2] -> ShowS
show :: Vec2 -> String
$cshow :: Vec2 -> String
showsPrec :: Int -> Vec2 -> ShowS
$cshowsPrec :: Int -> Vec2 -> ShowS
Show)

{-# INLINE vec2 #-}
vec2 :: Float -> Float -> Vec2
vec2 :: Float -> Float -> Vec2
vec2 = Float -> Float -> Vec2
Vec2

{-# INLINE withVec2 #-}
withVec2
  :: Vec2
  -> (Float -> Float -> r)
  -> r
withVec2 :: forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 (Vec2 Float
a Float
b) Float -> Float -> r
f = Float -> Float -> r
f Float
a Float
b

{-# INLINE convert #-}
convert :: Coercible v Vec2 => (Float -> a) -> (a -> a -> r) -> v -> r
convert :: forall v a r.
Coercible v Vec2 =>
(Float -> a) -> (a -> a -> r) -> v -> r
convert Float -> a
f a -> a -> r
t v
v =
  forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 (coerce :: forall a b. Coercible a b => a -> b
coerce v
v) \Float
a Float
b ->
    a -> a -> r
t (Float -> a
f Float
a) (Float -> a
f Float
b)

pattern WithVec2 :: Float -> Float -> Vec2
pattern $mWithVec2 :: forall {r}. Vec2 -> (Float -> Float -> r) -> ((# #) -> r) -> r
WithVec2 a b <- ((`withVec2` (,)) -> (a, b))
{-# COMPLETE WithVec2 #-}

{-# INLINE fromTuple #-}
fromTuple :: (Float, Float) -> Vec2
fromTuple :: (Float, Float) -> Vec2
fromTuple (Float
x, Float
y) = Float -> Float -> Vec2
vec2 Float
x Float
y

instance NFData Vec2 where
  rnf :: Vec2 -> ()
rnf Vec2{} = ()

type instance Element Vec2 = Float

instance MonoFunctor Vec2 where
  {-# INLINE omap #-}
  omap :: (Element Vec2 -> Element Vec2) -> Vec2 -> Vec2
omap Element Vec2 -> Element Vec2
f Vec2
v =
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
v \Float
x Float
y ->
      Float -> Float -> Vec2
vec2 (Element Vec2 -> Element Vec2
f Float
x) (Element Vec2 -> Element Vec2
f Float
y)

instance MonoPointed Vec2 where
  opoint :: Element Vec2 -> Vec2
opoint Element Vec2
x = Float -> Float -> Vec2
vec2 Element Vec2
x Element Vec2
x

instance Elementwise Vec2 where
  {-# INLINE emap2 #-}
  emap2 :: (Element Vec2 -> Element Vec2 -> Element Vec2)
-> Vec2 -> Vec2 -> Vec2
emap2 Element Vec2 -> Element Vec2 -> Element Vec2
f Vec2
p0 Vec2
p1 =
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p0 \Float
x0 Float
y0 ->
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p1 \Float
x1 Float
y1 ->
      Float -> Float -> Vec2
vec2
        (Element Vec2 -> Element Vec2 -> Element Vec2
f Float
x0 Float
x1)
        (Element Vec2 -> Element Vec2 -> Element Vec2
f Float
y0 Float
y1)

  {-# INLINE emap3 #-}
  emap3 :: (Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2)
-> Vec2 -> Vec2 -> Vec2 -> Vec2
emap3 Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2
f Vec2
p0 Vec2
p1 Vec2
p2 =
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p0 \Float
x0 Float
y0 ->
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p1 \Float
x1 Float
y1 ->
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p2 \Float
x2 Float
y2 ->
      Float -> Float -> Vec2
vec2
        (Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2
f Float
x0 Float
x1 Float
x2)
        (Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2
f Float
y0 Float
y1 Float
y2)

  {-# INLINE emap4 #-}
  emap4 :: (Element Vec2
 -> Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2)
-> Vec2 -> Vec2 -> Vec2 -> Vec2 -> Vec2
emap4 Element Vec2
-> Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2
f Vec2
p0 Vec2
p1 Vec2
p2 Vec2
p3 =
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p0 \Float
x0 Float
y0 ->
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p1 \Float
x1 Float
y1 ->
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p2 \Float
x2 Float
y2 ->
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p3 \Float
x3 Float
y3 ->
      Float -> Float -> Vec2
vec2
        (Element Vec2
-> Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2
f Float
x0 Float
x1 Float
x2 Float
x3)
        (Element Vec2
-> Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2
f Float
y0 Float
y1 Float
y2 Float
y3)

  {-# INLINE emap5 #-}
  emap5 :: (Element Vec2
 -> Element Vec2
 -> Element Vec2
 -> Element Vec2
 -> Element Vec2
 -> Element Vec2)
-> Vec2 -> Vec2 -> Vec2 -> Vec2 -> Vec2 -> Vec2
emap5 Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
f Vec2
p0 Vec2
p1 Vec2
p2 Vec2
p3 Vec2
p4 =
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p0 \Float
x0 Float
y0 ->
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p1 \Float
x1 Float
y1 ->
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p2 \Float
x2 Float
y2 ->
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p3 \Float
x3 Float
y3 ->
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p4 \Float
x4 Float
y4 ->
      Float -> Float -> Vec2
vec2
        (Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
f Float
x0 Float
x1 Float
x2 Float
x3 Float
x4)
        (Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
f Float
y0 Float
y1 Float
y2 Float
y3 Float
y4)

instance Num Vec2 where
  {-# INLINE (+) #-}
  Vec2 Float
l1 Float
l2 + :: Vec2 -> Vec2 -> Vec2
+ Vec2 Float
r1 Float
r2 =
    Float -> Float -> Vec2
Vec2
      (Float
l1 forall a. Num a => a -> a -> a
+ Float
r1)
      (Float
l2 forall a. Num a => a -> a -> a
+ Float
r2)

  {-# INLINE (-) #-}
  Vec2 Float
l1 Float
l2 - :: Vec2 -> Vec2 -> Vec2
- Vec2 Float
r1 Float
r2 =
    Float -> Float -> Vec2
Vec2
      (Float
l1 forall a. Num a => a -> a -> a
- Float
r1)
      (Float
l2 forall a. Num a => a -> a -> a
- Float
r2)

  {-# INLINE (*) #-}
  Vec2 Float
l1 Float
l2 * :: Vec2 -> Vec2 -> Vec2
* Vec2 Float
r1 Float
r2 =
    Float -> Float -> Vec2
Vec2
      (Float
l1 forall a. Num a => a -> a -> a
* Float
r1)
      (Float
l2 forall a. Num a => a -> a -> a
* Float
r2)

  {-# INLINE abs #-}
  abs :: Vec2 -> Vec2
abs (Vec2 Float
a Float
b) =
    Float -> Float -> Vec2
Vec2 (forall a. Num a => a -> a
abs Float
a) (forall a. Num a => a -> a
abs Float
b)

  {-# INLINE signum #-}
  signum :: Vec2 -> Vec2
signum (Vec2 Float
a Float
b) =
    Float -> Float -> Vec2
Vec2 (forall a. Num a => a -> a
signum Float
a) (forall a. Num a => a -> a
signum Float
b)

  {-# INLINE fromInteger #-}
  fromInteger :: Integer -> Vec2
fromInteger Integer
x = Float -> Float -> Vec2
Vec2 Float
x' Float
x'
    where
      x' :: Float
x' = forall a. Num a => Integer -> a
fromInteger Integer
x

instance Fractional Vec2 where
  {-# INLINE (/) #-}
  Vec2 Float
l1 Float
l2 / :: Vec2 -> Vec2 -> Vec2
/ Vec2 Float
r1 Float
r2 =
    Float -> Float -> Vec2
Vec2 (Float
l1 forall a. Fractional a => a -> a -> a
/ Float
r1) (Float
l2 forall a. Fractional a => a -> a -> a
/ Float
r2)

  {-# INLINE recip #-}
  recip :: Vec2 -> Vec2
recip (Vec2 Float
a Float
b) =
    Float -> Float -> Vec2
Vec2 (forall a. Fractional a => a -> a
recip Float
a) (forall a. Fractional a => a -> a
recip Float
b)

  {-# INLINE fromRational #-}
  fromRational :: Rational -> Vec2
fromRational Rational
x = Float -> Float -> Vec2
Vec2 Float
x' Float
x'
    where
      x' :: Float
x' = forall a. Fractional a => Rational -> a
fromRational Rational
x

instance Floating Vec2 where
  pi :: Vec2
pi = forall mono. MonoPointed mono => Element mono -> mono
opoint forall a. Floating a => a
pi

  exp :: Vec2 -> Vec2
exp = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
exp
  log :: Vec2 -> Vec2
log = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
log
  sqrt :: Vec2 -> Vec2
sqrt = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
sqrt
  sin :: Vec2 -> Vec2
sin = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
sin
  cos :: Vec2 -> Vec2
cos = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
cos
  asin :: Vec2 -> Vec2
asin = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
asin
  acos :: Vec2 -> Vec2
acos = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
acos
  atan :: Vec2 -> Vec2
atan = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
atan
  sinh :: Vec2 -> Vec2
sinh = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
sinh
  cosh :: Vec2 -> Vec2
cosh = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
cosh
  asinh :: Vec2 -> Vec2
asinh = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
asinh
  acosh :: Vec2 -> Vec2
acosh = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
acosh
  atanh :: Vec2 -> Vec2
atanh = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
atanh

  ** :: Vec2 -> Vec2 -> Vec2
(**) = forall a.
Elementwise a =>
(Element a -> Element a -> Element a) -> a -> a -> a
emap2 forall a. Floating a => a -> a -> a
(**)

{-# INLINE (^*) #-}
(^*) :: Vec2 -> Float -> Vec2
Vec2 Float
a Float
b ^* :: Vec2 -> Float -> Vec2
^* Float
x =
  Float -> Float -> Vec2
Vec2
    (Float
a forall a. Num a => a -> a -> a
* Float
x)
    (Float
b forall a. Num a => a -> a -> a
* Float
x)

{-# INLINE (^/) #-}
(^/) :: Vec2 -> Float -> Vec2
Vec2 Float
a Float
b ^/ :: Vec2 -> Float -> Vec2
^/ Float
x =
  Float -> Float -> Vec2
Vec2
    (Float
a forall a. Fractional a => a -> a -> a
/ Float
x)
    (Float
b forall a. Fractional a => a -> a -> a
/ Float
x)

{-# INLINE lerp #-}
lerp :: Float -> Vec2 -> Vec2 -> Vec2
lerp :: Float -> Vec2 -> Vec2 -> Vec2
lerp Float
alpha Vec2
u Vec2
v = Vec2
u Vec2 -> Float -> Vec2
^* Float
alpha forall a. Num a => a -> a -> a
+ Vec2
v Vec2 -> Float -> Vec2
^* (Float
1 forall a. Num a => a -> a -> a
- Float
alpha)

{-# INLINE dot #-}
dot :: Vec2 -> Vec2 -> Float
dot :: Vec2 -> Vec2 -> Float
dot (Vec2 Float
l1 Float
l2) (Vec2 Float
r1 Float
r2) =
  Float
l1 forall a. Num a => a -> a -> a
* Float
r1 forall a. Num a => a -> a -> a
+ Float
l2 forall a. Num a => a -> a -> a
* Float
r2

{-# INLINE normalize #-}
normalize :: Vec2 -> Vec2
normalize :: Vec2 -> Vec2
normalize Vec2
v =
  if forall {a}. (Ord a, Fractional a) => a -> Bool
nearZero Float
q Bool -> Bool -> Bool
|| forall {a}. (Ord a, Fractional a) => a -> Bool
nearZero (Float
1 forall a. Num a => a -> a -> a
- Float
q) then
    Vec2
v
  else
    let
      Vec2 Float
x Float
y = Vec2
v
    in
      Float -> Float -> Vec2
Vec2 (Float
x forall a. Fractional a => a -> a -> a
/ Float
l) (Float
y forall a. Fractional a => a -> a -> a
/ Float
l)

  where
    q :: Float
q = Vec2 -> Vec2 -> Float
dot Vec2
v Vec2
v
    l :: Float
l = forall a. Floating a => a -> a
sqrt Float
q

    nearZero :: a -> Bool
nearZero a
a = forall a. Num a => a -> a
abs a
a forall a. Ord a => a -> a -> Bool
<= a
1e-6

instance Storable Vec2 where
  {-# INLINE sizeOf #-}
  sizeOf :: Vec2 -> Int
sizeOf Vec2
_ = Int
8

  {-# INLINE alignment #-}
  alignment :: Vec2 -> Int
alignment Vec2
_ = Int
8

  {-# INLINE poke #-}
  poke :: Ptr Vec2 -> Vec2 -> IO ()
poke Ptr Vec2
ptr Vec2
v4 =
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
v4 \Float
a Float
b -> do
      forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Vec2
ptr Int
0 Float
a
      forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Vec2
ptr Int
4 Float
b

  {-# INLINE peek #-}
  peek :: Ptr Vec2 -> IO Vec2
peek Ptr Vec2
ptr = Float -> Float -> Vec2
vec2
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Vec2
ptr Int
0
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Vec2
ptr Int
4

instance Block Vec2 where
  type PackedSize Vec2 = 8
  alignment140 :: forall (proxy :: * -> *). proxy Vec2 -> Int
alignment140 proxy Vec2
_  = Int
8
  sizeOf140 :: forall (proxy :: * -> *). proxy Vec2 -> Int
sizeOf140 proxy Vec2
_     = Int
8
  alignment430 :: forall (proxy :: * -> *). proxy Vec2 -> Int
alignment430    = forall b (proxy :: * -> *). Block b => proxy b -> Int
alignment140
  sizeOf430 :: forall (proxy :: * -> *). proxy Vec2 -> Int
sizeOf430       = forall b (proxy :: * -> *). Block b => proxy b -> Int
sizeOf140
  isStruct :: forall (proxy :: * -> *). proxy Vec2 -> Bool
isStruct proxy Vec2
_      = Bool
False
  read140 :: forall (m :: * -> *) a. MonadIO m => Ptr a -> Diff a Vec2 -> m Vec2
read140     = forall (m :: * -> *) b a.
(MonadIO m, Storable b) =>
Ptr a -> Diff a b -> m b
peekDiffOff
  write140 :: forall (m :: * -> *) a.
MonadIO m =>
Ptr a -> Diff a Vec2 -> Vec2 -> m ()
write140    = forall (m :: * -> *) b a.
(MonadIO m, Storable b) =>
Ptr a -> Diff a b -> b -> m ()
pokeDiffOff
  read430 :: forall (m :: * -> *) a. MonadIO m => Ptr a -> Diff a Vec2 -> m Vec2
read430     = forall b (m :: * -> *) a.
(Block b, MonadIO m) =>
Ptr a -> Diff a b -> m b
read140
  write430 :: forall (m :: * -> *) a.
MonadIO m =>
Ptr a -> Diff a Vec2 -> Vec2 -> m ()
write430    = forall b (m :: * -> *) a.
(Block b, MonadIO m) =>
Ptr a -> Diff a b -> b -> m ()
write140
  readPacked :: forall (m :: * -> *) a. MonadIO m => Ptr a -> Diff a Vec2 -> m Vec2
readPacked  = forall b (m :: * -> *) a.
(Block b, MonadIO m) =>
Ptr a -> Diff a b -> m b
read140
  writePacked :: forall (m :: * -> *) a.
MonadIO m =>
Ptr a -> Diff a Vec2 -> Vec2 -> m ()
writePacked = forall b (m :: * -> *) a.
(Block b, MonadIO m) =>
Ptr a -> Diff a b -> b -> m ()
write140
  {-# INLINE alignment140 #-}
  {-# INLINE sizeOf140 #-}
  {-# INLINE alignment430 #-}
  {-# INLINE sizeOf430 #-}
  {-# INLINE isStruct #-}
  {-# INLINE read140 #-}
  {-# INLINE write140 #-}
  {-# INLINE read430 #-}
  {-# INLINE write430 #-}
  {-# INLINE readPacked #-}
  {-# INLINE writePacked #-}

instance VectorSpace Vec2 Float where
  zeroVector :: Vec2
zeroVector = forall a. Elementwise a => Element a -> a
epoint Float
0

  {-# INLINE (*^) #-}
  Float
a *^ :: Float -> Vec2 -> Vec2
*^ Vec2
v = Vec2
v Vec2 -> Float -> Vec2
Geomancy.Vec2.^* Float
a

  {-# INLINE (^/) #-}
  Vec2
v ^/ :: Vec2 -> Float -> Vec2
^/ Float
a = Vec2
v Vec2 -> Float -> Vec2
Geomancy.Vec2.^/ Float
a

  {-# INLINE (^+^) #-}
  ^+^ :: Vec2 -> Vec2 -> Vec2
(^+^) = forall a.
Elementwise a =>
(Element a -> Element a -> Element a) -> a -> a -> a
emap2 forall a. Num a => a -> a -> a
(+)

  {-# INLINE (^-^) #-}
  ^-^ :: Vec2 -> Vec2 -> Vec2
(^-^) = forall a.
Elementwise a =>
(Element a -> Element a -> Element a) -> a -> a -> a
emap2 (-)

  {-# INLINE negateVector #-}
  negateVector :: Vec2 -> Vec2
negateVector = forall a. Elementwise a => (Element a -> Element a) -> a -> a
emap forall a. Num a => a -> a
negate

  {-# INLINE dot #-}
  dot :: Vec2 -> Vec2 -> Float
dot = Vec2 -> Vec2 -> Float
Geomancy.Vec2.dot

  {-# INLINE normalize #-}
  normalize :: Vec2 -> Vec2
normalize = Vec2 -> Vec2
Geomancy.Vec2.normalize

instance GlNearest Vec2

instance GlModf Vec2 Vec2 where
  glModf :: Vec2 -> (Vec2, Vec2)
glModf Vec2
v =
    forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
v \Float
vx Float
vy ->
      let
        (Integer
xi, Float
xf) = forall i f. GlModf i f => f -> (i, f)
glModf Float
vx
        (Integer
yi, Float
yf) = forall i f. GlModf i f => f -> (i, f)
glModf Float
vy
      in
        ( Float -> Float -> Vec2
vec2 (forall a. Num a => Integer -> a
fromInteger Integer
xi) (forall a. Num a => Integer -> a
fromInteger Integer
yi)
        , Float -> Float -> Vec2
vec2 Float
xf Float
yf
        )