在 OpenGL 中的 2 个 3D 向量之间绘制圆柱体的 C 代码是什么?我希望它随着离观众更近而按比例变大
What would be the C code to draw a cylinder between 2 3D vectors in OpenGL? I want it to get proportionally bigger as it is closer to viewer
我正在尝试实现一个四边形函数来画线。我的目标是能够显示从一个 3D 点到另一个点的光束。但我失败了。此外,我希望能够在绘制 quad/cylinder 的函数中指定 3D 厚度参数。我需要画一个圆柱体吗?如果没有,如何设置 4 个 3D 四角坐标?我首先尝试使用四边形,但发现我真正需要的是一个圆柱体,请参阅我的答案中的代码,工作正常,甚至根本不使用 GLU,原始 C。我编辑了这个问题,因为我的初始代码是令人困惑和奇怪。我的回答有效,我重复一遍。谢谢!
这是我用来绘制圆柱体的改编版(来自 java)'raw' C 代码:
void getFirstPerpVector(float x, float y, float z, vec3_t result)
{
result[0] = result[1] = result[2] = 0.0f;
// That's easy.
if (x == 0.0f || y == 0.0f || z == 0.0f) {
if (x == 0.0f)
result[0] = 1.0f;
else if (y == 0.0f)
result[1] = 1.0f;
else
result[2] = 1.0f;
}
else {
// If xyz is all set, we set the z coordinate as first and second argument .
// As the scalar product must be zero, we add the negated sum of x and y as third argument
result[0] = z; //scalp = z*x
result[1] = z; //scalp = z*(x+y)
result[2] = -(x + y); //scalp = z*(x+y)-z*(x+y) = 0
// Normalize vector
float length = 0.0f;
length += result[0] * result[0];
length += result[1] * result[1];
length += result[2] * result[2];
length = (float)sqrt(length);
for (int i = 0; i < 3; i++)
result[i] /= length;
}
}
void drawCylinder(float x1, float y1, float z1, float x2, float y2, float z2, float thick, col_t color)
{
int X = 0,
Y = 1,
Z = 2;
// Get components of difference vector
float x = x1 - x2,
y = y1 - y2,
z = z1 - z2;
vec3_t firstPerp;
getFirstPerpVector(x, y, z, firstPerp);
// Get the second perp vector by cross product
vec3_t secondPerp;
secondPerp[X] = y * firstPerp[Z] - z * firstPerp[Y];
secondPerp[Y] = z * firstPerp[X] - x * firstPerp[Z];
secondPerp[Z] = x * firstPerp[Y] - y * firstPerp[X];
// Normalize vector
float length = 0.0f;
length += secondPerp[0] * secondPerp[0];
length += secondPerp[1] * secondPerp[1];
length += secondPerp[2] * secondPerp[2];
length = (float)sqrt(length);
for (int i = 0; i < 3; i++)
secondPerp[i] /= length;
// Having now our vectors, here we go:
// First points; you can have a cone if you change the radius R1
int ANZ = C_CYLINDER_NUM_VERTICES; // number of vertices Original 32
float FULL = (float)(2.0f * M_PI),
R1 = thick;// 2.0f; // radius Original 4.0f
float points[C_CYLINDER_NUM_VERTICES + 1][3]; // 32 was ANZ
for (int i = 0; i < ANZ; i++) {
float angle = FULL * (i / (float)ANZ);
points[i][X] = (float)(R1 * (cos(angle) * firstPerp[X] + sin(angle) * secondPerp[X]));
points[i][Y] = (float)(R1 * (cos(angle) * firstPerp[Y] + sin(angle) * secondPerp[Y]));
points[i][Z] = (float)(R1 * (cos(angle) * firstPerp[Z] + sin(angle) * secondPerp[Z]));
}
// Set last to first
for (int x = 0; x < 3; x++)
points[ANZ][x] = points[0][x];
glColor4ubv(color);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(x1, y1, z1);
for (int i = 0; i <= ANZ; i++) {
glVertex3f(x1 + points[i][X],
y1 + points[i][Y],
z1 + points[i][Z]);
}
glEnd();
glBegin(GL_TRIANGLE_FAN);
glVertex3f(x2, y2, z2);
for (int i = 0; i <= ANZ; i++) {
glVertex3f(x2 + points[i][X],
y2 + points[i][Y],
z2 + points[i][Z]);
}
glEnd();
glBegin(GL_QUAD_STRIP);
for (int i = 0; i <= ANZ; i++) {
glVertex3f(x1 + points[i][X],
y1 + points[i][Y],
z1 + points[i][Z]);
glVertex3f(x2 + points[i][X],
y2 + points[i][Y],
z2 + points[i][Z]);
}
glEnd();
}
我正在尝试实现一个四边形函数来画线。我的目标是能够显示从一个 3D 点到另一个点的光束。但我失败了。此外,我希望能够在绘制 quad/cylinder 的函数中指定 3D 厚度参数。我需要画一个圆柱体吗?如果没有,如何设置 4 个 3D 四角坐标?我首先尝试使用四边形,但发现我真正需要的是一个圆柱体,请参阅我的答案中的代码,工作正常,甚至根本不使用 GLU,原始 C。我编辑了这个问题,因为我的初始代码是令人困惑和奇怪。我的回答有效,我重复一遍。谢谢!
这是我用来绘制圆柱体的改编版(来自 java)'raw' C 代码:
void getFirstPerpVector(float x, float y, float z, vec3_t result)
{
result[0] = result[1] = result[2] = 0.0f;
// That's easy.
if (x == 0.0f || y == 0.0f || z == 0.0f) {
if (x == 0.0f)
result[0] = 1.0f;
else if (y == 0.0f)
result[1] = 1.0f;
else
result[2] = 1.0f;
}
else {
// If xyz is all set, we set the z coordinate as first and second argument .
// As the scalar product must be zero, we add the negated sum of x and y as third argument
result[0] = z; //scalp = z*x
result[1] = z; //scalp = z*(x+y)
result[2] = -(x + y); //scalp = z*(x+y)-z*(x+y) = 0
// Normalize vector
float length = 0.0f;
length += result[0] * result[0];
length += result[1] * result[1];
length += result[2] * result[2];
length = (float)sqrt(length);
for (int i = 0; i < 3; i++)
result[i] /= length;
}
}
void drawCylinder(float x1, float y1, float z1, float x2, float y2, float z2, float thick, col_t color)
{
int X = 0,
Y = 1,
Z = 2;
// Get components of difference vector
float x = x1 - x2,
y = y1 - y2,
z = z1 - z2;
vec3_t firstPerp;
getFirstPerpVector(x, y, z, firstPerp);
// Get the second perp vector by cross product
vec3_t secondPerp;
secondPerp[X] = y * firstPerp[Z] - z * firstPerp[Y];
secondPerp[Y] = z * firstPerp[X] - x * firstPerp[Z];
secondPerp[Z] = x * firstPerp[Y] - y * firstPerp[X];
// Normalize vector
float length = 0.0f;
length += secondPerp[0] * secondPerp[0];
length += secondPerp[1] * secondPerp[1];
length += secondPerp[2] * secondPerp[2];
length = (float)sqrt(length);
for (int i = 0; i < 3; i++)
secondPerp[i] /= length;
// Having now our vectors, here we go:
// First points; you can have a cone if you change the radius R1
int ANZ = C_CYLINDER_NUM_VERTICES; // number of vertices Original 32
float FULL = (float)(2.0f * M_PI),
R1 = thick;// 2.0f; // radius Original 4.0f
float points[C_CYLINDER_NUM_VERTICES + 1][3]; // 32 was ANZ
for (int i = 0; i < ANZ; i++) {
float angle = FULL * (i / (float)ANZ);
points[i][X] = (float)(R1 * (cos(angle) * firstPerp[X] + sin(angle) * secondPerp[X]));
points[i][Y] = (float)(R1 * (cos(angle) * firstPerp[Y] + sin(angle) * secondPerp[Y]));
points[i][Z] = (float)(R1 * (cos(angle) * firstPerp[Z] + sin(angle) * secondPerp[Z]));
}
// Set last to first
for (int x = 0; x < 3; x++)
points[ANZ][x] = points[0][x];
glColor4ubv(color);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(x1, y1, z1);
for (int i = 0; i <= ANZ; i++) {
glVertex3f(x1 + points[i][X],
y1 + points[i][Y],
z1 + points[i][Z]);
}
glEnd();
glBegin(GL_TRIANGLE_FAN);
glVertex3f(x2, y2, z2);
for (int i = 0; i <= ANZ; i++) {
glVertex3f(x2 + points[i][X],
y2 + points[i][Y],
z2 + points[i][Z]);
}
glEnd();
glBegin(GL_QUAD_STRIP);
for (int i = 0; i <= ANZ; i++) {
glVertex3f(x1 + points[i][X],
y1 + points[i][Y],
z1 + points[i][Z]);
glVertex3f(x2 + points[i][X],
y2 + points[i][Y],
z2 + points[i][Z]);
}
glEnd();
}