所以,你必须是存储像要绕Z轴旋转的3D位图“单色对象”。你必须先了解一个转数后,你将最终造成事实上的光学像差,您使用的array index
这是一个自然数表示对象的零部件的坐标。
在旋转时的任何整数值将最有可能成为一个无理数。传统上(不是谈论特殊程序和框架)的人存储无理数的近似值double
或float
或decimal
变量(它只能存储有理数集的一小部分)是没有什么相比于近似的通过将其存储在一个整数(一个array index
)中来表示无理数。此外,即使质量损失如果对于您的应用没有太大的重要性,您也一定要明白从数学角度而言,经过多次旋转后,您的3d形状将被滚筒修剪刻在原来的平行六面体中,沿着Z轴。
它是这样的。你说你已经做了一个名为Point3
类:
public class Point3 {
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
}
也许你应该遵循@Jeroen面包车兰根的意见,并使用标准的类,如果这样的类已经存在。好处是,如果有人已经建立或将要建立一个使用该类的图书馆,你可以立即开始使用图书馆。 但现在并不那么重要。
@Alpert已经给出了一个很棒的C#代码来围绕oZ轴旋转一个点。这是代码的N“扩展方法”改编:
public static class RotationHelpers {
public static Point3 RotatePoint(this Point3 point, int angle) {
var result = new Point3() {
X = point.X * Math.Cos(angle) - point.Y * Math.Sin(angle),
Y = point.X * Math.Sin(angle) + point.Y * Math.Cos(angle),
Z = point.Z,
};
return result;
}
...
}
你可以更进一步,使这些转动点绕OZ轴序列扩展方法:
public static class RotationHelpers {
...
public static IEnumerable<Point3> RotatePoints(this IEnumerable<Point3> points, int angle) {
foreach (var point in points)
yield return point.RotatePoint(angle);
}
...
}
现在你说你有1和0三维矩阵的本原它:
int[,,] matrix;
你需要以某种方式转换的本质定义的点,并且矩阵为Point3
实例的序列,旋转次然后将结果序列转换回int[,,]
矩阵。
这可以像这样来实现(记住质量的损失我早先提到):
public static class RotationHelpers {
...
public static IEnumerable<Point3> ToPoints(this int[,,] matrix) {
int lx = matrix.GetLength(0);
int ly = matrix.GetLength(1);
int lz = matrix.GetLength(2);
for (int x = 0; x < lx; x++)
for (int y = 0; y < ly; y++)
for (int z = 0; z < lz; z++) {
bool is1 = matrix[x, y, z] != 0;
if (is1)
yield return new Point3 {
X = x - lx/2,
Y = y - ly/2,
Z = z - lz/2
};
}
}
...
}
这将需要所有的细胞在宽x高x深矩阵和每个不等于0的单元格将产生具有该特定位置的坐标的新实例Point3
。
该序列可以然后通过使用先前描述RotatePoints
方法,然后可用于“渲染”背所得Point3
实例的序列为阵列的以下方法的角度旋转:
public static class RotationHelpers {
...
public static void AssignPoints(this int[,,] matrix, IEnumerable<Point3> points) {
int lx = matrix.GetLength(0);
int ly = matrix.GetLength(1);
int lz = matrix.GetLength(2);
for (int x = 0; x < lx; x++)
for (int y = 0; y < ly; y++)
for (int z = 0; z < lz; z++)
matrix[x, y, z] = 0;
foreach (var point in points) {
// this is when quality is lost, because things like 1.7 and 1.71
// will both become =2
var x = (int)Math.Round(point.X) + lx/2;
var y = (int)Math.Round(point.Y) + ly/2;
var z = (int)Math.Round(point.Z) + lz/2;
// this is where you loose parts of the object because
// it doesn't fit anymore inside the parallelepiped
if ((x >= 0) && (y >= 0) && (z >= 0) &&
(x < lx) && (y < ly) && (z < lz))
matrix[x, y, z] = 1;
}
}
...
}
要把它包起来,你可以像这样使用所有这些方法:
int[,,] matrix = ...
int angle = ...
IEnumerable<Point3> points = matrix.ToPoints();
IEnumerable<Point3> rotatedPoints = points.RotatePoints(angle);
matrix.AssignPoints(rotatedPoints);
// now you have the original matrix, rotated by angle
你是什么意思“没有固定大小的多维数组”。你正在使用“那个”,就好像你指的是前面描述的那样。请说明“3D阵列”的含义。您不需要等级为3的原始数组来存储设计时未知数量的顶点。你的意思是一个以空间起源为中心的想象约束框? “二元对象”是什么意思? –
@EduardDumitru多维数组可以具有任意大小,例如[10,20,40]或[40,35,70],没有固定大小。它指的是3d数组中的对象。是的,我想象的是空间中心的物体。二进制对象意味着一个只有0或1的数组,因为一个数组只是一个立方体,但在它内部我可以绘制任何东西。 – Butzke
所以三维原始数组包含0和1,1意味着那里有东西,0意味着那里什么也没有。我是否正确?如果我得到了正确的答案,你是否意识到没有人能从你的问题中理解这一点?此外,如果我说得对,那有点“密集”。您以非矢量方式存储3d形状,这自然会导致很多问题。你可以旋转这样一个对象,但是你会失去解析力(很多)。你为什么创建'Point3'类(这是更好的)。你的3d矩阵和'Point3'之间有什么关系? –