7*      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~Safe9:;<=?TA modified version of  and   that adds the k constraint on the result. You are unlikely to need to use this class much directly. Some vectors have  and   instances anyway.Like  , but with a  constraint.Like   , but with a  constraint.Like 9, but can only be used if you won't change the magnitude:Like   (or  ) but with a  constraint.RThis class is implemented by all 3D vectors. To get the X and Y components, use  and   from .7This class is implemented by all 2D and 3D vectors, so 3 gets the X co-ordinate of both 2D and 3D vectors. -The class that is implemented by all vectors.&Minimal implementation: fromComponents ;Gets the components of the vector, in the order x, y (, z). Re-constructs a vector from the list of coordinates. If there are too few, the rest will be filled with zeroes. If there are too many, the latter ones are ignored. VGets the magnitude squared of the vector. This should be fast for repeated calls on   and  , which cache this value.,Computes the dot product of the two vectors.An isomorphism amongst vectors. Allows you to convert between two vectors that have the same dimensions. You will notice that all the instances reflect this.FThe origin/all-zero vector (can be used with any vector type you like)'Gets the magnitude of the given vector.Scales the vector so that it has length 1. Note that due to floating-point inaccuracies and so on, mag (unitVector v) will not necessarily equal 1, but it should be very close. If an all-zero vector is passed, the same will be returned.2This function should be very fast when called on   and  A; vectors that are already unit vectors (no processing is done).xGets the average vector of all the given vectors. Essentially it is the sum of the vectors, divided by the length, so *averageVec [Point2 (-3, 0), Point2 (5,0)] will give  Point2 (1,0):. If the list is empty, the all-zero vector is returned.6Like averageVec composed with unitVector -- gets the average of the vectors in the list, and normalises the length. If the list is empty, the all-zero vector is returned (which is therefore not a unit vector). Similarly, if the average of all the vectors is all-zero, the all-zero vector will be returned.VWorks out if the two vectors are in the same direction (to within a small tolerance).Gives back the vector (first parameter), translated onto given axis (second parameter). Note that the scale is always distance, not) related to the size of the axis vector.eProjects the first parameter onto the given axes (X, Y), returning a point in terms of the new axes.Gives back the point (first parameter), translated onto given axis (second parameter). Note that the scale is always distance, not) related to the size of the axis vector.mProjects the point (first parameter) onto the given axes (X, Y), returning a point in terms of the new axes.*Works out the distance between two points.      Safe9:;<=?TFA pair of (position vector, direction vector) to be used as a 3D line.FA pair of (position vector, direction vector) to be used as a 2D line.!"A quad, which acts as a 4D vector.#$A triple, which acts as a 3D vector.%"A pair, which acts as a 2D vector.$ !"#$%&'()*+,-./0123456789:;<=>?@  !"#$%&$%&#$!" @?>=<;:9876543210/.-,+*)(' !"#$%&'()*+,-./0123456789:;<=>?@Safe9:;<=?TU3A 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).0Minimal implementation: everything but scaleRel.V4Scales a relative (free) vector by the given amount.W/Adds a relative (free) vector to a given point.X&Determines the relative (free) vector to the first parameter from the second parameter. So: 3Point2 (1,8) `fromPt` Point2 (3,4) == Point2 (-2,3)YgGiven a line, converts it back into its point and relative vector. It should always be the case that uncurry makeLine . getLineVecs is the identity function.ZWGiven a point and relative vector, creates a line. It should always be the case that uncurry makeLine . getLineVecs is the identity function.[=Adds the negation of the relative (free) vector to the point.\The flipped version of X.]Gets the line from the first point, to the second point.^The flipped version of ]._(Gets the point at the start of the line.`&Gets the direction vector of the line.a&Gets the point at the end of the line.bQAlters the line to the given length, but with the same start point and direction.cGiven a multiple of the direction vector (this is notP distance unless the direction vector is a unit vector), calculates that point.d 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.eUChecks if the given point is on the given line (to within a small epsilon-tolerance).f 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.gRFinds the nearest point on the line to the given point, and gives back the point.hFGives 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.iFGives 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.j 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.k;pointAtX (and the Y and Z equivalents) are wrappers around hM (and similar) that give back the point rather than distance along the line.l;pointAtX (and the Y and Z equivalents) are wrappers around hM (and similar) that give back the point rather than distance along the line.UVWXYZ[\]^_`abcdefghijklmnoUVWXYZ[\]^_`abcdefghijklmUVWXYZon[\]^_`abcdefghijklmUVWXYZ[\]^_`abcdefghijklmnoSafe9:;<=?T pA 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).tmA relative vector (free vector) in 2D space. The pair are the x and y components, and the last item is the squared magnitudeb of the vector, which is stored with it to speed up various operations. It is suggested you use xO to create one of these, unless the square magnitude is easily apparent, e.g. Rel2 (0, 2) 4vA point in 2D space.xConstructs a Rel2' vector.yGets the angle, in radiansc, anti-clockwise from the x-axis. If you pass the all-zero vector, the return value will be zero.zGets 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.{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: FmakeRel2 (-3, -4) `reflectAgainst2` makeRel2 (0,1) == makeRel2 (-3, 4)|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)}5Given 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 lbC, it should be the case (minus some possible precision loss) that  alongLine a la == alongLine b lb3. 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.~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.`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.Like m0, but returns a 2D vector instead of a 3D vector8Multiplication doesn't make much sense, but the rest do!$pqrstuvwxyz{|}~pqrstuvwxyz{|}~vwtuxpqrsyz{|}~pqrstuvwxyz{|}~Safe9:;<=?TA 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).nA relative vector (free vector) in 3D space. The triple is the x, y, z components, and the last item is the squared magnitudeb of the vector, which is stored with it to speed up various operations. It is suggested you use H to create one of these, unless the magnitude is easily apparent, e.g. Rel3 (0, 1, 1) 2A point in 3D space.Constructs a Rel3' vector Safe9:;<=?T&The class that all matrices belong to.(Gives back the matrix as a list of rows.Creates a matrix from a list of rows. Any missing entries are filled in with the relevant entries from the identity matrix, hence the identity matrix is equivalent to fromMatrixComponents [].Transposes a matrix;A 4x4 matrix. Primarily useful via its instances, such as , , and .;A 3x3 matrix. Primarily useful via its instances, such as , , and .;A 2x2 matrix. Primarily useful via its instances, such as , , and .8A square matrix. You will almost certainly want to use h and similar instead of this directly. It does have a variety of useful instances though, especially ,  and .gIts definition is based on a square matrix being, for example, a pair of pairs or a triple of triples.The identity matrix.lMatrix multiplication. There is no requirement that the size of the matrix matches the size of the vector:If the vector is too small for the matrix (e.g. multiplying a 4x4 matrix by a 3x3 vector), 1 will be used for the missing vector entries.If the matrix is too small for the vector (e.g. multiplying a 2x2 matrix by a 3x3 vector), the other components of the vector will be left untouched.This allows you to do tricks such as multiplying a 4x4 matrix by a 3D vector, and doing translation (a standard 3D graphics trick).%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.Given an angle in radians, produces a matrix that rotates anti-clockwise by that angle around the Z axis. Note that this can be used to produce a 2x2 (in which case it is a rotation around the origin), 3x3 or 4x4 matrix.Given an angle in radians, produces a matrix that rotates anti-clockwise by that angle around the X axis. Note that this can be used to produce a 2x2, 3x3 or 4x4 matrix, but if you produce a 2x2 matrix, odd things will happen!Given an angle in radians, produces a matrix that rotates anti-clockwise by that angle around the Y axis. Note that this can be used to produce a 2x2, 3x3 or 4x4 matrix, but if you produce a 2x2 matrix, odd things will happen!Given a 2D relative vector, produces a matrix that will translate by that much (when you multiply a 2D point with it using multMatrixGen)Given a 3D relative vector, produces a matrix that will translate by that much (when you multiply a 3D point with it using multMatrixGen)Safe9:;<=?TtA type for simple 2D convex shapes. It is expected that you will define a synonym in your own application such as type Shape = Shape' Double, hence the funny name.A rectangle with a centre, and a width (distance from the centre to the left or right side of the rectangle) and a height (distance from the centre to the top or bottom side of the rectangle. So the rectangle with corners (1,1) and (3,2) is $Rectangle (Point2 (2,1.5)) (1, 0.5). Technically a rectangle is a polygon, of course, but a rectangle (which is axis-aligned) can be processed faster by most algorithms.$A circle with a centre and a radius.A polygon with a centre, and a list of points. The points are relative vectors from the centre of the polygon, and are expected to be in clockwise order. For example, the triangle with corners (1,1) (3,3) and (3,1) could be QPolygon (Point2 (2.5, 1.5)) [Rel2 (-1.5,-0.5), Rel2 (0.5,1.5), Rel2 (-1.5, 1.5)].RNote that whereabouts the centre is inside the polygon is up to you (it does not  have to be the geometric average of the points), but it should at least be inside the polygon, or else some algorithms will behave strangely with it.gThe list of points should have at least 3 points in it, or else some algorithms will behave strangely.If your points are not in clockwise order (with the X-Y axes being how they are in graphs, not on screens), funny things will happen with the collision detection.7Moves a shape by a given vector (by moving the centre).Given an angle in radians, rotates the shape by that angle in an anti-clockwise direction. A circle will remain untouched, a polygon will have its points rotated, and a rectangle will become a polygon and get rotated (even if you pass 0 as the angle).SScales the size of the shape (for all edges, from the centre) by the given factor.tGives back the bounding box of a shape in terms of the minimum X-Y and the maximum X-Y corners of the bounding box.VGiven a line and a shape, finds all possible intersections of the line with the shape. Since the shapes are convex, continuous 2D shapes, there will either be no intersections or two (which could be the same point). The returned value is distance along the line in multiples of the direction vector (the return value is the same idea as ).ZChecks for overlap between the two shapes. If they do not collide, returns Nothing. If they do collide, gives back suggested angles away from each other. These are not necessarily the shortest direction to separate the two shapes, but should be decent for doing collision resolution (by using them as surface normals, or push-away vectors)The first vector returned is the direction in which the first shape should head (or the surface normal to bounce the first shape off), whereas the second vector returned is the direction in which the second shape should head (or the surface normal to bounce the second shape off).]This function includes an initial quick test, followed by a more detailed test if necessary.'A quick test for possible intersection.If it returns False, there is definitely no overlap. If it returns True, there might be some overlap. For two circles, radiuses are checked (and the answer is always accurate), for any other combination of shapes it checks bounding boxes.Collects a list of (unit-vector) axes perpendicular to all the edges of the polygon, pointed outwards. The list will be empty for circles.Given a shape, gets a list of relative vectors from the centre of the shape to the points of the shape. For polygons, this is the points list (unmodified). For rectangles, it will be vectors to the four corners, and for circles, the list will be empty.tGiven a shape, gets a list of points that make up the vertices of the shape. For circles, this list will be empty.sGets a list of lines representing each side of the shape (headed clockwise). For circles, the list will be empty. Safe9:;<=?Ty  !"#$%&UVWXYZ[\]^_`abcdefghijklmpqrstuvwxyz{|}~ !"#$%&'()*+,,--..//00123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} ~      !SGplus-1.1-JgfgTGiP5Kq5SsrQsJxqF3Data.SG.VectorData.SG.Vector.BasicData.SG.GeometryData.SG.Geometry.TwoDimData.SG.Geometry.ThreeDimData.SG.Matrix Data.SG.ShapeControl.Applicative ApplicativeliftA2pureRel2'Rel3'Data.SG VectorNumfmapNum1fmapNum2 fmapNum1inv simpleVecCoord3getZCoord2getXgetYCoord getComponentsfromComponentsmagSq dotProductIsomorphicVectorsisooriginmag unitVector averageVecaverageUnitVec sameDirection projectOnto projectOnto2projectPointOntoprojectPointOnto2distFrom$fIsomorphicVectorsvv LineTripleLinePairQuadTriplePair $fCoord3Quad $fCoord2Quad $fCoordQuad$fCoord3Triple$fCoord2Triple $fCoordTriple $fCoord2Pair $fCoordPair $fFunctorQuad$fFunctorTriple $fFunctorPair$fTraversableQuad$fFoldableQuad$fApplicativeQuad$fTraversableTriple$fFoldableTriple$fApplicativeTriple$fTraversablePair$fFoldablePair$fApplicativePair $fNumQuad $fNumTriple $fNumPair$fVectorNumQuad$fVectorNumTriple$fVectorNumPair$fEqPair $fOrdPair $fShowPair $fReadPair $fEqTriple $fOrdTriple $fShowTriple $fReadTriple$fEqQuad $fOrdQuad $fShowQuad $fReadQuad $fEqLinePair $fOrdLinePair$fShowLinePair$fReadLinePair$fEqLineTriple$fOrdLineTriple$fShowLineTriple$fReadLineTripleGeometryscaleRelplusDirfromPt getLineVecsmakeLineminusDirtoPtlineTolineFrom getLineStart getLineDir getLineEnd makeLength alongLine distAlongLineisOnLinenearestDistOnLinenearestPointOnLinevalueAtXvalueAtYvalueAtZpointAtXpointAtYpointAtZ $fGeometryTripleTripleLineTriple$fGeometryPairPairLinePairLine2'Line2 getLineStart2 getLineDir2Rel2Point2'Point2makeRel2toAngleperpendicular2reflectAgainst2reflectAgainstIfNeeded2intersectLines2findAllIntersections2intersectLineCircle point2AtZ$fGeometryRel2'Point2'Line2' $fCoordRel2' $fCoord2Rel2'$fCoordPoint2'$fCoord2Point2'$fTraversablePoint2'$fFoldableRel2'$fFoldablePoint2'$fApplicativePoint2'$fFunctorPoint2' $fNumRel2'$fVectorNumPoint2'$fVectorNumRel2'$fIsomorphicVectorsPairPoint2'$fIsomorphicVectorsPoint2'Pair$fIsomorphicVectorsPairRel2'$fIsomorphicVectorsRel2'Pair$fIsomorphicVectorsPoint2'Rel2'$fIsomorphicVectorsRel2'Point2' $fEqPoint2' $fOrdPoint2' $fShowPoint2' $fReadPoint2' $fEqRel2' $fOrdRel2' $fShowRel2' $fReadRel2' $fEqLine2' $fShowLine2' $fReadLine2'Line3'Line3 getLineStart3 getLineDir3Rel3Point3'Point3makeRel3$fGeometryRel3'Point3'Line3' $fCoordRel3'$fCoordPoint3' $fCoord3Rel3' $fCoord2Rel3'$fCoord3Point3'$fCoord2Point3'$fTraversablePoint3'$fFoldableRel3'$fFoldablePoint3'$fApplicativePoint3'$fFunctorPoint3' $fNumRel3'$fVectorNumPoint3'$fVectorNumRel3' $fIsomorphicVectorsTriplePoint3' $fIsomorphicVectorsPoint3'Triple$fIsomorphicVectorsTripleRel3'$fIsomorphicVectorsRel3'Triple$fIsomorphicVectorsPoint3'Rel3'$fIsomorphicVectorsRel3'Point3' $fEqPoint3' $fOrdPoint3' $fShowPoint3' $fReadPoint3' $fEqRel3' $fOrdRel3' $fShowRel3' $fReadRel3' $fEqLine3' $fShowLine3' $fReadLine3'MatrixmatrixComponentsfromMatrixComponents transpose Matrix44' Matrix33' Matrix22' SquareMatrixidentityMatrix multMatrixGen multMatrix rotateZaxis rotateXaxis rotateYaxis translate2D translate3D$fNumSquareMatrix$fMatrixSquareMatrix$fReadSquareMatrix$fShowSquareMatrix$fTraversableSquareMatrix$fFoldableSquareMatrix$fEqSquareMatrix$fApplicativeSquareMatrix$fFunctorSquareMatrixShape' RectangleCirclePolygon shapeCentrerectSizecircSize polyPoints moveShape rotateShape scaleShape boundingBoxintersectLineShapeoverlap shapePoints $fShowShape' $fReadShape' $fEqShape' $fOrdShape'baseGHC.BaseFunctorGHC.NumNumfmap fromIntegerfromListpossibleOverlap collectAxes polygonPoints polygonLinespts twoFromListbetween projectShape pairsInLoopdetailedOverlap