我需要有关haskell中旋转或旋转矩阵的帮助
我有一个数据类型为RGB的列表列表:
data RGBdata= RGB Int Int Int
m = [[(RGB 0 255 255),(RGB 255 0 0)],[(RGB 255 255 255),(RGB 255 0 0)]]
更好看我有一个矩阵2x2:
m = [[(RGB 1 2 3),(RGB 4 5 6)],
[(RGB 7 8 9),(RGB 1 5 9)]]
我需要90°旋转,我的意思是:
m = [[(RGB 7 8 9),(RGB 1 2 3)]
[(RGB 1 5 9),(RGB 4 5 6)]]
扩展我的解释,我有2种数据类型:
data RGBdata= RGB Int Int Int
data PBMfile= PBM Int Int [[RGBdata]]
我的功能收到:
spin :: PBMfile -> PBMfile
spin (PBM x y l) = (PBM x y ((transpose . reverse) l))
其中'x'和'y'分别是colums和rows的数量(可能有助于执行该功能)。
我尝试用你的anwer向左旋转90°,图像结果错误。
我试试
spin :: PBMfile -> PBMfile
spin (PBM x y l) = (PBM x y ((reverse . transpose) l))
和
spin :: PBMfile -> PBMfile
spin (PBM x y l) = (PBM x y ((transpose . reverse) l))
和
spin :: PBMfile -> PBMfile
spin (PBM x y l) = (PBM x y (((map reverse) . transpose) l))
旋转图像但不起作用。
结果类似于
答案 0 :(得分:7)
如果您计划使用列表来存储大图像,请记住它可能效率低下,因为每个像素有五个盒装值(很多字节)。使用未装箱的Vector或Array会更有效。只是给你一个抬头。
那就是说,让我们根据他们对图像所做的事情来看一下列表操作。
> 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
垂直翻转图像(通过反转行)
map reverse
水平翻转图像(通过反转每行中的像素)
transpose
沿着\
对角线翻转图像。
现在,找一张纸,弄清楚如何根据这些操作执行所需的旋转(如果你的纸是矩形的,建模transpose
很棘手)。请记住,只要看到纸张背面,图像就会显示为镜像。由于这些操作中的每一个都会转动纸张,因此需要偶数个来执行旋转。
您可以使用reverse
和map reverse
进行的唯一轮播是将文件翻转过来。这意味着您需要transpose
将图像旋转90°。
transpose
(对角线翻转)后跟reverse
(垂直翻转)将图像旋转90°到左:
> demo (reverse . transpose)
[RGB 4 5 6,RGB 1 5 9]
[RGB 1 2 3,RGB 7 8 9]
另一方面,reverse
(垂直翻转)后跟transpose
(对角线翻转)将图像旋转90°到右(你想要的):< / p>
> demo (transpose . reverse)
[RGB 7 8 9,RGB 1 2 3]
[RGB 1 5 9,RGB 4 5 6]
答案 1 :(得分:3)
如果我理解正确,您似乎需要map reverse . transpose
,其中transpose
位于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]]
请注意,如果您的输入列表足够大,这可能比必要的慢,但如果您的列表是1000 x 1000,或者如果您在紧密的内循环中执行此操作,则可能只会发挥作用。