我需要一个函数,它允许我顺时针旋转网格数据结构,任意次数90度。目前,该函数似乎对ds_grid
没有任何影响。
下面是我目前使用的代码,调用它的函数是:ds_grid_rotate_alt(global.grid, irandom(3), 10);
。
/// @description rotate grid clockwise 90 degrees x times
var grid = argument0;
var turns = argument1;
var width = argument2;
var gx = 0;
var gy = 0;
if turns > 0
{
var grid_copy = ds_grid_create(width, width);
for (gy = 0; gx < width; gy++)
{
for (gx = 0; gx < width; gx++)
{
//grid copy
var data = ds_grid_get(grid,gx,gy);
ds_grid_set(grid_copy,width-gy,width-gx,data);
}
}
//copy results back to origional grid
ds_grid_copy(grid_copy,grid);
ds_grid_destroy(grid_copy);
turns -= 1;
ds_grid_rotate_alt(grid,turns,width);
}
发布于 2018-04-03 07:57:05
如注释所示,您必须更改ds_grid_copy()
函数的参数,因为它没有保存您的计算。
看一看您的代码,我想出了一个函数,它可以实现您想要的功能,并且可以线性工作,而不需要(不必要的)递归。
由于ds_grid
s基本上是矩阵,所以我们可以用数学来处理它们。您的函数使用width
作为矩阵大小,因此假设它是方阵是安全的。设A是一个4x4方阵,我们想顺时针旋转它90度,这样的旋转与第一次转置,然后水平翻转矩阵是一样的:
你可以用方形纸板试一试,结果是一样的。对此有一个正式的解释,但我们对实现感兴趣。
另外,每四次旋转,我们就开始配置( 360度旋转等于根本不旋转),所以我们可以考虑变量turns
和4的模数,而不是重复执行不必要的旋转,从而节省有用的CPU时间。
所以,现在我们只考虑三种不同的旋转:顺时针90度、180度和270度。我们可以做另一个考虑:为什么顺时针旋转三次,如果我们只能顺时针旋转一次呢?数学对我们有帮助,因为如果我们在换位前水平翻转,结果是我们逆时针旋转90度,因此顺时针旋转270度:
最后,180度旋转是相同的,无论是CW还是CCW。我们可以说我们两次旋转90度,实际上180度的旋转等于水平和垂直的翻转,而不考虑转换的顺序:
唯一涉及的操作是换位,水平和垂直翻转,我们只是结合他们,以得到我们想要的旋转。我们可以创建三个单独的函数,并根据需要执行它们,但我们仍然可以脱机完成一些工作,并创建一个同时执行两个转换的单个函数。
换位通过交换起始坐标将给定单元格中的值移动到目标单元格。
变位 AU,V→AV,u
翻转涉及从行或列的末尾倒转坐标(W是最大宽度,H是最大高度)。
水平翻转 AU,V→AW-(u+1),V垂直翻转 AU,V→AU,H-(v+1)
我们将换位和翻转结合起来,使旋转达到90度(注意,我去掉了括号,相应地改变了符号):
换位,然后是霍尔。翻转(90°CW) AU,V→AW-v-1,u Hor。翻转,然后换位(270°CW - 90°CCW) AU,V→AV,W-u-1
最后,180度旋转:
霍尔。翻转,然后是弗特。翻转或反之亦然(180°CW/CCW) AU,V→AW-u-1,H-v-1
现在,您可以使用这些伪代码赋值在一个步骤中创建旋转矩阵,而无需任何不必要的迭代或递归。
https://gamedev.stackexchange.com/questions/157086
复制相似问题