C++ C++;创建包含节的多维数据集

C++ C++;创建包含节的多维数据集,c++,C++,我正试图找出一种算法来创建一个立方体/长方体,其中每个维度都可以划分为多个部分。创建球体或圆柱体时类似于环和边的东西 例如,要一次获取球体的所有顶点,可以执行以下操作: for (int r = 0; r < rings-1; ++r) { float u = -M_PI_2 + ((r+1) * M_PI / rings); float v = -M_PI; for (int s= 0; s < sides; ++s) { floa

我正试图找出一种算法来创建一个立方体/长方体,其中每个维度都可以划分为多个部分。创建球体或圆柱体时类似于环和边的东西

例如,要一次获取球体的所有顶点,可以执行以下操作:

for (int r = 0; r < rings-1; ++r)
{
    float u = -M_PI_2 + ((r+1) * M_PI / rings);
    float v = -M_PI;

    for (int s= 0; s < sides; ++s)
    {
        float x = radius * cos(u) * cos(v);
        float y = radius * sin(u);
        float z = radius * cos(u) * sin(v);
        add_vertex(x, y, z);
        v += 2 * M_PI / sides;
    }
}   
for(int r=0;r

任何关于如何在理论上进行类似操作的帮助都将不胜感激。

以下是创建cude的代码,其中包含堆栈、wslice和dslice。它用于向OpenGL绘制数组缓冲区。您可以简单地删除未使用的法线和颜色数组,并仅使用顶点数组。不要因为
GLint
GLfloat
类型而惊慌失措,它们只是int和float的同义词

void DrawBox(GLfloat fWidth,GLfloat fHeight,GLfloat fDepth,GLint wslices,GLint dslices,GLint stacks)
{
     // Calculate number of primitives on each side of box
     // because we can use different tessalation configurations 
     // we must calculate separate group of box sides 

    int iTopButtonQuads = wslices * dslices * 2; // Calculate number of quads in top and button sides
    int iLeftRightQuads = dslices * stacks * 2; // Calculate number of quads in left and right sides
    int iFrontBackQuads = wslices * stacks * 2; // Calculate number of quads in front and back sides

    // If we consider to use quads as primitive then each primitive will
    // have 4 points, and each point has color, coord and normal attribute.
    // So we create separate array to contain each attibute values.

    float* pfVertices = new float[(iTopButtonQuads + iLeftRightQuads + iFrontBackQuads) * 3 * 4];
    float* pfColors = new float[(iTopButtonQuads + iLeftRightQuads + iFrontBackQuads) * 3 * 4];
    float* pfNormals = new float[(iTopButtonQuads + iLeftRightQuads + iFrontBackQuads) * 3 * 4];

    int iVertexIndex = 0;

    GLfloat Xstep = fWidth / wslices;
    GLfloat Ystep = fHeight / stacks;
    GLfloat Zstep = fDepth / dslices;

    GLfloat firstX = fWidth / 2.0f;
    GLfloat firstY = fHeight / 2.0f;
    GLfloat firstZ = fDepth / 2.0f;

    GLfloat currX = 0.0f;
    GLfloat currY = 0.0f;
    GLfloat currZ = 0.0f;

    GLfloat x_status = 0.0f;
    GLfloat y_status = 0.0f;
    GLfloat z_status = 0.0f;

    // the bottom and the top of the box
    for (currZ = -firstZ, z_status = 0.0f; currZ < firstZ - Zstep / 2.0f; currZ += Zstep, z_status += Zstep)
    {
        for (currX = -firstX, x_status = 0.0f; currX < firstX - Xstep / 2.0f; currX += Xstep, x_status += Xstep)
        {
            int iCurrentIndex = iVertexIndex * 3 * 4;

            float pfNormal[3] = { 0.0f, -1.0f, 0.0f };

            memcpy(pfNormals + iCurrentIndex, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 3, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 6, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 9, pfNormal, 3 * 4);

            float pfColor[3] = { 1.0f, 0.0f, 0.0f };

            memcpy(pfColors + iCurrentIndex, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 3, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 6, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 9, pfColor, 3 * 4);

            float pfVertex0[3] = {currX,-firstY,currZ};
            float pfVertex1[3] = {currX + Xstep,-firstY,currZ};
            float pfVertex2[3] = {currX + Xstep,-firstY,currZ + Zstep};
            float pfVertex3[3] = {currX,-firstY,currZ + Zstep};

            memcpy(pfVertices + iCurrentIndex, pfVertex0, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 3, pfVertex1, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 6, pfVertex2, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 9, pfVertex3, 3 * 4);

            iVertexIndex++;
        }

        for (currX = -firstX, x_status = 0.0f; currX < firstX - Xstep / 2.0f; currX += Xstep, x_status += Xstep)
        {
            int iCurrentIndex = iVertexIndex * 3 * 4;

            float pfNormal[3] = { 0.0f, 1.0f, 0.0f };

            memcpy(pfNormals + iCurrentIndex, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 3, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 6, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 9, pfNormal, 3 * 4);

            float pfColor[3] = { 0.0f, 1.0f, 0.0f };

            memcpy(pfColors + iCurrentIndex, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 3, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 6, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 9, pfColor, 3 * 4);

            float pfVertex0[3] = {currX + Xstep,firstY,currZ + Zstep};
            float pfVertex1[3] = {currX + Xstep,firstY,currZ};
            float pfVertex2[3] = {currX,firstY,currZ};
            float pfVertex3[3] = {currX,firstY,currZ + Zstep};

            memcpy(pfVertices + iCurrentIndex, pfVertex0, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 3, pfVertex1, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 6, pfVertex2, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 9, pfVertex3, 3 * 4);

            iVertexIndex++;
        }
    }

    // the front and the back of the box
    for (currY = -firstY, y_status = 0.0f; currY < firstY - Ystep / 2.0f ; currY += Ystep, y_status += Ystep)
    {
        for (currX = -firstX, x_status = 0.0f; currX < firstX - Xstep / 2.0f; currX += Xstep, x_status += Xstep)
        {
            int iCurrentIndex = iVertexIndex * 3 * 4;

            float pfNormal[3] = { 0.0f, 0.0f, 1.0f };

            memcpy(pfNormals + iCurrentIndex, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 3, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 6, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 9, pfNormal, 3 * 4);

            float pfColor[3] = { 0.0f, 0.0f, 1.0f };

            memcpy(pfColors + iCurrentIndex, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 3, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 6, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 9, pfColor, 3 * 4);

            float pfVertex0[3] = {currX,currY,firstZ};
            float pfVertex1[3] = {currX + Xstep,currY,firstZ};
            float pfVertex2[3] = {currX + Xstep,currY + Ystep,firstZ};
            float pfVertex3[3] = {currX,currY + Ystep,firstZ};

            memcpy(pfVertices + iCurrentIndex, pfVertex0, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 3, pfVertex1, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 6, pfVertex2, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 9, pfVertex3, 3 * 4);

            iVertexIndex++;
        }

        for (currX = -firstX, x_status = 0.0f; currX < firstX - Xstep / 2.0f; currX += Xstep, x_status += Xstep)
        {
            int iCurrentIndex = iVertexIndex * 3 * 4;

            float pfNormal[3] = { 0.0f, 0.0f, -1.0f };

            memcpy(pfNormals + iCurrentIndex, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 3, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 6, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 9, pfNormal, 3 * 4);

            float pfColor[3] = { 0.0f, 1.0f, 1.0f };

            memcpy(pfColors + iCurrentIndex, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 3, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 6, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 9, pfColor, 3 * 4);

            float pfVertex0[3] = {currX + Xstep,currY + Ystep,-firstZ};
            float pfVertex1[3] = {currX + Xstep,currY,-firstZ};
            float pfVertex2[3] = {currX,currY,-firstZ};
            float pfVertex3[3] = {currX,currY + Ystep,-firstZ};

            memcpy(pfVertices + iCurrentIndex, pfVertex0, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 3, pfVertex1, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 6, pfVertex2, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 9, pfVertex3, 3 * 4);

            iVertexIndex++;
        }
    }

    // Right side and the left side of the box
    for (currY = -firstY, y_status = 0.0f; currY < firstY - Ystep / 2.0f; currY += Ystep, y_status += Ystep)
    {
        for (currZ = -firstZ, z_status = 0.0f; currZ < firstZ - Zstep / 2.0f; currZ += Zstep, z_status += Zstep)
        {
            int iCurrentIndex = iVertexIndex * 3 * 4;

            float pfNormal[3] = { 1.0f, 0.0f, 0.0f };

            memcpy(pfNormals + iCurrentIndex, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 3, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 6, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 9, pfNormal, 3 * 4);

            float pfColor[3] = { 1.0f, 0.0f, 1.0f };

            memcpy(pfColors + iCurrentIndex, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 3, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 6, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 9, pfColor, 3 * 4);

            float pfVertex0[3] = {firstX,currY,currZ};
            float pfVertex1[3] = {firstX,currY + Ystep,currZ};
            float pfVertex2[3] = {firstX,currY + Ystep,currZ + Zstep};
            float pfVertex3[3] = {firstX,currY,currZ + Zstep};

            memcpy(pfVertices + iCurrentIndex, pfVertex0, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 3, pfVertex1, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 6, pfVertex2, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 9, pfVertex3, 3 * 4);

            iVertexIndex++;
        }

        for (currZ = -firstZ, z_status = 0.0f; currZ < firstZ - Zstep / 2.0f; currZ += Zstep, z_status += Zstep)
        {
            int iCurrentIndex = iVertexIndex * 3 * 4;

            float pfNormal[3] = { -1.0f, 0.0f, 0.0f };

            memcpy(pfNormals + iCurrentIndex, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 3, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 6, pfNormal, 3 * 4);
            memcpy(pfNormals + iCurrentIndex + 9, pfNormal, 3 * 4);

            float pfColor[3] = { 1.0f, 1.0f, 0.0f };

            memcpy(pfColors + iCurrentIndex, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 3, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 6, pfColor, 3 * 4);
            memcpy(pfColors + iCurrentIndex + 9, pfColor, 3 * 4);

            float pfVertex0[3] = {-firstX,currY,currZ};
            float pfVertex1[3] = {-firstX,currY,currZ + Zstep};
            float pfVertex2[3] = {-firstX,currY + Ystep,currZ + Zstep};
            float pfVertex3[3] = {-firstX,currY + Ystep,currZ};

            memcpy(pfVertices + iCurrentIndex, pfVertex0, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 3, pfVertex1, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 6, pfVertex2, 3 * 4);
            memcpy(pfVertices + iCurrentIndex + 9, pfVertex3, 3 * 4);

            iVertexIndex++;
        }
    }

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);

    glColorPointer(3, GL_FLOAT, 0, (void*)pfColors);
    glNormalPointer(GL_FLOAT, 0, (void*)pfNormals);
    glVertexPointer(3, GL_FLOAT, 0, (void*)pfVertices);

    glDrawArrays(GL_QUADS, 0, (iTopButtonQuads + iLeftRightQuads + iFrontBackQuads) * 4);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);

    delete [] pfVertices;
    delete [] pfNormals;
    delete [] pfColors;
}
剩下的唯一顶点是

  float pfVertex0[3] = {-firstX,currY,currZ};
简单的算法显示24/4=6!=8.
因此,为了形成合适的长方体,我们只需在长方体的一侧(2个顶点)添加额外的迭代即可。

我试图避免每个面都有单独的循环(不确定是否可能),但这是一个非常可接受的答案,我研究了它,并将其适当标记为答案。非常感谢@J.Doe:您可以将相同列表值的循环分组。咖喱,咖喱,咖喱上面有一个问题。它不会创建唯一的顶点。例如:对于一个简单的立方体而不是8个顶点,您将有24个顶点。当你只是为了渲染而使用它时,这是完美的。@J.Doe:没问题。等一下,我将发布优化代码。我不认为通过循环现有元素来找到重复项是一个好的解决方案。例如,如果在下面的链接中看到ofMesh::box()函数,它将创建唯一的顶点,而不会带来额外的麻烦。唯一的问题是它会创建三角形,我更喜欢四边形。
  float pfVertex0[3] = {-firstX,currY,currZ};
  float pfVertex1[3] = {-firstX,currY,currZ + Zstep};
  float pfVertex2[3] = {-firstX,currY + Ystep,currZ + Zstep};
  float pfVertex3[3] = {-firstX,currY + Ystep,currZ};
  float pfVertex0[3] = {-firstX,currY,currZ};