{-
Affine Transformation:
[ x'] [ A B C ] [ x ] [ Ax+By+C ]
[ y'] = [ D E F ] [ y ] = [ Dx+Ey+F ]
[ 1 ] [ 0 0 1 ] [ 1 ] [ 1 ]
If the affine transform matrix is not invertible,
which means the determinant of the matrix is zero,
than that means all points transform to a point or a line.
Det == 0 <=> A*E - B*D == 0
(1) A == E == B == D == 0
It transforms all (x,y) to point (C,F). (x'==C, y'==F)
(2) A*E == B*D && not all A,E,B,D == 0
x' = Ax+By+C
y' = Dx+Ey+F
<=> Dx' = ADx + BDy + CD
Ay' = ADx + AEy + AF
<=> Dx' - Ay' = CD - AF
<=> so, it transforms all point (x,y) to the line
Dx' - Ay' + AF - CD = 0
-}
type Coordinate = (Float, Float)
type AffineTransformMatrix = [Float]
data Region
= UnitCircle
| Polygon [Coordinate]
| Empty
| AffineTransform AffineTransformMatrix Region
containsR :: Region -> Coordinate -> Bool
UnitCircle `containsR` (x, y) = x*x + y*y <= 1
-- Polygon ps `containsR` p = <<< see ex.8.12 >>>
Empty `containsR` p = False
AffineTransform matrix region `containsR` (x, y)
| matrix' == Nothing =
let (a:b:c:d:e:f:_) = matrix
in if (a == 0 && b == 0 && d == 0 && e == 0)
then (x == c && y == f) -- transform to a point
else (d*x - a*y + a*f - c*d == 0) -- transform to a line
| otherwise =
let Just m' = matrix'
x' = (m'!!0)*x + (m'!!1)*y + (m'!!2)
y' = (m'!!3)*x + (m'!!4)*y + (m'!!5)
in region `containsR` (x', y')
where
matrix' = inverse3×3 $ take 6 matrix ++ [0, 0, 1]
-- http://mathworld.wolfram.com/MatrixInverse.html
inverse3×3 :: [Float] -> Maybe [Float]
inverse3×3 matrix@[a11, a12, a13,
a21, a22, a23,
a31, a32, a33]
| det == 0 = Nothing
| otherwise = Just $
map (/ det)
[ a22*a33 - a23*a32, a13*a32 - a12*a33, a12*a23 - a13*a22,
a23*a31 - a21*a33, a11*a33 - a13*a31, a13*a21 - a11*a23,
a21*a32 - a22*a31, a12*a31 - a11*a32, a11*a22 - a12*a21]
where det = determinant3×3 matrix
-- http://mathworld.wolfram.com/Determinant.html
determinant3×3 :: [Float] -> Float
determinant3×3 [a11, a12, a13,
a21, a22, a23,
a31, a32, a33]
= a11*a22*a33 + a12*a23*a31 + a13*a21*a32
- a13*a22*a31 - a12*a21*a33 - a11*a23*a32
This entry was posted
on Monday, June 4th, 2007 at 5:16 pm and is filed under Haskell - SOE.
You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.