很难解释我的程序有什么问题,所以我做了一个视频来直观地向你展示https://youtu.be/j8yrB2BQUrI。
如视频所示,涉及y轴和z轴旋转的旋转无法正常工作。我添加了下面的代码,我知道我添加了很多,所以很抱歉。
rotateX/Y/Z函数只是更新每个立方体的旋转结构,所以我没有添加代码。对不起,写得很差的问题,我只是尝试了一切我能想到的,不能让它工作
`
private async void L(int n) //This is a working function
{
for (int i = 0; i < 15 * n; i++)
{
cube[0].rotateX(6 *DEGREE);
cube[1].rotateX(6 * DEGREE); //rotates the left face of the cube 90 degrees
cube[2].rotateX(6 * DEGREE);
cube[9].rotateX(6 * DEGREE);
cube[10].rotateX(6 * DEGREE);
cube[11].rotateX(6 * DEGREE);
cube[17].rotateX(6 * DEGREE);
cube[18].rotateX(6 * DEGREE);
cube[19].rotateX(6 * DEGREE);
Invalidate(rec);
await Task.Delay(1);
}
cube[0].rotateX(-90 * DEGREE); // here it quickly rotates the cube back to how it was originally
cube[1].rotateX(-90 * DEGREE);
cube[2].rotateX(-90 * DEGREE);
cube[9].rotateX(-90 * DEGREE);
cube[10].rotateX(-90 * DEGREE);
cube[11].rotateX(-90 * DEGREE);
cube[17].rotateX(-90 * DEGREE);
cube[18].rotateX(-90 * DEGREE);
cube[19].rotateX(-90 * DEGREE);
CubeFaces = Rotations.L(1, CubeFaces); // this changes the colours of the left face and then updates the display
Invalidate(rec); // to make it seem as if the cube has rotated
}
private async void R(int n) // this is also a working function
{
for (int i = 0; i < 15 * n; i++)
{
cube[6].rotateX(-6 * DEGREE);
cube[7].rotateX(-6 * DEGREE);
cube[8].rotateX(-6 * DEGREE);
cube[14].rotateX(-6 * DEGREE);
cube[15].rotateX(-6 * DEGREE);
cube[16].rotateX(-6 * DEGREE);
cube[23].rotateX(-6 * DEGREE);
cube[24].rotateX(-6 * DEGREE);
cube[25].rotateX(-6 * DEGREE);
await Task.Delay(1);
Invalidate(rec);
}
cube[6].rotateX(90 * DEGREE);
cube[7].rotateX(90 * DEGREE);
cube[8].rotateX(90 * DEGREE);
cube[14].rotateX(90 * DEGREE);
cube[15].rotateX(90 * DEGREE);
cube[16].rotateX(90 * DEGREE);
cube[23].rotateX(90 * DEGREE);
cube[24].rotateX(90 * DEGREE);
cube[25].rotateX(90 * DEGREE);
CubeFaces = Rotations.R(1, CubeFaces);
Invalidate(rec);
}
private async void U(int n) // this function does not work. you will see why when i run it
{
for (int i = 0; i < 15 * n; i++)
{
cube[0].rotateY(6 * DEGREE);
cube[3].rotateY(6 * DEGREE);
cube[6].rotateY(6 * DEGREE);
cube[9].rotateY(6 * DEGREE);
cube[12].rotateY(6 * DEGREE);
cube[14].rotateY(6 * DEGREE);
cube[17].rotateY(6 * DEGREE);
cube[20].rotateY(6 * DEGREE);
cube[23].rotateY(6 * DEGREE);
//cube[0].rotateX(cube[0].GetRotation().z);
//cube[3].rotateX(-rotation.x);
//cube[6].rotateX(-rotation.x);
//cube[9].rotateX(-rotation.x);
//cube[12].rotateX(-rotation.x);
//cube[14].rotateX(-rotation.x);
//cube[17].rotateX(-rotation.x);
//cube[20].rotateX(-rotation.x);
//cube[23].rotateX(-rotation.x);
await Task.Delay(1);
Invalidate();
}
}
private async void F(int n) // this also doesnt work and you will see why when i run it
{
for (int i = 0; i < 15 * n; i++)
{
cube[0].rotateZ(6 * DEGREE); // so the x axis rotations work however the y and z do not
cube[1].rotateZ(6 * DEGREE);
cube[2].rotateZ(6 * DEGREE);
cube[3].rotateZ(6 * DEGREE);
cube[4].rotateZ(6 * DEGREE);
cube[5].rotateZ(6 * DEGREE);
cube[6].rotateZ(6 * DEGREE);
cube[7].rotateZ(6 * DEGREE);
cube[8].rotateZ(6 * DEGREE);
await Task.Delay(1);
Invalidate();
}
//cube[0].rotateZ(-90 * DEGREE);
//cube[1].rotateZ(-90 * DEGREE);
//cube[2].rotateZ(-90 * DEGREE);
//cube[3].rotateZ(-90 * DEGREE);
//cube[4].rotateZ(-90 * DEGREE);
//cube[5].rotateZ(-90 * DEGREE);
//cube[6].rotateZ(-90 * DEGREE);
//cube[7].rotateZ(-90 * DEGREE);
//cube[8].rotateZ(-90 * DEGREE);
//CubeFaces = Rotations.F(1, CubeFaces);
}
`
我试着做U函数中注解掉的东西,我想它可以抵消立方体以其奇怪的方式旋转,但它只会让它变得更糟
2条答案
按热度按时间0kjbasz61#
你需要使用四元数旋转,否则你会得到“吉姆巴尔效果”。四元数可以从轴/Angular 计算,并且是累积的。你只需要做两件事
然后旋转:
这取决于你想在局部空间还是全局空间中旋转。
你可以在Git上找到例子。
dy2hfwbg2#
好的,让我们在这里写下一些定义。
1.你有9个独立的旋转平面。
1.即x为3,y为3,z为3。
1.这些旋转平面中的每一个都有自己独特的枢轴点 (然而,沿着每个轴的中间平面沿着已经以原点为中心,因此这些情况更容易,因为枢轴已经在原点)
1.对于这些旋转中的任何一个,您都希望围绕给定的轴应用动画旋转。
1.您有6个中心面 (1种颜色)
1.您有8个角件 (3种颜色)
1.您有12个边片 (2种颜色)
1.有一个没有颜色的中心部分,你可能可以忽略它,但是为了让代码更容易理解,我将假装它存在。
你如何跟踪和识别26/27件中的哪一件真的取决于你,所以我假设你已经工作了。
每个片段都有一个当前位置和当前方向。有一种很好的方法可以在一个完整的实体中表示所有这些信息,那就是4x 4矩阵 (存储单独的平移和欧拉旋转可能是你的错误!)。应该提到的是,你可以用位置+四元数来表示那些,但这里并不需要。
最初,对于这27个片段,它们都具有相同的方向,但具有不同的平移值。首先,初始化这些转换。
您还拥有9个旋转平面和关联的轴点。
在数学上正确的意义上,为了转换这些块,你应该做:
在代码中,这看起来像:
然而,在这种情况下,由于您只使用轴对齐旋转,因此实际上可以完全跳过枢轴点,直接跳到旋转。
这假定动画完成后,您将更新整个矩阵集。
或者,您可以 * 指定上述1度的旋转,并仅返回最终矩阵 (如果您只是想在动画时累积变换,避免临时数组)。然而,这样做可能会随着时间的推移积累浮点误差。
重要的是要意识到,你必须为你的块存储累积的转换。在上面的代码中,您看到的问题是您有XYZ Euler旋转顺序 (并且您只是更新Euler值)。所以这将适用于X和Z旋转,但是一旦你接触中间旋转,Z轴不再在它的原始平面,东西开始出错!