Matrix 围绕轴心旋转心形物?(俄罗斯方块)

Matrix 围绕轴心旋转心形物?(俄罗斯方块),matrix,rotation,tetris,Matrix,Rotation,Tetris,我正试图设计我自己的俄罗斯方块克隆,但在形状旋转方面遇到了一个小问题。我有一个2维数组,表示一个10 x 20的游戏网格和单个形状对象,初始化时包含形状从网格上开始下落的坐标。例如,当用户向下移动形状时,每个坐标的y值都会减小,并且这个变化会反映在网格上 我似乎无法找到使用此实现处理形状旋转的有效方法。是否有任何方法可以使用矩阵来表示指定轴周围的坐标 如有任何建议,我们将不胜感激 谢谢。当然,请查阅“仿射变换”。但在你的例子中,你得到的是一个物体在离散角度的四个可能的旋转,没有70.3°的旋转,

我正试图设计我自己的俄罗斯方块克隆,但在形状旋转方面遇到了一个小问题。我有一个2维数组,表示一个10 x 20的游戏网格和单个形状对象,初始化时包含形状从网格上开始下落的坐标。例如,当用户向下移动形状时,每个坐标的y值都会减小,并且这个变化会反映在网格上

我似乎无法找到使用此实现处理形状旋转的有效方法。是否有任何方法可以使用矩阵来表示指定轴周围的坐标

如有任何建议,我们将不胜感激


谢谢。

当然,请查阅“仿射变换”。但在你的例子中,你得到的是一个物体在离散角度的四个可能的旋转,没有70.3°的旋转,只有0,90°,180°,270°。那么为什么不进行预计算呢?

这是经典的线性代数。你正在寻找一个旋转矩阵,除了你所有的角度都是直角,所以你可以预先计算正弦和余弦


要围绕一个点执行此操作,您必须先减去中心值(使该参考点成为中心原点),然后应用矩阵,并将原始中心位置加回来。

如果经典旋转矩阵有效,将取决于您要使用的。我将以此为例

围绕原点逆时针旋转的旋转矩阵为:

[0 -1]
[1  0]
现在,假设您有一个坐标列表[(0,1),(1,1),(2,1),(3,1)],表示初始位置的I块:

 0123
0....
1####
2....
3....
请注意,我没有使用笛卡尔坐标系,而是使用通常的屏幕坐标,从左上角开始。要正确旋转块,首先必须考虑y轴的翻转。然后,旋转矩阵变为:

[ 0 1]  ->  x_new = y_old
[-1 0]  ->  y_new = -x_old
接下来,要围绕轴心点旋转,在旋转之前,必须移动坐标,使轴心点成为原点(下面称为
sb
),并在旋转后将其移回原点(下面称为
sa
):

通常你会有
sb=sa
,但对于俄罗斯方块,轴心点有时在两个单元格之间的网格上(对于I-和O-区块),有时在单元格的中心(对于所有其他区块)

原来

sa_x = 0
sb_x = 0
sa_y = 1
sb_y = me - 2
其中
me
是要旋转的块的最大范围(即2、3或4),适用于所有块。总之,你可以得到:

x_new = y_old
y_new = 1 - (x_old - (me - 2))
顺时针旋转类似,但如果缓存块方向的所有坐标,则只需要一个方向


对于其他旋转系统,移位变量的其他值可能会起作用,但您可能需要再次移位工件,具体取决于块的当前方向(与I块的当前方向进行比较,以了解我的意思)。

我假设您现在已经完成了此操作。
我不是程序员,但我确实记得我在大学里做过这件事。我们只是有4个不同的对象(不同的旋转)为每件作品。例如“L”形有1、2、3、4块。如果您的活动件位于3中,且您顺时针旋转,则加载件4,再次顺时针旋转并加载件1

我自己也遇到过这个问题,我找到了关于这个主题的很棒的维基百科页面(在“常见轮换”一段:

然后我编写了以下代码,非常详细,以便清楚地了解正在发生的事情

我希望,更好地理解这是如何工作的,这会有所帮助

要快速测试,您可以将其复制/粘贴到此处:


此外,任何“正确”的旋转都很难在正确的网格边界上定位块。对于一组典型的俄罗斯方块,我只需要对每个块的4个旋转进行硬编码。或者,如果你必须按程序进行,你可以通过简单的交换和对x,y坐标的求反得到直角旋转——在纸上计算出来,你就可以你会发现这很简单。同时要注意工件在板边缘时发生的旋转。在某些情况下,你必须将工件移回表中。对于硬编码,以及算法,都是+1。
x_new = y_old
y_new = 1 - (x_old - (me - 2))
triangle = [[0,0],[5,0],[5,2]]
coordinates_a = triangle[0]
coordinates_b = triangle[1]
coordinates_c = triangle[2]

def rotate90ccw(coordinates):
    print "Start coordinates:"
    print coordinates
    old_x = coordinates[0]
    old_y = coordinates[1]
# Here we apply the matrix coming from Wikipedia
# for 90 ccw it looks like:
# 0,-1
# 1,0
# What does this mean?
#
# Basically this is how the calculation of the new_x and new_y is happening:
# new_x = (0)(old_x)+(-1)(old_y)
# new_y = (1)(old_x)+(0)(old_y)
#
# If you check the lonely numbers between parenthesis the Wikipedia matrix's numbers finally start making sense.
# All the rest is standard formula, the same behaviour will apply to other rotations
    new_x = -old_y
    new_y = old_x
    print "End coordinates:"
    print [new_x, new_y]

def rotate180ccw(coordinates):
    print "Start coordinates:"
    print coordinates
    old_x = coordinates[0]
    old_y = coordinates[1] 
    new_x = -old_x
    new_y = -old_y
    print "End coordinates:"
    print [new_x, new_y]

def rotate270ccw(coordinates):
    print "Start coordinates:"
    print coordinates
    old_x = coordinates[0]
    old_y = coordinates[1]  
    new_x = -old_x
    new_y = -old_y
    print "End coordinates:"
    print [new_x, new_y]

print "Let's rotate point A 90 degrees ccw:"
rotate90ccw(coordinates_a)
print "Let's rotate point B 90 degrees ccw:"
rotate90ccw(coordinates_b)
print "Let's rotate point C 90 degrees ccw:"
rotate90ccw(coordinates_c)
print "=== === === === === === === === === "
print "Let's rotate point A 180 degrees ccw:"
rotate180ccw(coordinates_a)
print "Let's rotate point B 180 degrees ccw:"
rotate180ccw(coordinates_b)
print "Let's rotate point C 180 degrees ccw:"
rotate180ccw(coordinates_c)
print "=== === === === === === === === === "
print "Let's rotate point A 270 degrees ccw:"
rotate270ccw(coordinates_a)
print "Let's rotate point B 270 degrees ccw:"
rotate270ccw(coordinates_b)
print "Let's rotate point C 270 degrees ccw:"
rotate270ccw(coordinates_c)
print "=== === === === === === === === === "