-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Small geometry library for dealing with vectors and collision detection -- -- A small geometry library for dealing with vectors, points, lines, -- simple shapes, and their various intersection tests. See also the -- SGdemo project -- (http://hackage.haskell.org/cgi-bin/hackage-scripts/package/SGdemo) -- for an example of using the module. @package SG @version 1.0 -- | The module with all the different type-classes for vectors. Generally, -- the main functions you might need from this function are: -- --
-- fmap (*3) v -- Scales vector v by 3 -- pure 0 -- Creates a vector filled with zeroes -- v + w -- Adds two vectors (there is a 'Num' instance, basically) ---- -- Plus all the instances for the classes in Data.SG.Vector, which -- allows you to use getX and so on. -- -- You will probably want to create more friendly type synonyms, such as: -- --
-- type Vector2 = Pair Double -- type Vector3 = Triple Double -- type Line2 = LinePair Double -- type Line3 = LineTriple Double --module Data.SG.Vector.Basic -- | A pair, which acts as a 2D vector. newtype Pair a Pair :: (a, a) -> Pair a -- | A triple, which acts as a 3D vector. newtype Triple a Triple :: (a, a, a) -> Triple a -- | A quad, which acts as a 4D vector. newtype Quad a Quad :: (a, a, a, a) -> Quad a -- | A pair of (position vector, direction vector) to be used as a 2D line. newtype LinePair a LinePair :: (Pair a, Pair a) -> LinePair a -- | A pair of (position vector, direction vector) to be used as a 3D line. newtype LineTriple a LineTriple :: (Triple a, Triple a) -> LineTriple a instance Eq a => Eq (Pair a) instance Ord a => Ord (Pair a) instance Show a => Show (Pair a) instance Read a => Read (Pair a) instance Eq a => Eq (Triple a) instance Ord a => Ord (Triple a) instance Show a => Show (Triple a) instance Read a => Read (Triple a) instance Eq a => Eq (Quad a) instance Ord a => Ord (Quad a) instance Show a => Show (Quad a) instance Read a => Read (Quad a) instance Eq a => Eq (LinePair a) instance Ord a => Ord (LinePair a) instance Show a => Show (LinePair a) instance Read a => Read (LinePair a) instance Eq a => Eq (LineTriple a) instance Ord a => Ord (LineTriple a) instance Show a => Show (LineTriple a) instance Read a => Read (LineTriple a) instance Coord3 Quad instance Coord2 Quad instance Coord Quad instance Coord3 Triple instance Coord2 Triple instance Coord Triple instance Coord2 Pair instance Coord Pair instance Functor Quad instance Functor Triple instance Functor Pair instance Traversable Quad instance Foldable Quad instance Applicative Quad instance Traversable Triple instance Foldable Triple instance Applicative Triple instance Traversable Pair instance Foldable Pair instance Applicative Pair instance (Show a, Eq a, Num a) => Num (Quad a) instance (Show a, Eq a, Num a) => Num (Triple a) instance (Show a, Eq a, Num a) => Num (Pair a) instance VectorNum Quad instance VectorNum Triple instance VectorNum Pair -- | This module has the type-class (and associated functions) for dealing -- with geometric systems of 2 or 3 dimensions. module Data.SG.Geometry -- | A geometry system, parameterised over points, relative (free) vectors, -- and lines. There are separate instances for two dimensions and for -- three dimensions. Each pair of type-class parameters is uniquely -- determined by the other parameter (i.e. by the dimensionality, and -- which vector type you are using). -- -- Minimal implementation: everything but scaleRel. class (VectorNum rel, Coord rel, Coord pt, IsomorphicVectors rel pt, IsomorphicVectors pt rel) => Geometry rel pt ln | rel -> pt ln, pt -> rel ln, ln -> rel pt scaleRel :: (Geometry rel pt ln, Num a) => a -> rel a -> rel a plusDir :: (Geometry rel pt ln, Num a) => pt a -> rel a -> pt a fromPt :: (Geometry rel pt ln, Num a) => pt a -> pt a -> rel a getLineVecs :: (Geometry rel pt ln, Num a) => ln a -> (pt a, rel a) makeLine :: (Geometry rel pt ln, Num a) => pt a -> rel a -> ln a -- | Adds the negation of the relative (free) vector to the point. minusDir :: (Num a, Geometry rel pt ln) => pt a -> rel a -> pt a -- | The flipped version of fromPt. toPt :: (Geometry rel pt ln, Num a) => pt a -> pt a -> rel a -- | Gets the line from the first point, to the second point. lineTo :: (Num a, Geometry rel pt ln) => pt a -> pt a -> ln a -- | The flipped version of lineTo. lineFrom :: (Num a, Geometry rel pt ln) => pt a -> pt a -> ln a -- | Gets the point at the start of the line. getLineStart :: (Num a, Geometry rel pt ln) => ln a -> pt a -- | Gets the direction vector of the line. getLineDir :: (Num a, Geometry rel pt ln) => ln a -> rel a -- | Gets the point at the end of the line. getLineEnd :: (Geometry rel pt ln, Num a) => ln a -> pt a -- | Alters the line to the given length, but with the same start point and -- direction. makeLength :: (Floating a, Ord a, Geometry rel pt ln) => a -> ln a -> ln a -- | Given a multiple of the direction vector (this is not -- distance unless the direction vector is a unit vector), calculates -- that point. alongLine :: (Num a, Geometry rel pt ln) => a -> ln a -> pt a -- | Checks if the given point is on the given line (to within a small -- epsilon-tolerance). If it is, gives back the distance along the line -- (as a multiple of its direction vector) to the point in a Just -- wrapper. If the point is not on the line, Nothing is returned. distAlongLine :: (Geometry rel pt ln, Ord a, Floating a) => pt a -> ln a -> Maybe a -- | Checks if the given point is on the given line (to within a small -- epsilon-tolerance). isOnLine :: (Geometry rel pt ln, Ord a, Floating a) => pt a -> ln a -> Bool -- | Finds the nearest point on the line to the given point, and gives back -- its distance along the line (as a multiple of the direction vector). -- Since the nearest distance will be at a right-angle to the point, this -- is the same as projecting the point onto the line. nearestDistOnLine :: (Geometry rel pt ln, Ord a, Floating a) => pt a -> ln a -> a -- | Finds the nearest point on the line to the given point, and gives back -- the point. nearestPointOnLine :: (Geometry rel pt ln, Ord a, Floating a) => pt a -> ln a -> pt a -- | Gives the distance along the line (2D or 3D) at a given X value. -- Returns Nothing if the line is parallel to the YZ plane (in 2D, if the -- X component of the line is zero). The value returned is a multiple of -- the direction vector of the line, which will only be the same as -- distance if the direction vector is a unit vector. valueAtX :: (Geometry rel pt ln, Coord2 rel, Coord2 pt, Fractional a) => ln a -> a -> Maybe a -- | Gives the distance along the line (2D or 3D) at a given Y value. -- Returns Nothing if the line is parallel to the XZ plane (in 2D, if the -- Y component of the line is zero). The value returned is a multiple of -- the direction vector of the line, which will only be the same as -- distance if the direction vector is a unit vector. valueAtY :: (Geometry rel pt ln, Coord2 rel, Coord2 pt, Fractional a) => ln a -> a -> Maybe a -- | Gives the distance along the 3D line at a given Z value. Returns -- Nothing if the line is parallel to the XY plane. The value returned is -- a multiple of the direction vector of the line, which will only be the -- same as distance if the direction vector is a unit vector. valueAtZ :: (Geometry rel pt ln, Coord3 rel, Coord3 pt, Fractional a) => ln a -> a -> Maybe a -- | pointAtX (and the Y and Z equivalents) are wrappers around -- valueAtX (and similar) that give back the point rather than -- distance along the line. pointAtX, pointAtY :: (Geometry rel pt ln, Coord2 rel, Coord2 pt, Fractional a) => ln a -> a -> Maybe (pt a) pointAtZ :: (Geometry rel pt ln, Coord3 rel, Coord3 pt, Fractional a) => ln a -> a -> Maybe (pt a) instance Geometry Triple Triple LineTriple instance Geometry Pair Pair LinePair -- | A module with types to use in a 2D system, and various helper -- functions. Several more functions are available for use in the -- Data.SG.Geometry module. module Data.SG.Geometry.TwoDim -- | A point in 2D space. newtype Point2' a Point2 :: (a, a) -> Point2' a -- | A relative vector (free vector) in 2D space. The pair are the x and y -- components, and the last item is the squared magnitude of the -- vector, which is stored with it to speed up various operations. It is -- suggested you use makeRel2 to create one of these, unless the -- square magnitude is easily apparent, e.g. Rel2 (0, 2) 4 data Rel2' a Rel2 :: (a, a) -> a -> Rel2' a -- | Constructs a Rel2' vector. makeRel2 :: Num a => (a, a) -> Rel2' a -- | A line in 2D space. A line is a point, and a free vector indicating -- direction. A line may be treated by a function as either finite -- (taking the magnitude of the free vector as the length) or infinite -- (ignoring the magnitude of the direction vector). data Line2' a Line2 :: (Point2' a) -> (Rel2' a) -> Line2' a getLineStart2 :: Line2' a -> (Point2' a) getLineDir2 :: Line2' a -> (Rel2' a) -- | Gets the angle, in radians, anti-clockwise from the x-axis. If -- you pass the all-zero vector, the return value will be zero. toAngle :: RealFloat a => Rel2' a -> a -- | Gets the vector perpendicular to the given 2D vector. If you pass it a -- vector that is in a clockwise direction around a polygon, the result -- will always face away from the polygon. perpendicular2 :: Num a => Rel2' a -> Rel2' a -- | Reflects the first direction vector against the given surface normal. -- The resulting direction vector should have the same magnitude as the -- original first parameter. An example: -- --
-- makeRel2 (-3, -4) `reflectAgainst2` makeRel2 (0,1) == makeRel2 (-3, 4) --reflectAgainst2 :: (Floating a, Ord a) => Rel2' a -> Rel2' a -> Rel2' a -- | Reflects the first direction vector against the given surface normal. -- The resulting direction vector should have the same magnitude as the -- original first parameter. -- -- The reflection is not performed if the given vector points along the -- same direction as the normal, that is: if once projected onto the -- normal vector, the component is positive, the original first parameter -- is returned unmodified. Examples: -- --
-- makeRel2 (-3, -4) `reflectAgainstIfNeeded2` makeRel2 (0,1) == makeRel2 (-3, 4) -- makeRel2 (-3, 4) `reflectAgainstIfNeeded2` makeRel2 (0,1) == makeRel2 (-3, 4) --reflectAgainstIfNeeded2 :: (Floating a, Ord a) => Rel2' a -> Rel2' a -> Rel2' a -- | Given two 2D lines, finds out their intersection. The first part of -- the result pair is how much to multiply the direction vector of the -- first line by (and add it to the start point of the first line) to -- reach the intersection, and the second part is the corresponding item -- for the second line. So given Just (a, b) = intersectLines2 la -- lb, it should be the case (minus some possible precision loss) -- that alongLine a la == alongLine b lb. If the lines are -- parallel, Nothing is returned. -- -- Note that this function assumes the lines are infinite. If you want to -- check for the intersection of two finite lines, check if the two parts -- of the result pair are both in the range 0 to 1 inclusive. intersectLines2 :: Fractional a => Line2' a -> Line2' a -> Maybe (a, a) -- | Finds all the intersections between a line from the first list and a -- line from the second list, and how far along that is each line. That -- is, this is a bit like mapMaybe composed with intersectLines2 on all -- pairings of a line from the first list and a line from the second -- list. findAllIntersections2 :: Fractional a => ([Line2' a], [Line2' a]) -> [((Line2' a, a), (Line2' a, a))] -- | Given a line, and a circle (defined by a point and a radius), finds -- the points of intersection. -- -- If the line does not intersect the circle, Nothing is returned. If -- they do intersect, two values are returned that are distances along -- the line. That is, given Just (a, b) = intersectLineCircle l -- c, the two points of intersection are (alongLine l a, -- alongLine l b). -- -- The ordering of the two items in the pair is arbitrary, and if the -- line is a tangent to the circle, the values will be the same. intersectLineCircle :: (Ord a, Floating a) => Line2' a -> (Point2' a, a) -> Maybe (a, a) -- | Like pointAtZ, but returns a 2D vector instead of a 3D vector point2AtZ :: (Geometry rel pt ln, Coord3 rel, Coord3 pt, Fractional a) => ln a -> a -> Maybe (Point2' a) instance Eq a => Eq (Point2' a) instance Ord a => Ord (Point2' a) instance Show a => Show (Point2' a) instance Read a => Read (Point2' a) instance Eq a => Eq (Rel2' a) instance Ord a => Ord (Rel2' a) instance Show a => Show (Rel2' a) instance Read a => Read (Rel2' a) instance Eq a => Eq (Line2' a) instance Show a => Show (Line2' a) instance Read a => Read (Line2' a) instance Geometry Rel2' Point2' Line2' instance Coord Rel2' instance Coord2 Rel2' instance Coord Point2' instance Coord2 Point2' instance Traversable Point2' instance Foldable Rel2' instance Foldable Point2' instance Applicative Point2' instance Functor Point2' instance (Show a, Eq a, Num a) => Num (Rel2' a) instance VectorNum Point2' instance VectorNum Rel2' instance IsomorphicVectors Pair Point2' instance IsomorphicVectors Point2' Pair instance IsomorphicVectors Pair Rel2' instance IsomorphicVectors Rel2' Pair instance IsomorphicVectors Point2' Rel2' instance IsomorphicVectors Rel2' Point2' -- | A module with types to use in a 3D system, and various helper -- functions. Several more functions are available for use in the -- Data.SG.Geometry module. module Data.SG.Geometry.ThreeDim -- | A point in 3D space. newtype Point3' a Point3 :: (a, a, a) -> Point3' a -- | A relative vector (free vector) in 3D space. The triple is the x, y, z -- components, and the last item is the squared magnitude of the -- vector, which is stored with it to speed up various operations. It is -- suggested you use makeRel3 to create one of these, unless the -- magnitude is easily apparent, e.g. Rel3 (0, 1, 1) 2 data Rel3' a Rel3 :: (a, a, a) -> a -> Rel3' a -- | Constructs a Rel3' vector makeRel3 :: Num a => (a, a, a) -> Rel3' a -- | A line in 3D space. A line is a point and a free vector indicating -- direction. A line may be treated by a function as either finite -- (taking the magnitude of the free vector as the length) or infinite -- (ignoring the magnitude of the direction vector). data Line3' a Line3 :: (Point3' a) -> (Rel3' a) -> Line3' a getLineStart3 :: Line3' a -> (Point3' a) getLineDir3 :: Line3' a -> (Rel3' a) instance Eq a => Eq (Point3' a) instance Ord a => Ord (Point3' a) instance Show a => Show (Point3' a) instance Read a => Read (Point3' a) instance Eq a => Eq (Rel3' a) instance Ord a => Ord (Rel3' a) instance Show a => Show (Rel3' a) instance Read a => Read (Rel3' a) instance Eq a => Eq (Line3' a) instance Show a => Show (Line3' a) instance Read a => Read (Line3' a) instance Geometry Rel3' Point3' Line3' instance Coord Rel3' instance Coord Point3' instance Coord3 Rel3' instance Coord2 Rel3' instance Coord3 Point3' instance Coord2 Point3' instance Traversable Point3' instance Foldable Rel3' instance Foldable Point3' instance Applicative Point3' instance Functor Point3' instance (Show a, Eq a, Num a) => Num (Rel3' a) instance VectorNum Point3' instance VectorNum Rel3' instance IsomorphicVectors Triple Point3' instance IsomorphicVectors Point3' Triple instance IsomorphicVectors Triple Rel3' instance IsomorphicVectors Rel3' Triple instance IsomorphicVectors Point3' Rel3' instance IsomorphicVectors Rel3' Point3' -- | A module with various simple matrix operations to augment the vector -- stuff. -- -- The Num instances implement proper matrix multiplication as you would -- expect (not element-wise multiplication). module Data.SG.Matrix -- | A 2x2 matrix. Primarily useful via its instances, such as -- Functor, Num, and Matrix. type Matrix22' a = SquareMatrix Pair a -- | A 3x3 matrix. Primarily useful via its instances, such as -- Functor, Num, and Matrix. type Matrix33' a = SquareMatrix Triple a -- | A 4x4 matrix. Primarily useful via its instances, such as -- Functor, Num, and Matrix. type Matrix44' a = SquareMatrix Quad a -- | A square matrix. You will almost certainly want to use -- Matrix22' and similar instead of this directly. It does have a -- variety of useful instances though, especially Functor, -- Num and Matrix. -- -- Its definition is based on a square matrix being, for example, a pair -- of pairs or a triple of triples. newtype SquareMatrix c a SquareMatrix :: (c (c a)) -> SquareMatrix c a -- | The class that all matrices belong to. class Matrix m matrixComponents :: Matrix m => m a -> [[a]] fromMatrixComponents :: (Matrix m, Num a) => [[a]] -> m a transpose :: Matrix m => m a -> m a -- | The identity matrix. identityMatrix :: (Num a, Matrix m) => m a -- | Matrix multiplication where the size of the vector matches the -- dimensions of the matrix. The complicated type just means that this -- function will work for any combination of matrix types and vectors -- where the width of the square matrix is the same as the number of -- dimensions in the vector. multMatrix :: (Foldable c, Applicative c, Num a, IsomorphicVectors c p, IsomorphicVectors p c) => SquareMatrix c a -> p a -> p a -- | Matrix multiplication. There is no requirement that the size of the -- matrix matches the size of the vector: -- --
-- type Point2 = Point2' Double -- type Rel2 = Rel2' Double -- type Line2 = Line2' Double -- type Matrix22 = Matrix22' Double ---- -- Much of the use of the types (especially vectors) in this library is -- made using type-classes such as Num, Functor, Applicative and so on. -- For more explanation on some of the less well-known type-classes, see -- either the article Typeclassopedia in The Monad Reader -- (http://www.haskell.org/haskellwiki/The_Monad.Reader) issue 13 -- (http://www.haskell.org/sitewiki/images/8/85/TMR-Issue13.pdf), -- or my own notes at http://www.twistedsquare.com/haskell.html. -- -- To understand what various functions will actually do, look at the -- SGdemo project -- (http://hackage.haskell.org/cgi-bin/hackage-scripts/package/SGdemo) -- on Hackage (and its code) which provides a visual demonstration of -- several of the functions. module Data.SG