无法使用 OpenGL 在 C 中旋转移动对象



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

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) 点并以指定的角度旋转。为此,我试图构建一个函数,该函数将通过接受该函数来绘制要旋转和移动的对象来执行此操作。

如果我向它发送一个常量坐标,则旋转没有运动效果很好。

你的函数似乎要么做出你没有披露的假设,要么参数比他们需要的要少。 特别是,未指定要相对于对象坐标旋转的轴。

只有围绕穿过物体中心的轴的旋转才没有物体的净运动——围绕顶点质心的旋转保留质心;关于(虚拟)质量中心的旋转保留质心。 通过glRotatef()应用的 OpenGL 旋转始终与通过原点的轴有关,因此通常,您需要执行以下逻辑系列操作:

  1. 选择驻留在所需旋转轴(例如顶点质心)上的点P0

  2. 应用P0移动到原点的翻译。

  3. 应用所需的旋转。

  4. 应用将原点带回P0的翻译。

您可以将其与附加平移相结合,以影响对象移动。 也

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

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

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

因此,您想要的函数将具有以下形式:

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();
}

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

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

void rotateObjectWithMovement(void functionToDrawObject(), struct point pivot,
float rotationAngle, struct point translation) {
glPushMatrix();
glTranslatef(pivot.x + translation.x, pivot.y + translation.y, 0.0f);
glRotatef(rotationAngle, 0.0f, 0.0f, 1.0f);
glTranslatef(-pivot.x, -pivot.y, 0.0f);
functionToDrawObject();
glPopMatrix();
}
void rotateObjectWithoutMovement(void functionToDrawObject(), struct point pivot,
float rotationAngle) {
static const struct point zero = { 0, 0 };
rotateObjectWithMovement(functionToDrawObject, pivot, rotationAngle, zero);
}

最新更新