-2

我正在尝试实现一个四元函数来绘制线条。我的目标是能够显示从一个 3D 点到另一个点的光束。但我失败了。此外,我希望能够在绘制四边形/圆柱体的函数中指定 3D 厚度参数。我需要画一个圆柱体吗?如果没有,如何设置 4 个 3D 四角坐标?我首先尝试使用四边形,但发现我真正需要的是圆柱体,请参阅我的答案中的代码,工作得很好,甚至根本不使用 GLU,原始 C。我编辑了这个问题,因为我的初始代码是令人困惑和奇怪。我的回答有效,我重复一遍。谢谢!

4

1 回答 1

1

这是我用来绘制圆柱体的改编(来自java)“原始”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();
}
于 2020-12-29T08:39:41.920 回答