module Mischief.Math.Vec
  ( V2 (..),
    V3 (..),
    V4 (..),
    ext2,
    trunc3,
    Dir3 (Dir3),
    dir3,
  )
where

import GHC.Records
import Linear

ext2 :: a -> V2 a -> V3 a
ext2 :: forall a. a -> V2 a -> V3 a
ext2 a
z (V2 a
x a
y) = a -> a -> a -> V3 a
forall a. a -> a -> a -> V3 a
V3 a
x a
y a
z

trunc3 :: V3 a -> V2 a
trunc3 :: forall a. V3 a -> V2 a
trunc3 (V3 a
x a
y a
_) = a -> a -> V2 a
forall a. a -> a -> V2 a
V2 a
x a
y

newtype Dir3 a = Dir3 (V3 a) deriving newtype (Int -> Dir3 a -> ShowS
[Dir3 a] -> ShowS
Dir3 a -> String
(Int -> Dir3 a -> ShowS)
-> (Dir3 a -> String) -> ([Dir3 a] -> ShowS) -> Show (Dir3 a)
forall a. Show a => Int -> Dir3 a -> ShowS
forall a. Show a => [Dir3 a] -> ShowS
forall a. Show a => Dir3 a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Dir3 a -> ShowS
showsPrec :: Int -> Dir3 a -> ShowS
$cshow :: forall a. Show a => Dir3 a -> String
show :: Dir3 a -> String
$cshowList :: forall a. Show a => [Dir3 a] -> ShowS
showList :: [Dir3 a] -> ShowS
Show, Dir3 a -> Dir3 a -> Bool
(Dir3 a -> Dir3 a -> Bool)
-> (Dir3 a -> Dir3 a -> Bool) -> Eq (Dir3 a)
forall a. Eq a => Dir3 a -> Dir3 a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Dir3 a -> Dir3 a -> Bool
== :: Dir3 a -> Dir3 a -> Bool
$c/= :: forall a. Eq a => Dir3 a -> Dir3 a -> Bool
/= :: Dir3 a -> Dir3 a -> Bool
Eq, Eq (Dir3 a)
Eq (Dir3 a) =>
(Dir3 a -> Dir3 a -> Ordering)
-> (Dir3 a -> Dir3 a -> Bool)
-> (Dir3 a -> Dir3 a -> Bool)
-> (Dir3 a -> Dir3 a -> Bool)
-> (Dir3 a -> Dir3 a -> Bool)
-> (Dir3 a -> Dir3 a -> Dir3 a)
-> (Dir3 a -> Dir3 a -> Dir3 a)
-> Ord (Dir3 a)
Dir3 a -> Dir3 a -> Bool
Dir3 a -> Dir3 a -> Ordering
Dir3 a -> Dir3 a -> Dir3 a
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 a. Ord a => Eq (Dir3 a)
forall a. Ord a => Dir3 a -> Dir3 a -> Bool
forall a. Ord a => Dir3 a -> Dir3 a -> Ordering
forall a. Ord a => Dir3 a -> Dir3 a -> Dir3 a
$ccompare :: forall a. Ord a => Dir3 a -> Dir3 a -> Ordering
compare :: Dir3 a -> Dir3 a -> Ordering
$c< :: forall a. Ord a => Dir3 a -> Dir3 a -> Bool
< :: Dir3 a -> Dir3 a -> Bool
$c<= :: forall a. Ord a => Dir3 a -> Dir3 a -> Bool
<= :: Dir3 a -> Dir3 a -> Bool
$c> :: forall a. Ord a => Dir3 a -> Dir3 a -> Bool
> :: Dir3 a -> Dir3 a -> Bool
$c>= :: forall a. Ord a => Dir3 a -> Dir3 a -> Bool
>= :: Dir3 a -> Dir3 a -> Bool
$cmax :: forall a. Ord a => Dir3 a -> Dir3 a -> Dir3 a
max :: Dir3 a -> Dir3 a -> Dir3 a
$cmin :: forall a. Ord a => Dir3 a -> Dir3 a -> Dir3 a
min :: Dir3 a -> Dir3 a -> Dir3 a
Ord)

instance (Floating a, Epsilon a) => Num (Dir3 a) where
  + :: Dir3 a -> Dir3 a -> Dir3 a
(+) (Dir3 V3 a
a) (Dir3 V3 a
b) = V3 a -> Dir3 a
forall a. V3 a -> Dir3 a
Dir3 (V3 a -> V3 a
forall a (f :: * -> *).
(Floating a, Metric f, Epsilon a) =>
f a -> f a
normalize (V3 a -> V3 a) -> V3 a -> V3 a
forall a b. (a -> b) -> a -> b
$ V3 a
a V3 a -> V3 a -> V3 a
forall a. Num a => a -> a -> a
+ V3 a
b)
  * :: Dir3 a -> Dir3 a -> Dir3 a
(*) (Dir3 V3 a
a) (Dir3 V3 a
b) = V3 a -> Dir3 a
forall a. V3 a -> Dir3 a
Dir3 (V3 a -> V3 a
forall a (f :: * -> *).
(Floating a, Metric f, Epsilon a) =>
f a -> f a
normalize (V3 a -> V3 a) -> V3 a -> V3 a
forall a b. (a -> b) -> a -> b
$ V3 a
a V3 a -> V3 a -> V3 a
forall a. Num a => a -> a -> a
- V3 a
b)
  abs :: Dir3 a -> Dir3 a
abs (Dir3 V3 a
a) = V3 a -> Dir3 a
forall a. V3 a -> Dir3 a
Dir3 (V3 a -> V3 a
forall a. Num a => a -> a
abs V3 a
a)
  signum :: Dir3 a -> Dir3 a
signum (Dir3 V3 a
a) = V3 a -> Dir3 a
forall a. V3 a -> Dir3 a
Dir3 (V3 a -> V3 a
forall a. Num a => a -> a
signum V3 a
a)
  fromInteger :: Integer -> Dir3 a
fromInteger = V3 a -> Dir3 a
forall a. V3 a -> Dir3 a
Dir3 (V3 a -> Dir3 a) -> (Integer -> V3 a) -> Integer -> Dir3 a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> V3 a
forall a. Num a => Integer -> a
fromInteger
  negate :: Dir3 a -> Dir3 a
negate (Dir3 V3 a
a) = V3 a -> Dir3 a
forall a. V3 a -> Dir3 a
Dir3 (V3 a -> V3 a
forall a. Num a => a -> a
negate V3 a
a)

instance HasField "vec" (Dir3 a) (V3 a) where
  getField :: Dir3 a -> V3 a
  getField :: Dir3 a -> V3 a
getField (Dir3 V3 a
v3) = V3 a
v3

dir3 :: (Floating a, Epsilon a) => a -> a -> a -> Dir3 a
dir3 :: forall a. (Floating a, Epsilon a) => a -> a -> a -> Dir3 a
dir3 a
x a
y a
z = V3 a -> Dir3 a
forall a. V3 a -> Dir3 a
Dir3 (V3 a -> Dir3 a) -> V3 a -> Dir3 a
forall a b. (a -> b) -> a -> b
$ V3 a -> V3 a
forall a (f :: * -> *).
(Floating a, Metric f, Epsilon a) =>
f a -> f a
normalize (V3 a -> V3 a) -> V3 a -> V3 a
forall a b. (a -> b) -> a -> b
$ a -> a -> a -> V3 a
forall a. a -> a -> a -> V3 a
V3 a
x a
y a
z