我有一个 float[] newCoords
变量,其大小为 9。前 3 个条目代表一个顶点,接下来的 3 个条目代表第二个顶点,最后 3 个条目代表最后一个顶点。
我有一些代码,当我向它提供坐标时,应该在空间中的任何位置旋转三角形。它看起来像这样:
float s = (float) Math.sin(0.5);
float c = (float) Math.cos(0.5);
float[] centroid = getCentroid(newCoords);
newCoords[0] -= centroid[0];
newCoords[1] -= centroid[1];
newCoords[3] -= centroid[0];
newCoords[4] -= centroid[1];
newCoords[6] -= centroid[0];
newCoords[7] -= centroid[1];
newCoords[0] = (newCoords[0] * c) - (newCoords[1] * s);
newCoords[1] = (newCoords[0] * s) + (newCoords[1] * c);
newCoords[3] = (newCoords[3] * c) - (newCoords[4] * s);
newCoords[4] = (newCoords[3] * s) + (newCoords[4] * c);
newCoords[6] = (newCoords[6] * c) - (newCoords[7] * s);
newCoords[7] = (newCoords[6] * s) + (newCoords[7] * c);
newCoords[0] += centroid[0];
newCoords[1] += centroid[1];
newCoords[3] += centroid[0];
newCoords[4] += centroid[1];
newCoords[6] += centroid[0];
newCoords[7] += centroid[1];
问题是,它没有正确旋转它,三角形旋转并且变得越来越小,直到它们由于某种原因消失,有人能明白为什么会发生这种情况吗?
编辑:哎呀,差点忘了,这是我的 getCentroid()
方法。
private float[] getCentroid(float[] p1) {
float[] newCoords = new float[] {(p1[0] + p1[3] + p1[6]) / 3.0f,
(p1[1] + p1[4] + p1[7]) / 3.0f, 0};
return newCoords;
}
最佳答案
我发现您的代码有两个问题。两者都经过一点点改变就得到了修复。
您尝试应用旋转操作,将 X 和 Y 坐标作为输入,并将新的 X 和 Y 作为输出。对于旋转的每个顶点,您有两行代码:第一行计算 X 坐标,第二行计算 Y 坐标。但是在计算 Y 坐标时,您使用已经旋转的 X 坐标!这是错误的。
还有一个数值问题。您一次又一次地重复使用旧值,从而产生一个值所产生的旋转计算链,因此数值误差会累加起来。切勿依赖此类计算来按预期工作。相反,您应该使用原始值并增加每帧中的角度。这可确保每个值仅参与单次旋转计算。
要解决这两个问题,请将原始坐标保留在代码中的某个位置,我将其称为coords
,并重写代码,以便将该数组作为输入(保留newCoords
) > 作为输出)。增加每一帧的旋转角度,实现旋转动画。
这解决了这两个问题,因为您摆脱了该链,并且旋转函数中的输入和输出有不同的数组。
伪代码:
// initial:
angle = 0.0;
coords = (initial coordinates)
// per frame:
angle += 0.5;
newCoords = rotate(coords, angle);
draw(newCoords);
另外,请注意,如果您想逐帧旋转该角度,则 0.5
是一个大角度。数学函数期望角度以弧度(而不是度数)为单位,因此您可能需要使用较低的值,具体取决于您想要具体可视化的内容。
你可能想知道为什么我在每一帧中重复使用旧角度,根据上面提到的问题2,它应该引入数值问题,因为它也是一个计算链。这不是旋转角度的问题,因为简单的求和不会显示您在应用旋转时遇到的严重数值错误。然而它也存在一些问题,但它们只有在运行时间很长、角度达到数十亿时才会出现。一般来说,这样的求和并没有那么糟糕的原因是因为您在每个帧中以相同的方向更改变量,并且用户不会注意到稍微偏离的旋转角度。
关于java - 连续旋转三角形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24244405/