{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Data.H3.Extent(
Extent(..),
_Extent,
extent,
toTuple,
fromTuple,
resize
) where
import Data.Profunctor (Profunctor (..))
import Data.Semigroup (Max (..), Min (..), Semigroup (..))
import Data.Semigroup.Foldable (Foldable1 (..))
import GHC.Generics (Generic)
newtype Extent a = Extent { getExtent :: (Min a, Max a) }
deriving (Eq, Ord, Show, Functor, Semigroup, Generic, Foldable, Traversable)
instance Foldable1 Extent where
fold1 (Extent (Min l, Max r)) = l <> r
_Extent :: forall p f a b. (Profunctor p, Functor f) => p (Extent a) (f (Extent b)) -> p (a, a) (f (b, b))
_Extent = dimap fromTuple (fmap toTuple)
extent :: a -> Extent a
extent a = Extent (Min a, Max a)
toTuple :: Extent a -> (a, a)
toTuple (Extent (Min l, Max r)) = (l, r)
fromTuple :: (a, a) -> Extent a
fromTuple (l, r) = Extent (Min l, Max r)
resize :: (Fractional a, Num a) => a -> Extent a -> Extent a
resize factor (Extent (Min mn, Max mx)) = Extent (Min mn', Max mx') where
range = mx - mn
change = ((range * factor) - range) / 2
mn' = mn - change
mx' = mx + change