Java 连续旋转一个三角形

Java 连续旋转一个三角形,java,opengl,opengl-es-2.0,Java,Opengl,Opengl Es 2.0,我有一个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

我有一个
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。它应该引入数值问题,因为它也是一个计算链。这不是旋转角度的问题,因为简单的求和不会显示应用旋转时遇到的严重数值错误。然而,它也有一些问题,但它们只在角度达到数十亿时才会在很长的运行时间内出现。一般来说,这种求和没有那么糟糕的原因是,您在每一帧中以相同的方向更改变量,并且用户没有注意到稍微偏离旋转角度。

    我发现您的代码有两个问题。两个都是固定的,只需稍加修改

  • 尝试应用旋转操作,将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。它应该引入数值问题,因为它也是一个计算链。这不是旋转角度的问题,因为简单的求和不会显示应用旋转时遇到的严重数值错误。然而,它也有一些问题,但它们只在角度达到数十亿时才会在很长的运行时间内出现。一般来说,这种求和没有那么糟糕的原因是,在每一帧中,在相同的方向上更改变量,并且用户没有注意到稍微偏离旋转角度。

    我每100毫秒旋转一个恒定的0.2弧度。rotate方法只是没有正确地旋转它,我不知道为什么它会减小三角形的大小。@Clay,等等,你的代码还有一个问题,这可能是主要原因。让我来解决这个问题。@Clay好的,现在请再看看我的答案,第1点。这是非常重要的。我建议的更改应该解决这两个问题。请不要应用原始问题答案中建议的修复。那是因为这使我的答案无效(它与问题不再匹配)。我将恢复你对这个问题的编辑。当前代码中的问题是新值的公式中有
    p1、p2、p2
    (而不是
    p1、p2、p3