点以奇怪的方式旋转,我的计算出了什么问题?

3
这是我想要的结果: 旋转的正方形 但是我得到了这个:

错误旋转的三角形

当我使用这个公式时: 公式 更确切地说,是这段 GLSL 顶点着色器代码:
#version 330
layout (location = 0) in vec2 pos;
layout (location = 1) in vec3 clr;
uniform float sinr, cosr;
float x, y;
out vec3 color;
void main() {
    color = clr;
    x = pos.x * cosr - pos.y * sinr;
    y = pos.x * sinr + pos.y * cosr;
    gl_Position = vec4(x, y, 0.0, 1.0); }

我已经没有更多的想法了。我已经算出旋转的代码,但显然它并不能正确旋转。有人能告诉我为什么以及如何解决吗?

编辑:设置/更新程序:

void tgle_rot(int i, float rad) {
    float *sin = &global.objs[i].sinr, *cos = &global.objs[i].cosr;
    *sin = *sin * cosf(rad) + *cos * sinf(rad);
    *cos = *cos * cosf(rad) - *sin * sinf(rad); }

void callback(void) {
    tgle_rot(0, 0.01); }

static void run_draw(void) {
    /* ... */
    for(int i = 0; i < global.num_objs; ++i) {
        /* ... */
        glUniform1f(global.shader.sinr, global.objs[i].sinr);
        glUniform1f(global.shader.cosr, global.objs[i].cosr);
        /* ... */ }
    /* ... */
    glfwSwapBuffers(global.window); }

编辑2:问题不在于 tgle_rot!我已将其更改为
void tgle_rot(int i, float rad) {
    float *sin = &global.objs[i].sinr, *cos = &global.objs[i].cosr;
    static float rotation = 0;
    rotation += 0.01;
    *sin = sinf(rotation);
    *cos = cosf(rotation); }

程序行为没有改变!

编辑3:以下是单行旋转:

line rot

解决方案:问题在于变换的顺序。我先进行缩放,再进行旋转。交换缩放和旋转的顺序解决了问题。我之前没有添加缩放部分,因为我认为它不重要。结果证明我错了。现在我正在弄清楚原因。感谢您的时间,我将根据您的建议修改我的 tgle_rot 函数。

事实上,问题出在着色器上。

void main() {
        color = clr;
        x = x * cosr - y * sinr;
        y = x * sinr + y * cosr; // using modified x!!!
        gl_Position = vec4(x, y, 0.0, 1.0);

你想要实现什么目标不是很清楚。你是想旋转对象还是视图?你在哪里设置和更新 sinrcosr - M Oehm
我想要实现第一张图片中完全相同的旋转 - 我想要旋转物体的每个点。我正在更新代码以包括设置/更新例程。 - user2933244
请明确:第一个动画有什么奇怪的地方? - chux - Reinstate Monica
1
tgle_rot真的正确吗?在计算cos时,您应该使用 sin的新值吗?也许您应该使用临时变量。 - Les
1
你应该使用临时变量。你计算了新的“sin”,但下一行计算“cos”时,使用的是新的“*sin”值。 - Weather Vane
显示剩余6条评论
2个回答

2
这只是一种猜测,因为我无法尝试,但是需要更改...
void tgle_rot(int i, float rad) {
    float *sin = &global.objs[i].sinr, *cos = &global.objs[i].cosr;
    *sin = *sin * cosf(rad) + *cos * sinf(rad);
    *cos = *cos * cosf(rad) - *sin * sinf(rad); }

to ...

void tgle_rot(int i, float rad) {
    float *sin = &global.objs[i].sinr, *cos = &global.objs[i].cosr;
    float tmpSin = *sin, tmpCos = *cos;
    *sin = tmpSin * cosf(rad) + tmpCos * sinf(rad);
    *cos = tmpCos * cosf(rad) - tmpSin * sinf(rad); }

您正在使用修改后的Sin函数进行Cos计算,因此使用临时变量可以避免这种情况。

1
在这个函数中。
void tgle_rot(int i, float rad) {
    float *sin = &global.objs[i].sinr, *cos = &global.objs[i].cosr;
    *sin = *sin * cosf(rad) + *cos * sinf(rad);
    *cos = *cos * cosf(rad) - *sin * sinf(rad);
}

你需要计算*sin*cos的新值。然而,*cos的计算使用了*sin的新值而不是原始值。我会使用临时变量来解决这个问题:
void tgle_rot(int i, float rad) {
    float *sin = &global.objs[i].sinr, *cos = &global.objs[i].cosr;
    float sindash, cosdash;
    sindash = *sin * cosf(rad) + *cos * sinf(rad);
    cosdash = *cos * cosf(rad) - *sin * sinf(rad);
    *sin = sindash;
    *cos = cosdash;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接