将立方体变形为球体

时间:2016-04-01 09:18:46

标签: c++ opengl

我试图了解创建球体背后的数学。我刚刚开始,但我做了一些研究,他们说我需要制作一个点网格并使用公式来创建一个球体。我的问题是,是另一种方式,包括立方体上的四边形?如果不是,我将划伤我的项目并开始创建一个带点网格的立方体,而不是立方体面的四边形。

#include <GL/glut.h>
#include <iostream>

      void DrawArea (){
      glColor3f(1,1, 1);
      glBegin(GL_QUADS);

      glVertex3f(-10, -1.1, 10);
      glVertex3f(10, -1.1, 10);
      glVertex3f(10, -1.1, -10);
      glVertex3f(-10, -1.1, -10);
      glEnd();

    }

GLfloat n[6][3] = {  /* Normals for the 6 faces of a cube. */
  {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, { 1.0, 0.0, 0.0},
  {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0} };
GLint faces[6][4] = {  /* Vertex indices for the 6 faces of a cube. */
  {0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4},
  {4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3} };
GLfloat v[8][3];  /* Will be filled in with X,Y,Z vertexes. */
void init(void)
{
  /* Setup cube vertex data. */
  v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1;
  v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1;
  v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1;
  v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1;
  v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1;
  v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1;

  /* Use depth buffering for hidden surface elimination. */
  glEnable(GL_DEPTH_TEST);

  /* Setup the view of the cube. */
  glMatrixMode(GL_PROJECTION);
  gluPerspective( /* field of view in degree */ 70.0,
    /* aspect ratio */ 1.0,
    /* Z near */ 1.0, /* Z far */ 500.0);
  glMatrixMode(GL_MODELVIEW);
  gluLookAt(0.0, 0.0, 10,  /* eye is at (0,0,5) */
    0.0, 0.0, 0.0,      /* center is at (0,0,0) */
    0.0, 1.0, 0.);      /* up is in positive Y direction */

  /* Adjust cube position to be asthetic angle. */
  //glTranslatef(0.0, 0.0, -1.0);

}

void drawLines() {


      glBegin(GL_LINES);
      int y = 0;
      for (int i = 10; i != 0; i--) {

       // po x osi
        glVertex2f(-i, -0.1);
        glVertex2f(-i, 0.1);
        glVertex2f(i, -0.1);
        glVertex2f(i, 0.1);

        //po y osi
        glVertex2f(-0.1, -i);
        glVertex2f(0.1, -i);
        glVertex2f(-0.1, i);
        glVertex2f(0.1, i);
//      
//        //po z osi
//       // glColor3f(0.0f, 1.0f, 0.0f); //seems it doesnt register
        glVertex3f(0, -0.3, -i);
        glVertex3f(0, 0.3, -i);
        glVertex3f(0, -0.3, i);
        glVertex3f(0, 0.3, i);
      }
      glEnd();
    }

void drawGrid(){
  for(int a = 0; a<=10; a++){
  glBegin(GL_LINES);
 //po x-u
  glVertex3f(-a, 0, 10);
  glVertex3f(-a, 0, -10);
  glVertex3f(a, 0, 10);
  glVertex3f(a, 0, -10);
  //po z
  glVertex3f(-10, 0, -a);
  glVertex3f(10, 0, -a);

  glVertex3f(10, 0, a);
  glVertex3f(-10, 0, a);
  glEnd();
  }

}
void drawCP() {
      drawLines();
      glBegin(GL_LINES);

      glVertex2f(-10.0f, 0);
      glVertex2f(10.0f, 0);

      glVertex3f(0.0f, 0.0f, -10);
      glVertex2f(0,0);
      glEnd(); 
    }

GLfloat color[8][3] = 
{
    {0.0,1.0,1.0},
    {1.0,0.0,0.0},
    {1.0,1.0,0.0},
    {0.0,1.0,0.0},
    {0.0,0.0,1.0},
    {1.0,0.0,1.0},
    {1.0,1.0,1.0},
    {0.0,1.0,1.0},
};

void drawBox()
{
  int i;

  for (i = 0; i < 6; i++) {
    glBegin(GL_QUADS);
    glNormal3fv(&n[i][0]);
    glColor3fv(color[i]);
    glVertex3fv(&v[faces[i][0]][0]);
    glVertex3fv(&v[faces[i][1]][0]);
    glVertex3fv(&v[faces[i][2]][0]);
    glVertex3fv(&v[faces[i][3]][0]);

    glEnd();
  }
}
void display(void)
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


  drawBox();
  glColor3f(0.0,0.0,0.0);
  drawGrid();
  glColor3f(1.0,1.0,1.0);
  drawCP();
  glPopMatrix();
  glutSwapBuffers();
}

void timer (int mili){
  glutPostRedisplay();
  glutTimerFunc(mili, timer, mili);
}

int main(int argc, char **argv)
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(800, 800);
  glEnable(GL_COLOR_MATERIAL);
  glutCreateWindow("red 3D lighted cube");
  init();
  glutDisplayFunc(display);
  glClearColor(0.6, 0.6, 0.6, 1);
  glutMainLoop();
  return 0;             /* ANSI C requires main to return int. */
}

1 个答案:

答案 0 :(得分:0)

我很少看到使用QUADS(虽然它们当然可以生成球体),因为用于转换/渲染的大多数算法都基于三角形数学。切换到GL_TRIANGLES或GL_TRIANGLE_STRIP会更好。

使用三角形生成球体顶点的算法非常简单,通常使用基本的三角函数。这就是我用于简单半球的方法

float Hincrement = PI / (Hresolution - 1);
float Vincrement = PI / (Vresolution - 1);

float theta = 0;
float phi = Vincrement;

for (int i = 0; i < Vresolution; i += 1){
    for (int j = 0; j < Hresolution - 2; j++){
        hemisphereVertices[currentIndex] = (radius * cos(phi)) + transX;
        hemisphereVertices[currentIndex + 1] = (radius * sin(theta) * sin(phi)) + transY;
        hemisphereVertices[currentIndex + 2] = (radius * cos(theta) * sin(phi)) + transZ;

        phi += Vincrement;
        currentIndex += 3;
    }
    phi = Vincrement;
    theta += Hincrement;
}

更难的部分是创建索引缓冲区,但可以使用类似的方法。