-1

我需要有关 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”分别是列数和行数(也许可以帮助执行该功能)。

我试着用你的答案向左旋转 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))

旋转图像但不起作用。

结果类似于

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

4

2 回答 2

7

TL;博士:transpose . reverse

如果您打算使用列表来存储大图像,请记住它可能效率低下,因为每个像素都有五个装箱值(很多字节)。使用未装箱的 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如果你的纸是矩形的,建模会很棘手)。请记住,只要您看到纸张的背面,图像就会出现镜像。由于这些操作中的每一个都将纸张翻转,因此您需要偶数个它们来执行旋转。

您可以做的唯一旋转reversemap 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° (您想要的):

> demo (transpose . reverse)
[RGB 7 8 9,RGB 1 2 3]
[RGB 1 5 9,RGB 4 5 6]
于 2012-05-02T03:27:00.477 回答
3

如果我理解正确,它看起来像你想要的,在map reverse . transpose哪里:transposeData.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 或者您在紧密的内部循环中执行此操作,则可能只会发挥作用。

于 2012-05-02T02:54:29.820 回答