SG-1.0: Small geometry library for dealing with vectors and collision detection

Data.SG.Geometry.TwoDim

Description

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.

Synopsis

Documentation

data Rel2' a Source

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

Constructors

Rel2 (a, a) a 

Instances

makeRel2 :: Num a => (a, a) -> Rel2' aSource

Constructs a Rel2' vector.

data Line2' a Source

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).

Constructors

Line2 

Instances

Geometry Rel2' Point2' Line2' 
Eq a => Eq (Line2' a) 
Read a => Read (Line2' a) 
Show a => Show (Line2' a) 

toAngle :: RealFloat a => Rel2' a -> aSource

Gets the angle, in radians, anti-clockwise from the x-axis. If you pass the all-zero vector, the return value will be zero.

perpendicular2 :: Num a => Rel2' a -> Rel2' aSource

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.

reflectAgainst2 :: (Floating a, Ord a) => Rel2' a -> Rel2' a -> Rel2' aSource

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)

reflectAgainstIfNeeded2 :: (Floating a, Ord a) => Rel2' a -> Rel2' a -> Rel2' aSource

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)

intersectLines2 :: Fractional a => Line2' a -> Line2' a -> Maybe (a, a)Source

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.

findAllIntersections2 :: Fractional a => ([Line2' a], [Line2' a]) -> [((Line2' a, a), (Line2' a, a))]Source

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.

intersectLineCircle :: (Ord a, Floating a) => Line2' a -> (Point2' a, a) -> Maybe (a, a)Source

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.

point2AtZ :: (Geometry rel pt ln, Coord3 rel, Coord3 pt, Fractional a) => ln a -> a -> Maybe (Point2' a)Source

Like pointAtZ, but returns a 2D vector instead of a 3D vector