Java俄罗斯方块 - 使用旋转矩阵进行旋转

4
我正在用Java构建俄罗斯方块游戏,试图使用线性代数来旋转由4个小方块组成的方块。
我的朋友解释了如何实现:
他说:“需要澄清的是,您确实需要旋转每个点 - 也就是说,您需要为方块中的每个小方块旋转一个点。但不是为方块中的每个小方块旋转四个角落。原点就像是您将一支铅笔插入纸片并围绕着旋转... 铅笔所在的位置就是原点。”
所以我用坐标(1,3)(1,2)(1,1)(2,2)... 并且原点为(1,2)。
然后他说:“您将小方块移动到相对于原点的位置。也就是说,您将原点视为此旋转的新(0,0)。这很容易,只需从每个坐标中减去原点即可,得到(-1,0)(0,0)(1,0)(0,1)。”
从每个坐标中减去原点(1,2),得到(1-1,3-2)(1-1,2-2)(1-1,1-2)(2-1,2-2) = (0,1)(0,0)(0,-1)(1,0)
然后他说:“现在使用旋转矩阵乘法旋转这四个坐标,就像我们一直在讨论的那样。”
最后他说:“然后将原始坐标添加回每个结果坐标中,现在您就有了旋转后的四个小方块坐标。”
从上面的矩阵中,我得到(0,-1)(0,0)(0,1)(-1,0)... 所以我按他所说的将它们添加到原始坐标中:(1-1,3+0)(1+0,2+0)(1+0,1+1)(2-1,2+0) = 旋转后的坐标:(0,3)(1,2)(1,2)(1,2)。

然而,看着我旋转的形状... 它完全是错误的:

在此输入图片描述

有什么想法为什么会这样吗?

谢谢!

2个回答

1

你有两个错误。

错误1:

你进行了以下数学计算:

(1-1, 3-2) (1-1, 2-2) (1-1, 1-2) (2-1, 2-2) =

(0, 1) (0, 0) (0, -1) (1, 0)

但是你在数学公式(图像)中实际写下的矩阵是:

[ -1 0 1 0 ]
[  0 0 0 1 ]

当它本应该是:

[ 0 0  0 1 ]
[ 1 0 -1 0 ]

这就是为什么它看起来像是一个180度的旋转,因为你将旋转矩阵乘了两次。

错误2:

你应该将所有输出点添加到原点。

你说:

从上面的矩阵中,我得到了(0,-1)(0,0)(0,1)(-1,0)...所以我按照他说的将它们添加到原始坐标中(1-1,3+0)(1+0,2+0)(1+0,1+1)(2-1,2+0)=(0,3)(1,2)(1,2)(1,2)

但你真正需要做的是将它们添加到原点,即

(0, -1) (0, 0) (0, 1) (-1, 0) - 矩阵输出

(0 + 1, -1 + 2) (0 + 1, 0 + 2) (0 + 1, 1 + 2) (-1 + 1, 0 + 2) - 加回原点(原点坐标加粗)

(1, 1) (1, 2) (1, 3) (0, 2) - 得到的点


哎呀,我猜那是有道理的吧... 很明显如果我减去原点,我需要把它加回来... 哎呀哈哈 - user3871
我想问一下,每个新的坐标(x,y)在您的矩阵中都是一个新的列,这样理解对吗? - user3871
我不太确定,但是你帖子里除了那个“粗心的错误”之外其他地方看起来都很完美。 - durron597
我刚刚注意到,你的结果(1, 1) (1, 2) (1, 3) (0, 2)是从我的原始输入(1, 3) (1, 2) (1, 1) (2, 2)中作为坐标(x, y)而不是(行, 列)得出的...它所做的只是将块水平翻转180度...我不明白这是怎么可能的,因为我的乘法矩阵是R(90度),而不是R(180度)。为什么会这样? - user3871
该死的愚蠢错误...我真的不确定为什么我把它复制到图像中:/ - user3871
显示剩余3条评论

1
我已经有一段时间没有做矩阵乘法了,但是你插入旋转矩阵的点的顺序似乎与您取出点的顺序不同。您说您剩下了(0,-1) (0,0) (0,1) (-1,0)。这看起来好像列是您的点,顶部是您的x,底部是您的y。如果您对第一组点使用相同的约定,那么您乘以旋转矩阵的矩阵将是(-1,0) (0,0) (1,0) (0,1),这不是您开始的点集。由于您开始的点是(0,1) (0,0) (0,-1) (1,0),所以您需要使用以下矩阵:| 0 0 0 1 |1 0 -1 0 |作为要乘的矩阵,我认为您最终会得到点(-1,0),(0,0),(1,0),(0,1)。

我一直认为矩阵(向量)是按照(x,y)排列的 - 每个新坐标(x,y)都是矩阵中的新列。这不是这种情况吗? - user3871
@Growler 我不是很确定,我只是注意到你在第一个矩阵中将坐标写成了(y,x),而在取出时却变成了(x,y)。 - Mike
Mike,我是不是要将(-1,0),(0,0),(1,0),(0,1)(您下面提供的结果点)添加到我的原始坐标(1,3)(1,2)(1,1)(2,2)中? 如果是这样,我得到的是(0,3)(1,2)(2,1)(2,3),但无法正确绘制。 - user3871

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接