我想制作当我点击屏幕上的任何位置时对象移动时绘制轨迹的代码。
我将初始中心点设置为起点。我想将单击鼠标按钮的另一个点(目标点)设置为变量,但我不知道该怎么做。
float v1[3] = { -35.0f, 22.5f, 0.0f };
float v2[3] = { -35.0f, -22.5f, 0.0f };
float v3[3] = { 0.0f, 42.5f, 0.0f };
float v4[3] = { 0.0f, -42.5f, 0.0f };
float v5[3] = { 35.0f, 22.5f, 0.0f };
float v6[3] = { 35.0f, -22.5f, 0.0f };
这是对象的初始位置。 (带有 2 个三角形的 6 点星)
float px, py;
float center_s[3] = { 0.0f, 0.0f, 0.0f };
float center_d[3] = { px, py, 0.0f };
center_s
为起点,center_d
为终点,变量为px
, py
。
void lines(void) {
glColor3f(1.0, 0.0, 0.0);
glPointSize(5);
glBegin(GL_POINTS);
glVertex3fv(center_s);
glLineWidth(1);
glBegin(GL_LINES);
glVertex3fv(center_s);
glVertex3fv(center_d);
}
此函数用红线绘制从center_s
到center_d
的轨迹。它还绘制了一个中心点。
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN) {
x = mx;
y = glutGet(GLUT_WINDOW_HEIGHT) - my;
px = x + 35.0;
py = y + 42.5;
glutIdleFunc(lines);
}
glutPostRedisplay();
break;
问题来了。当按下鼠标左键时,星星必须移动到单击的位置并计算该位置的中心点并绘制线。但是,如果我运行这些代码,则不会绘制运动轨迹。
请告诉我问题是什么。另外,星星必须以恒定的速度移动到单击的位置。 (不是传送)
完整代码如下:
#include <stdlib.h>
#include <GL/glut.h>
float v1[3] = { -35.0f, 22.5f, 0.0f };
float v2[3] = { -35.0f, -22.5f, 0.0f };
float v3[3] = { 0.0f, 42.5f, 0.0f };
float v4[3] = { 0.0f, -42.5f, 0.0f };
float v5[3] = { 35.0f, 22.5f, 0.0f };
float v6[3] = { 35.0f, -22.5f, 0.0f };
float px, py;
float center_s[3] = { 0.0f, 0.0f, 0.0f };
float center_d[3] = { px, py, 0.0f };
static GLfloat spin = 0.0;
float x = 400.0f, y = 442.5f;
float color1[3] = { 1.0f, 1.0f, 1.0f };
float color2[3] = { 1.0f, 1.0f, 1.0f };
int mode = 1;
int rotate = 1;
void init(void);
void triangle_1(void);
void triangle_2(void);
void lines(void);
void display(void);
void spinDisplay_1(void);
void spinDisplay_2(void);
void reshape(int, int);
void changeColor(int);
void mouse(int, int, int, int);
////////////////////////////////////////////////////////////////////
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(300, 300);
glutCreateWindow("6-Point Star");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}
////////////////////////////////////////////////////////////////////
void init(void) {
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
}
void triangle_1(void) {
glColor3fv(color1);
glBegin(GL_TRIANGLE_FAN);
glVertex3fv(v1);
glVertex3fv(v4);
glVertex3fv(v5);
glEnd();
}
void triangle_2(void) {
glColor3fv(color2);
glBegin(GL_TRIANGLE_FAN);
glVertex3fv(v2);
glVertex3fv(v3);
glVertex3fv(v6);
glEnd();
}
void lines(void) {
glColor3f(1.0, 0.0, 0.0);
glPointSize(5);
glBegin(GL_POINTS);
glVertex3fv(center_s);
glLineWidth(1);
glBegin(GL_LINES);
glVertex3fv(center_s);
glVertex3fv(center_d);
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glTranslatef(x, y, 0.0f);
glRotatef(spin, 0.0, 0.0, 1.0);
triangle_1();
triangle_2();
glPopMatrix();
glutSwapBuffers();
}
void spinDisplay_1(void) {
spin = spin + 2.0;
if (spin > 360.0) {
spin = spin - 360.0;
}
glutPostRedisplay();
}
void spinDisplay_2(void) {
spin = spin - 2.0;
if (spin < 360.0) {
spin = spin + 360.0;
}
glutPostRedisplay();
}
void reshape(int w, int h) {
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 500.0, 0.0, 500.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void changeColor(int n) {
if (n == 1) {
color1[0] = 0.0f, color1[1] = 0.0f, color1[2] = 1.0f;
color2[0] = 0.0f, color2[1] = 1.0f, color2[2] = 0.0f;
}
else if (n == 2) {
color1[0] = 1.0f, color1[1] = 1.0f, color1[2] = 1.0f;
color2[0] = 1.0f, color2[1] = 1.0f, color2[2] = 1.0f;
}
}
void mouse(int button, int state, int mx, int my) {
switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN) {
x = mx;
y = glutGet(GLUT_WINDOW_HEIGHT) - my;
px = x + 35.0;
py = y + 42.5;
glutIdleFunc(lines);
}
glutPostRedisplay();
break;
case GLUT_MIDDLE_BUTTON:
if (state == GLUT_DOWN) {
if (mode == 1) {
changeColor(mode);
mode = 2;
}
else if (mode == 2) {
changeColor(mode);
mode = 1;
}
}
glutPostRedisplay();
break;
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN)
if (rotate == 1) {
glutIdleFunc(spinDisplay_1);
rotate = 2;
}
else if (rotate == 2) {
glutIdleFunc(spinDisplay_2);
rotate = 1;
}
break;
default:
break;
}
}
最佳答案
你错过了一些 glEnd()
除非你对 center_s
有其他计划和 center_d
那么你不需要它们。作为x
和 y
是center_s
, 而 px
和 py
是center_d
.
所以首先在mouse()
只需将鼠标位置分配给 px
和 py
而不是 x
和 y
.
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN) {
px = mx;
py = glutGet(GLUT_WINDOW_HEIGHT) - my;
}
接下来您需要一种获取增量时间的方法。增量时间是自上一帧以来耗时。 为方便起见,我将以下代码添加到 display()
的顶部.
int timeNow = glutGet(GLUT_ELAPSED_TIME);
float delta = (float)(timeNow - timeLastFrame) / 1000.0f;
timeLastFrame = timeNow;
记得申报int timeLastFrame = 0;
在你的全局变量中。
现在(仍在 display()
中)我们可以计算行进路径的方向。我们通过计算两点之间的差异来做到这一点。然后计算长度并对差异进行归一化。
float dx = px - x;
float dy = py - y;
float length = sqrt(dx * dx + dy * dy);
dx /= length;
dy /= length;
现在您只需将它们放在一起即可。
if (length > 1.0f) {
x += dx * speed * delta;
y += dy * speed * delta;
}
所以 length > 1.0
然后我们走向px
和 py
以 float speed = 100.0f;
的速度(也在你的全局变量中声明它)。
再强调一下。是的,请删除 glutIdleFunc(lines)
来自 mouse()
.然后我们把它添加到display()
中反而。 display()
的完整扩展现在应该是这样的:
void display(void) {
int timeNow = glutGet(GLUT_ELAPSED_TIME);
float delta = (float)(timeNow - timeLastFrame) / 1000.0f;
timeLastFrame = timeNow;
float dx = px - x;
float dy = py - y;
float length = sqrt(dx * dx + dy * dy);
dx /= length;
dy /= length;
if (length > 1.0f) {
x += dx * speed * delta;
y += dy * speed * delta;
}
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glTranslatef(x, y, 0.0f);
glRotatef(spin, 0.0, 0.0, 1.0);
triangle_1();
triangle_2();
glPopMatrix();
lines();
glutSwapBuffers();
glutPostRedisplay();
}
记住glutPostRedisplay()
.如果不是,那么它不会重绘,因此不会设置动画。还记得#include <math.h>
对于 sqrt()
.
glClear()
之前的所有内容可以转移到你的glutIdleFunc()
回调。
因为不需要 center_s
和 center_d
然后 lines()
可以归结为:
void lines(void) {
glColor3f(1.0, 0.0, 0.0);
glPointSize(5);
glBegin(GL_POINTS);
glVertex2f(px, py);
glEnd();
glLineWidth(1);
glBegin(GL_LINES);
glVertex2f(x, y);
glVertex2f(px, py);
glEnd();
}
结果应该是这样的:
供将来引用。如果你不想手工做线性代数。然后你可以使用类似 GLM 的东西.
关于c++ - 在 OpenGL 中绘制物体的轨迹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43164540/