Portability | GHC with TypeFamilies and more |
---|---|
Stability | unstable |
Maintainer | stephen.tetley@gmail.com |
Objects and operations for 2D geometry.
Vector, point, affine frame, 3x3 matrix, and radian
representations, plus a type family DUnit
for parameterizing
type classes with some dimension.
- type family DUnit a :: *
- data Vec2 a = V2 !a !a
- type DVec2 = Vec2 Double
- data Point2 a = P2 !a !a
- type DPoint2 = Point2 Double
- data Frame2 a = Frame2 (Vec2 a) (Vec2 a) (Point2 a)
- type DFrame2 = Frame2 Double
- data Matrix3'3 a = M3'3 !a !a !a !a !a !a !a !a !a
- type DMatrix3'3 = Matrix3'3 Double
- data Radian
- class Pointwise sh where
- class MatrixMult t where
- direction :: (Floating a, Real a) => Vec2 a -> Radian
- hvec :: Num a => a -> Vec2 a
- vvec :: Num a => a -> Vec2 a
- avec :: Floating a => Radian -> a -> Vec2 a
- pvec :: Num a => Point2 a -> Point2 a -> Vec2 a
- vangle :: (Floating a, Real a, InnerSpace (Vec2 a)) => Vec2 a -> Vec2 a -> Radian
- zeroPt :: Num a => Point2 a
- langle :: (Floating a, Real a) => Point2 a -> Point2 a -> Radian
- ortho :: Num a => Point2 a -> Frame2 a
- displaceOrigin :: Num a => Vec2 a -> Frame2 a -> Frame2 a
- pointInFrame :: Num a => Point2 a -> Frame2 a -> Point2 a
- frame2Matrix :: Num a => Frame2 a -> Matrix3'3 a
- matrix2Frame :: Matrix3'3 a -> Frame2 a
- frameProduct :: (Num a, InnerSpace (Vec2 a)) => Frame2 a -> Frame2 a -> Frame2 a
- standardFrame :: Num a => Frame2 a -> Bool
- identityMatrix :: Num a => Matrix3'3 a
- scalingMatrix :: Num a => a -> a -> Matrix3'3 a
- translationMatrix :: Num a => a -> a -> Matrix3'3 a
- rotationMatrix :: (Floating a, Real a) => Radian -> Matrix3'3 a
- originatedRotationMatrix :: (Floating a, Real a) => Radian -> Point2 a -> Matrix3'3 a
- invert :: Fractional a => Matrix3'3 a -> Matrix3'3 a
- determinant :: Num a => Matrix3'3 a -> a
- transpose :: Matrix3'3 a -> Matrix3'3 a
- req :: Radian -> Radian -> Bool
- toRadian :: Real a => a -> Radian
- fromRadian :: Fractional a => Radian -> a
- d2r :: (Floating a, Real a) => a -> Radian
- r2d :: (Floating a, Real a) => Radian -> a
- circularModulo :: Radian -> Radian
Type family
Data types
2D Vector - both components are strict.
V2 !a !a |
Functor Vec2 | |
Eq a => Eq (Vec2 a) | |
Show a => Show (Vec2 a) | |
Num a => Monoid (Vec2 a) | |
Num a => VectorSpace (Vec2 a) | |
(Scalar a ~ a, Num a, InnerSpace a) => InnerSpace (Vec2 a) | |
Num a => AdditiveGroup (Vec2 a) | |
Pretty a => Pretty (Vec2 a) | |
Num a => MatrixMult (Vec2 a) | |
Pointwise (Vec2 a) | |
Num u => Translate (Vec2 u) | |
Num u => Scale (Vec2 u) | |
(Floating a, Real a) => RotateAbout (Vec2 a) | |
(Floating a, Real a) => Rotate (Vec2 a) |
2D Point - both components are strict.
Point2 derives Ord so it can be used as a key in Data.Map etc.
P2 !a !a |
Functor Point2 | |
Eq a => Eq (Point2 a) | |
Ord a => Ord (Point2 a) | |
Show a => Show (Point2 a) | |
Num a => AffineSpace (Point2 a) | |
Pretty a => Pretty (Point2 a) | |
Ord a => CMinMax (Point2 a) | |
Num a => MatrixMult (Point2 a) | |
Pointwise (Point2 a) | |
Num u => Translate (Point2 u) | |
Num u => Scale (Point2 u) | |
(Floating a, Real a) => RotateAbout (Point2 a) | |
(Floating a, Real a) => Rotate (Point2 a) |
A two dimensional frame.
The components are the two basis vectors e0
and e1
and
the origin o
.
Typically these names for the elements will be used:
Frame2 (V2 e0x e0y) (V2 e1x e1y) (P2 ox oy)
3x3 matrix, considered to be in row-major form.
(M3'3 a b c d e f g h i)
For instance the rotation matrix is represented as
( cos(a) -sin(a) 0 sin(a) cos(a) 0 0 0 1 )
This seems commplace in geometry texts, but PostScript
represents the current-transformation-matrix
in
column-major form.
The right-most column is considered to represent a coordinate:
( 1 0 x 0 1 y 0 0 1 )
So a translation matrix representing the displacement in x of 40 and in y of 10 would be:
( 1 0 40 0 1 10 0 0 1 )
M3'3 !a !a !a !a !a !a !a !a !a |
type DMatrix3'3 = Matrix3'3 DoubleSource
Radian is represented with a distinct type. Equality and ordering are approximate where the epsilon is 0.0001.
Pointwise type class
class Pointwise sh whereSource
Pointwise is a Functor like type class, except that the container/element relationship is defined via an associated type rather than a type parameter. This means that applied function must be type preserving.
Matrix multiply type class
class MatrixMult t whereSource
Matrix multiplication - typically of points and vectors represented as homogeneous coordinates.
Num a => MatrixMult (Point2 a) | |
Num a => MatrixMult (Vec2 a) |
Vector operations
direction :: (Floating a, Real a) => Vec2 a -> RadianSource
Direction of a vector - i.e. the counter-clockwise angle from the x-axis.
pvec :: Num a => Point2 a -> Point2 a -> Vec2 aSource
The vector between two points
pvec = flip (.-.)
vangle :: (Floating a, Real a, InnerSpace (Vec2 a)) => Vec2 a -> Vec2 a -> RadianSource
Extract the angle between two vectors.
Point operations
langle :: (Floating a, Real a) => Point2 a -> Point2 a -> RadianSource
Calculate the counter-clockwise angle between two points and the x-axis.
Frame operations
ortho :: Num a => Point2 a -> Frame2 aSource
Create a frame with standard (orthonormal bases) at the supplied point.
displaceOrigin :: Num a => Vec2 a -> Frame2 a -> Frame2 aSource
Displace the origin of the frame by the supplied vector.
pointInFrame :: Num a => Point2 a -> Frame2 a -> Point2 aSource
'World coordinate' calculation of a point in the supplied frame.
frame2Matrix :: Num a => Frame2 a -> Matrix3'3 aSource
Concatenate the elements of the frame as columns forming a 3x3 matrix. Points and vectors are considered homogeneous coordinates - triples where the least element is either 0 indicating a vector or 1 indicating a point:
Frame (V2 e0x e0y) (V2 e1x e1y) (P2 ox oy)
becomes
(M3'3 e0x e1x ox e0y e1y oy 0 0 1 )
matrix2Frame :: Matrix3'3 a -> Frame2 aSource
Interpret the matrix as columns forming a frame.
(M3'3 e0x e1x ox e0y e1y oy 0 0 1 )
becomes
Frame (V2 e0x e0y) (V2 e1x e1y) (P2 ox oy)
frameProduct :: (Num a, InnerSpace (Vec2 a)) => Frame2 a -> Frame2 a -> Frame2 aSource
Multiplication of frames to form their product.
standardFrame :: Num a => Frame2 a -> BoolSource
Is the origin at (0,0) and are the basis vectors orthogonal with unit length?
Matrix contruction
identityMatrix :: Num a => Matrix3'3 aSource
Construct the identity matrix:
(M3'3 1 0 0 0 1 0 0 0 1 )
scalingMatrix :: Num a => a -> a -> Matrix3'3 aSource
Construct a scaling matrix:
(M3'3 sx 0 0 0 sy 0 0 0 1 )
translationMatrix :: Num a => a -> a -> Matrix3'3 aSource
Construct a translation matrix:
(M3'3 1 0 x 0 1 y 0 0 1 )
rotationMatrix :: (Floating a, Real a) => Radian -> Matrix3'3 aSource
Construct a rotation matrix:
(M3'3 cos(a) -sin(a) x sin(a) cos(a) y 0 0 1 )
originatedRotationMatrix :: (Floating a, Real a) => Radian -> Point2 a -> Matrix3'3 aSource
Construct a matrix for rotation about some point.
This is the product of three matrices: T R T^-1
(T being the translation matrix, R the rotation matrix and T^-1 the inverse of the translation matrix).
matrix operations
invert :: Fractional a => Matrix3'3 a -> Matrix3'3 aSource
Invert a matrix.
determinant :: Num a => Matrix3'3 a -> aSource
Determinant of a matrix.
Radian operations
req :: Radian -> Radian -> BoolSource
Equality on radians, this is the operation used for (==) in Radian's Eq instance.
fromRadian :: Fractional a => Radian -> aSource
Convert from radians.
circularModulo :: Radian -> RadianSource
Modulate a (positive) angle to be in the range 0..2*pi