我发现,要旋转网格中存在的任意大小的一块,只需要两个图形操作。
如果你想顺时针旋转棋子,首先反转组成棋子的每个块的坐标。这意味着交换每个块的 x 和 y 坐标。
在代码中,它可能看起来像这样
for (int i = 0; i < sizeOfPiece; i++)
{
int temp = piece[i].X;
piece[i].X = piece[i].Y;
piece[i].Y = temp;
}
然后,将新操作的部件镜像到 Y 轴上。这可以通过获取每个块的 x 坐标并将其设置为等于整个块的宽度 - x 坐标来完成。
代码可能如下所示:
for (int i = 0; i < sizeOfPiece; i++)
{
piece[i].X = pieceWidth - piece[i].X;
}
在哪里int pieceWidth = piece[RightEdge].X - piece[leftEdge].X;
如果您无法找到作品的左右边缘,这应该可以正常工作
int edges[4] = {0, 0, 0, 0};
for (int i = 1; i < sizeOfPiece; i++)
{
if (piece[i].X < piece[edges[LEFT]].X) edges[LEFT] = i; //Check for a block on the left edge
if (piece[i].X > piece[edges[RIGHT]].X) edges[RIGHT] = i; //Check for a block on the right edge
if (piece[i].Y < piece[edges[UP]].Y) edges[UP] = i; //Check for a block on the upper edge
if (piece[i].Y > piece[edges[DOWN]].Y) edges[DOWN] = i; //Check for a block on the bottom edge
}
其中 LEFT = 0,RIGHT = 1,UP = 2,DOWN = 3
在这种情况下,edges 数组存储单个块的 ID,该块位于块的 4 个边缘中的每一个上。只需要右边缘和左边缘来计算宽度,但在其他点上知道其他边缘可能很有用。
在这种情况下,前面提到的pieceWidth 公式实际上应该是这样的:
int pieceWidth = piece[edges[RIGHT]].X - piece[edges[LEFT]].X;
如果您想逆时针旋转,只需执行相反的操作即可。这意味着您首先在 y 轴上镜像该部分,然后反转它的坐标。
我已经为这些付诸实施的图形翻译绘制了一些视觉表示:
Picture
在上图中,红色部分表示原始部分,蓝色过渡部分表示反转后的部分,绿色部分表示在 y 轴上镜像后的前一部分。
上面的例子是顺时针旋转,而下面的例子是逆时针旋转。