{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}
module Geomancy.Vec2
( Vec2
, vec2
, withVec2
, pattern WithVec2
, fromTuple
, (^*)
, (^/)
, lerp
, dot
, normalize
) where
import Control.DeepSeq (NFData(rnf))
import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
import Data.VectorSpace (VectorSpace)
import Foreign (Storable(..))
import qualified Data.VectorSpace as VectorSpace
import Geomancy.Elementwise (Elementwise(..))
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
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 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
)