\begin{code}
{-# OPTIONS -XFlexibleInstances -XNamedFieldPuns #-}
module Graphics.Typography.Geometry (Matrix2(..),
inverse,rotation,
Geometric(..),
leftMost,rightMost,topMost,bottomMost)
where
import Algebra.Polynomials.Numerical
data Matrix2 a=
Matrix2 a a a a deriving (Show, Read, Eq)
inverse::(Fractional a, Num a)=>Matrix2 a->Matrix2 a
inverse (Matrix2 a b c d)=
let det=a*d-c*b in
Matrix2 (d/det) (-b/det) (-c/det) (a/det)
instance Num a=>Num (Matrix2 a) where
(+) (Matrix2 a b c d) (Matrix2 e f g h)=
Matrix2 (a+e) (b+f) (c+g) (d+h)
(*) (Matrix2 a b c d) (Matrix2 e f g h)=
Matrix2 (a*e+b*g) (a*f+b*h) (c*e+d*g) (c*f+d*h)
fromInteger a=Matrix2 (fromInteger a) 0 0 (fromInteger a)
abs=undefined
signum=undefined
instance Intervalize Matrix2 where
intervalize (Matrix2 a b c d)=
Matrix2 (interval a) (interval b) (interval c) (interval d)
intersects (Matrix2 a b c d) (Matrix2 a' b' c' d')=
(intersectsd a a') &&
(intersectsd b b') &&
(intersectsd c c') &&
(intersectsd d d')
class Geometric g where
translate::Double->Double->g->g
apply::Matrix2 Double->g->g
rotation::Floating a=>a->Matrix2 a
rotation theta=
let ct=cos theta
st=sin theta
in
Matrix2 ct (-st) st ct
instance Geometric g=>Geometric [g] where
translate x y cur=map (translate x y) cur
apply m cur=map (apply m) cur
leftMost::(Double,Double)->(Double,Double)->(Double,Double)
leftMost u@(a,_) v@(b,_)
| a<b = u
| otherwise = v
rightMost::(Double,Double)->(Double,Double)->(Double,Double)
rightMost u@(a,_) v@(b,_)
| a<b = v
| otherwise = u
bottomMost::(Double,Double)->(Double,Double)->(Double,Double)
bottomMost u@(_,a) v@(_,b)
| a<b = u
| otherwise = v
topMost::(Double,Double)->(Double,Double)->(Double,Double)
topMost u@(_,a) v@(_,b)
| a<b = v
| otherwise = u
\end{code}