c# - 旋转 3d 阵列
问题描述
我有一个由 a 表示的 3D 数组int[,,]
。我希望能够在任何 3 个轴上将其旋转 90(或-90)度增量。
例子
对于以下二维数组:
1 2 3
4 5 6
我希望这个结果:
4 1
5 2
6 3
我想要同样的逻辑,但适用于 3D 数组。
解决方案
这是你如何做到的。
您不需要乘以矩阵,因为您只是在移动值而不更改它们。您所要做的就是将每个输入单元映射到其输出单元。
从 2D 开始
想象一下,您有一个 3x4x1 的 3D 数组。这可以用一个 3x4 的二维数组来表示。
这是旋转时每个单元格的关联方式:
// Rotating 90 degrees clockwise
output[i, j] = input[j, maxHeight - i];
// Rotating 90 degrees counter clockwise
output[i, j] = input[maxWidth - j, i];
(您可以在本文末尾找到在上下文中使用这些行的完整代码。)
添加第三维
现在不是 3x4x1,而是想象我们有一个 3x4x2。这相当于旋转两个二维数组。这是旋转代码的样子。
// Rotating 90 degrees clockwise (around z axis)
output[i, j, k] = input[j, maxHeight - i, k];
// Rotating 90 degrees counter clockwise (around z axis)
output[i, j, k] = input[maxWidth - j, i, k];
从那里,您可以重复相同的模式以围绕另一个轴旋转。
// Rotating around the x axis (i doesn't change)
output[i, j, k] = input[i, maxHeight - k, j ];
output[i, j, k] = input[i, k , maxDepth - j];
// Rotating around the y axis (j doesn't change)
output[i, j, k] = input[maxWidth - k, j, i ];
output[i, j, k] = input[k , j, maxDepth - i];
完整代码
以下代码执行以下操作:
- 它创建一个 4x3 2D 数组并打印它。
- 它通过将原始数组顺时针旋转 90 度来创建一个新数组并打印它。
- 它通过将原始数组逆时针旋转 90 度来创建一个新数组并打印它。
该代码还包含一个名为的方法,该方法Rotate90DegreesClockwiseAroundZAxis
说明了如何围绕 Z 轴旋转 3D 数组。您可以使用此代码生成围绕另一个轴旋转的方法。
static void Main(string[] args)
{
int[,] grid = new int[4, 3];
int counter = 0;
for (int j = 0; j < grid.GetLength(1); j++)
{
for (int i = 0; i < grid.GetLength(0); i++)
{
grid[i, j] = counter++;
}
}
Debug.WriteLine("Default:");
PrintGrid(grid);
var rotated90Grid = Rotate90DegreesClockwise(grid);
Debug.WriteLine("Rotated 90:");
PrintGrid(rotated90Grid);
var rotated270Grid = Rotate90DegreesCounterClockwise(grid);
Debug.WriteLine("Rotated 270:");
PrintGrid(rotated270Grid);
}
static int[,] Rotate90DegreesClockwise(int[,] input)
{
var inputWidth = input.GetLength(0);
var inputHeight = input.GetLength(1);
// We swap the sizes because rotating a 3x4 yields a 4x3.
var output = new int[inputHeight, inputWidth];
var maxHeight = inputHeight - 1;
for (int j = 0; j < output.GetLength(1); j++)
{
for (int i = 0; i < output.GetLength(0); i++)
{
output[i, j] = input[j, maxHeight - i];
}
}
return output;
}
static int[,] Rotate90DegreesCounterClockwise(int[,] input)
{
var inputWidth = input.GetLength(0);
var inputHeight = input.GetLength(1);
// We swap the sizes because rotating a 3x4 yields a 4x3.
var output = new int[inputHeight, inputWidth];
var maxWidth = inputWidth - 1;
for (int j = 0; j < output.GetLength(1); j++)
{
for (int i = 0; i < output.GetLength(0); i++)
{
output[i, j] = input[maxWidth - j, i];
}
}
return output;
}
static int[,,] Rotate90DegreesClockwiseAroundZAxis(int[,,] input)
{
var inputWidth = input.GetLength(0);
var inputHeight = input.GetLength(1);
var inputDepth = input.GetLength(1);
// We swap the sizes because rotating a 3x4x5 yields a 4x3x5.
var output = new int[inputHeight, inputWidth, inputDepth];
var maxHeight = inputHeight - 1;
for (int k = 0; k < inputDepth; k++)
{
for (int j = 0; j < output.GetLength(1); j++)
{
for (int i = 0; i < output.GetLength(0); i++)
{
output[i, j, k] = input[j, maxHeight - i, k];
}
}
}
return output;
}
static void PrintGrid(int[,] grid)
{
for (int j = 0; j < grid.GetLength(1); j++)
{
for (int i = 0; i < grid.GetLength(0); i++)
{
Debug.Write($"{grid[i, j]:D2} ");
}
Debug.WriteLine("");
}
Debug.WriteLine("---------------");
}
输出
Default:
00 01 02 03
04 05 06 07
08 09 10 11
---------------
Rotated 90:
08 04 00
09 05 01
10 06 02
11 07 03
---------------
Rotated 270:
03 07 11
02 06 10
01 05 09
00 04 08
---------------
推荐阅读
- javascript - SystemJS,将 importmap 与模块一起使用,需要做出反应
- vue.js - 如何处理在组件内部使用 uuid 的测试
- javascript - python 有与 javascript 等效的函数注释吗?
- c# - sqlite 无法在树莓派上使用 Windows IOT 在 UPW 中打开数据库文件
- javascript - 带有 laravel 的甜蜜警报
- java - JDK-13 Surefire 插件不支持的类文件主要版本
- python - 如何在pycharm python上从3到6按钮相乘和求和
- html - 我想在链接按钮上停止页面重新加载点击下载
- python - 当我的主数据库是 Mongo 时,Django 访问 Admin 问题
- javascript - 如何使用选项 jQuery 隐藏 select2