In computer graphics, spatial transforms are commonly represented by matrices, and hence are restricted to special classes like linear, affine, or projective.
Application of transformations is implemented as a matrix/vector multiplication, and composition as matrix/matrix multiplication. In fact, this representation is so common that transforms are often thought of as being matrices.
A simpler and more general point of view, however, is that transforms are simply space-to-space functions:
type Transform = Point * Point
It is then easy to define the familiar affine transforms:
type Vector = (Float, Float)
translateP :: Vector -> Transform
translateP (dx, dy) (x, y) = (x + dx, y + dy)
scaleP :: Vector -> Transform
scaleP (sx, sy) (x, y) = (sx × x, sy × y)
uscaleP :: Float -> Transform — uniform
uscaleP s = scaleP (s, s)
rotateP :: Float -> Transform
rotateP theta (x, y) = (x × cos theta - y × sin theta ,y × cos theta + x × sin theta)
By definition, transforms map points to points. Can we ‘apply’ them, in some sense, to map images into transformed images?
applyTrans :: Transform -> Image a -> Image a
A look at the definitions of the Image and Transform types suggests the following
simple definition:
applyTrans xf im ?= im · xf — wrong
udisk :: Region
udisk p = distO p < 1
Notice that the uscaleP-composed udisk is half rather than twice the size of udisk. (Similarly, udisk · translateP (1, 0) moves udisk to the left rather than right.) The reason is that uscaleP 2 maps input points to be twice as far from the origin, so points have to start out within 1/2 unit of the origin in order for their scaled counterparts to be within 1 unit.
In general, to transform an image, we must inversely transform sample points before feeding them to the image being transformed:
applyTrans xf im = im · xf -1
While this definition is simple and general, it has the serious problem of requiring inversion of arbitrary spatial mappings. Not only is it sometimes
difficult to construct inverses, but also some interesting mappings are manyto-one and hence not invertible. In fact, from an image-centric point-of-view, we only need the inverses and not the transforms themselves. For these reasons, we simply construct the transforms in inverted form, and do not use applyTrans.
Partager