Question

i need help about a rotation or spin matrix in haskell

i have a list of list, of a data type RGB:

data RGBdata= RGB Int Int Int

m = [[(RGB 0 255 255),(RGB 255 0 0)],[(RGB 255 255 255),(RGB 255 0 0)]]

to be seen better i have a matrix 2x2:

m = [[(RGB 1 2 3),(RGB 4 5 6)],
     [(RGB 7 8 9),(RGB 1 5 9)]]

and i need 90° rotation, i mean something like:

m = [[(RGB 7 8 9),(RGB 1 2 3)]
     [(RGB 1 5 9),(RGB 4 5 6)]]

Extends my explication, i have 2 data type:

data RGBdata= RGB Int Int Int
data PBMfile= PBM Int Int [[RGBdata]]

and my function receive:

spin :: PBMfile -> PBMfile
spin (PBM x y l) = (PBM x y ((transpose . reverse) l))

where 'x' and 'y' is the number of colums and rows respectively (maybe can help to do the function).

I try rotate 90° to the left with your anwer and the image result is wrong.

i try

spin :: PBMfile -> PBMfile
spin (PBM x y l) = (PBM x y ((reverse . transpose) l))

and

spin :: PBMfile -> PBMfile
spin (PBM x y l) = (PBM x y ((transpose . reverse) l))

and

spin :: PBMfile -> PBMfile
spin (PBM x y l) = (PBM x y (((map reverse) . transpose) l))

to rotate the image but does not work.

the result is something like

http://imageshack.us/photo/my-images/52/catmc.jpg/

Was it helpful?

Solution

TL;DR: transpose . reverse

If you're planning to use lists to store large images, bear in mind that it will probably be inefficient, since there's five boxed values (a lot of bytes) for every pixel. It'd be more efficient to use an unboxed Vector or Array instead. Just giving you a heads up.

That said, let's look at list operations in terms of what they do to the image.

> let demo f = mapM_ print $ f m
> demo id
[RGB 1 2 3,RGB 4 5 6]
[RGB 7 8 9,RGB 1 5 9]
> demo reverse
[RGB 7 8 9,RGB 1 5 9]
[RGB 1 2 3,RGB 4 5 6]
> demo (map reverse)
[RGB 4 5 6,RGB 1 2 3]
[RGB 1 5 9,RGB 7 8 9]
> demo (transpose)
[RGB 1 2 3,RGB 7 8 9]
[RGB 4 5 6,RGB 1 5 9]
  • reverse flips the image vertically (by reversing the rows)

  • map reverse flips the image horizontally (by reversing the pixels in each row)

  • transpose flips the image along the \ diagonal line.

Now, find a piece of paper, and figure out how to perform the desired rotation in terms of these operations (modeling transpose is tricky if your paper is rectangular). Remember that any time you see the back of the paper, the image will appear mirrored. Since each of these operations turns the paper around, you need an even number of them to perform a rotation.

The only rotation you can do with reverse and map reverse is turn the paper upside down. This means you'll need transpose to rotate the image 90°.

transpose (diagonal flip) followed by reverse (vertical flip) rotates the image 90° to the left:

> demo (reverse . transpose)
[RGB 4 5 6,RGB 1 5 9]
[RGB 1 2 3,RGB 7 8 9]

On the other hand, reverse (vertical flip) followed by transpose (diagonal flip) rotates the image 90° to the right (which you want):

> demo (transpose . reverse)
[RGB 7 8 9,RGB 1 2 3]
[RGB 1 5 9,RGB 4 5 6]

OTHER TIPS

If I understand you correctly, it looks like you want map reverse . transpose, where transpose is in Data.List:

> let x = [[1,2,3], [4,5,6], [7,8,9]]
> map reverse . transpose $ x
[[7,4,1],[8,5,2],[9,6,3]]

Note that this is probably slower than necessary if your input list is large enough, but that'll likely only come into play if your list is 1000 by 1000 or if you're doing this in a tight inner loop.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top