无法使用opengl在c中旋转移动对象

时间:2017-04-25 19:09:18

标签: c opengl glut

我试图在移动物体的同时旋转它,但是我无法使它移动并沿着我希望它移动的点旋转。

struct point {
    int x;
    int y;
};

// A line between two points.

struct line {
    struct point start;
    struct point end;
};

float j = 100.0;
float rotationAngle = 0.0f; // The angle of rotation for our object  

void rotateObjectWithMovement(void functionToDrawObject(), struct point pivot, float rotationAngle) {
    glPushMatrix();
    glTranslatef(pivot.x, pivot.y, 0.0f);
    glRotatef(rotationAngle, 0.0f, 0.0f, 1.0f);
    functionToDrawObject();
    glPopMatrix();
}

void rotateObjectWithoutMovement(void functionToDrawObject(), struct point pivot, float rotationAngle) {
    glPushMatrix();
    glTranslatef(pivot.x, pivot.y, 0.0f);
    glRotatef(rotationAngle, 0.0f, 0.0f, 1.0f);
    glTranslatef(-pivot.x, -pivot.y, 0.0f);
    functionToDrawObject();
    glPopMatrix();
}

void rocket() {

    struct point allPoints[2] = {
        { 100, 100},
        { 150, 150}
    };      
    struct line line1 = {allPoints[0], allPoints[1]};
    glColor3f(1.0, 1.0, 0.0);
    drawLines(&line1, 1);
}

void display() {
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    struct point pivot={j,100};
    rotateObjectWithoutMovement(rocket,pivot,rotationAngle);
    //rotateObjectWithMovement(rocket,pivot,rotationAngle);

    //reference line
    glBegin(GL_LINES);
    glVertex2f(0, 100);
    glVertex2d(1000, 100);
    glEnd();

    j += 1;  

    rotationAngle += 0.5f; // Increment our rotation value  
    if (rotationAngle > 360.0f) // If we have rotated beyond 360 degrees (a full rotation)  
        rotationAngle -= 360.0f; // Subtract 360 degrees off of our rotation
    glutSwapBuffers(); // Swap our buffers
}

void myinit() {
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, 988.0, 0.0, 999.0);
    glClearColor(0.5f, 0.5f, 1, 1);
    glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char *argv[]) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE);
    glutInitWindowSize(700, 500);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("OpenGL Hierarchical Modeling 2D Example");

    myinit();

    glutDisplayFunc(display);
    glutIdleFunc(display);

    glutMainLoop();
    return 0;
}

rotateWithMoment()函数获取一个对象,静态坐标和对象必须旋转到的角度,并以statis坐标作为枢轴旋转它。

rotateWithoutMovement()函数取一个物体,改变物体必须旋转的坐标和角度,并随着变化的坐标旋转它作为枢轴(例如:旋转一条线看起来像轮子旋转)发送变化的坐标到这个功能制作线路旋转。

我一直试图让它工作2天,不知道我哪里出错了。

我试图让我发送的物体移动到(x,y)点并以指定的角度旋转。为此,我试图通过接受绘制要旋转和移动的对象的功能来构建将执行此操作的功能。

rotateWithoutMovement工作得很好,如果我发送一个恒定的坐标。

1 个答案:

答案 0 :(得分:2)

您的功能似乎要么假设您没有透露,要么参数少于他们需要的参数。特别是,未指定要相对于对象坐标旋转的轴。

只有围绕物体中心的轴旋转才能没有物体的净移动 - 围绕顶点质心的旋转保留了质心;那些关于(虚拟)质量中心的东西保留了质心。通过glRotatef()应用的OpenGL旋转始终是关于通过原点的轴,因此通常需要执行此逻辑系列操作:

  1. 选择位于所需旋转轴上的点P0(例如顶点质心)。

  2. 应用将P0移至原点的翻译。

  3. 应用所需的旋转。

  4. 应用将原点恢复为P0

  5. 的翻译

    您可以将其与其他平移组合以实现对象移动。任

    • 在(1)之前执行翻译,在(1)/(2)或
    • 期间进行考虑
    • 在(4)之后或与之结合执行。

    如果我们假设您的functionToDrawObject()根据坐标定义了一个可绘制对象,使得所需的旋转轴已经通过原点 - 看起来您确实在假设 - 那么(1)和(2 )不需要,因为所需的翻译是零。否则,您需要在对象的坐标系中提供所需的枢轴点,与世界坐标系中对象的所需位置分开。让我们做出这个假设。

    在我们编写函数之前,我们需要知道另外一件事:OpenGL将当前矩阵定义为左侧坐标倍增的矩阵:Matrix * X = X',当您应用新的转换(旋转,平移或缩放)时,其矩阵与右侧的当前矩阵组合在一起Current * M = {{1 }}。实际上,这意味着您要应用矩阵的程序顺序与您希望它们应用于图形坐标的逻辑顺序相反,或者等效地,程序的结构反映了矩阵方程的结构它编码。

    因此,您想要的功能将具有以下形式:

    New

    另请注意,在旋转之前不应用任何平移会影响绘制对象的最终方向 - 此类平移仅影响对象在场景中的位置(当然,对于应用的平移也是如此) em>在旋转之后)。

    然而,我怀疑我们之前的假设并不是你想要做的。在这种情况下,你真正想要的可能更像是这样:

    void rotateObjectWithoutMovement(void functionToDrawObject(), struct point pivot,
            float rotationAngle) {
        glPushMatrix();
        // No translation needed, because we're rotating around the object's
        // natural origin (thus pivot is unused) ...
        glRotatef(rotationAngle, 0.0f, 0.0f, 1.0f);
        functionToDrawObject();
        glPopMatrix();
    }
    
    void rotateObjectWithMovement(void functionToDrawObject(), struct point pivot,
            float rotationAngle) {
        glPushMatrix();
    
        // Translate to the desired position after rotating to orient the object
        // as desired.  No additional translation is needed because we did not
        // apply any before the rotation.
        glTranslatef(pivot.x, pivot.y, 0.0f);
        glRotatef(rotationAngle, 0.0f, 0.0f, 1.0f);
        // No _initial_ translation needed, because we're rotating around the object's
        // natural origin ...
        functionToDrawObject();
        glPopMatrix();
    }