-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Coordinate systems -- -- Coordinate systems @package Cartesian @version 0.6.0.0 module Cartesian.Types -- | A 1-dimensional vector -- --
--   >>> pure 1 :: V1 Int
--   V1 1
--   
-- --
--   >>> V1 2 + V1 3
--   V1 5
--   
-- --
--   >>> V1 2 * V1 3
--   V1 6
--   
-- --
--   >>> sum (V1 2)
--   2
--   
newtype V1 a :: * -> * V1 :: a -> V1 a -- | A 2-dimensional vector -- --
--   >>> pure 1 :: V2 Int
--   V2 1 1
--   
-- --
--   >>> V2 1 2 + V2 3 4
--   V2 4 6
--   
-- --
--   >>> V2 1 2 * V2 3 4
--   V2 3 8
--   
-- --
--   >>> sum (V2 1 2)
--   3
--   
data V2 a :: * -> * V2 :: ~a -> ~a -> V2 a -- | A 3-dimensional vector data V3 a :: * -> * V3 :: ~a -> ~a -> ~a -> V3 a -- | A 4-dimensional vector. data V4 a :: * -> * V4 :: ~a -> ~a -> ~a -> ~a -> V4 a -- | Complex numbers are an algebraic type. -- -- For a complex number z, abs z is a number -- with the magnitude of z, but oriented in the positive real -- direction, whereas signum z has the phase of -- z, but unit magnitude. -- -- The Foldable and Traversable instances traverse the real -- part first. data Complex a :: * -> * -- | forms a complex number from its real and imaginary rectangular -- components. (:+) :: ~a -> ~a -> Complex a -- | A lens focusing on a single [vector-]component in a BoundingBox type BoxLens v v' f f' = Lens (BoundingBox (v f)) (BoundingBox (v' f')) f f' -- | An axis represented as (begin, length) type Axis a = (a, a) -- | A vector where each component represents a single axis (cf. -- Axis) type Axes v a = v (Axis a) -- | type Domain -- -- TODO: Rename (eg. Shape) (?) type Polygon m v f = m (v f) -- | Coordinate system wrappers data Normalised v data Absolute v -- | TODO: Anchors (eg. C, N, S, E W and combinations thereof, perhaps -- represented as relative Vectors) TODO: Define some standard instances -- (eg. Functor, Applicative) data BoundingBox v BoundingBox :: v -> v -> BoundingBox v [cornerOf] :: BoundingBox v -> v [sizeOf] :: BoundingBox v -> v -- | TODO: Use record (eg. from, to) (?) data Line v data Linear f -- | TODO: Use existing type instead (?) data Side = SideLeft | SideRight | -- SideTop | SideBottom class HasX a f | a -> f class HasY a f | a -> f class HasZ a f | a -> f module Cartesian.Lenses -- | pad :: (Getter v f) -> f -> f -> BoundingBox v pad axis by -- direction = _ -- -- Like pinned, except it operates on a single axis and only focuses on -- the position (not size) -- -- TODO: Change the type to make it play more nicely with pinned -- (?) TODO: - What's the proper way of lifting lenses (such as -- pinnedAxis), so they work on multiple fields. This is not -- mucher better than it used to be when we didn't have the -- pinnedAxis helper... pinnedAxis :: Num n => n -> Simple Lens (Axis n) (Axis n) -- | Creates a lens where a pin is placed on a given point (to), -- so that the box can be placed or resized relative to the pin. It is -- also useful for retrieving points within the box (such as the centre). -- -- The pin is assumed to be normalised with respect to the corner and -- size of the box. -- --
--   let box = BoundingBox { cornerOf = V2 10 24, sizeOf = V2 6 18 }
--   
--   box^.pinned (V2 0.5 0.5) -- Anchored to the centre
--   > V2 (13.0,6.0) (33.0,18.0)
--   
pinned :: (Applicative v, Num n) => v n -> Simple Lens (BoundingBox (v n)) (Axes v n) -- | Focuses on a single axis of the box axis :: (Applicative v, Num n) => Simple Lens (Axes v n) (Axis n) -> Simple Lens (BoundingBox (v n)) (Axis n) axes :: (Applicative v) => Lens (BoundingBox (v a)) (BoundingBox (v b)) (Axes v a) (Axes v b) extents :: (Applicative v, Num a, Num b) => Lens (BoundingBox (v a)) (BoundingBox (v b)) (Axes v a) (Axes v b) -- | TODO: Turn this into a lens function (?) TODO: Polish description -- TODO: Loosen constraint on n (✓) axes which.pinned (V1 step).x._1 -- -- lens get set side :: (Applicative v, Num n) => Simple Lens (Axes v n) (Axis n) -> Simple Lens (Axis n) n -> Simple BoxLens v n corner :: forall v_aotZ. Lens' (BoundingBox v_aotZ) v_aotZ -- | Ugh... size :: forall v_aotZ. Lens' (BoundingBox v_aotZ) v_aotZ begin :: Lens (Line v) (Line v) v v end :: Lens (Line v) (Line v) v v width :: (HasX (v f) f) => Simple Lens (BoundingBox (v f)) f height :: (HasY (v f) f) => Simple BoxLens v f depth :: (HasZ (v f) f) => Simple BoxLens v f left :: (Applicative v, HasX (Axes v n) (Axis n), Num n) => Simple BoxLens v n right :: (Applicative v, HasX (Axes v n) (Axis n), Num n) => Simple BoxLens v n bottom :: (Applicative v, HasY (Axes v n) (Axis n), Num n) => Simple BoxLens v n top :: (Applicative v, HasY (Axes v n) (Axis n), Num n) => Simple BoxLens v n front :: (Applicative v, HasZ (Axes v n) (Axis n), Num n) => Simple BoxLens v n back :: (Applicative v, HasZ (Axes v n) (Axis n), Num n) => Simple BoxLens v n -- | TODO: This should probably yield a vector (rename or redesign) centre :: (Applicative v, Fractional f) => Simple Lens (BoundingBox (v f)) (Axes v f) x :: HasX a f => Simple Lens a f y :: HasY a f => Simple Lens a f z :: HasZ a f => Simple Lens a f module Cartesian.Core -- | Finds the overlap between two ranges (lower bound, upper bound). | -- Yields the overlap of two closed intervals (n ∈ R) TODO: Normalise -- intervals (eg. (12, 5) -> (5, 12)) TODO: Type for intervals (which -- would also encode the openness of the lower and upper limits) overlap :: (Ord n) => (n, n) -> (n, n) -> Maybe (n, n) -- | Cross product cross :: (Vector v, Num f) => v f -> v f -> v f -- cross a b = _ -- -- Euclidean distance between two points euclidean :: (Vector v, Floating -- f) => v f -> v f -> f euclidean a b = sqrt $ dot a b -- -- Vector -> (magnitude, argument) polar :: (Floating a, Eq a) => -- Vector a -> (a, a) polar v@(Vector x y) = (magnitude v, argument v) -- -- Creates a bounding box from two opposite corners TODO: Better name (?) -- TODO: Don't make assumptions about WHICH corners they are (✓) TODO: -- Should we care about degenerate cases (such as a and -- b being identical) fromCorners :: (Applicative v, Num n, Ord n) => v n -> v n -> BoundingBox (v n) fromAxes :: (Applicative v) => Axes v n -> BoundingBox (v n) -- | Top Left Bottom Right fromExtents :: (Applicative v, Num n) => Axes v n -> BoundingBox (v n) -- | Finds the intersection (boolean AND) of two bounding boxes intersect :: (Applicative v, Traversable v, Ord n, Num n) => BoundingBox (v n) -> BoundingBox (v n) -> Maybe (BoundingBox (v n))