Reconstruct a sphere from 6 patches

梦想的初衷 提交于 2020-07-23 09:07:11

问题


It sounds easy for me until I tried

The implementation uses lib igl but the problem is not there but in my lack of math knowledge :-\

Eigen::MatrixXd p;
const int size = 128;
p.resize(size * size, 3);
int index = 0;

for (int y = 0; y < size; y++)
{
  double ypos = (double(y) / double(size - 1)) - 0.5;
  for (int x = 0; x < size; x++)
  {
    double xpos = (double(x) / double(size - 1)) - 0.5;

    const double sphericalTheta = xpos * (pi / 2.0);
    const double sphericalPhi = ypos * (pi / 2.0);

    const double mX = cos(sphericalPhi) * sin(sphericalTheta);
    const double mY = cos(sphericalPhi) * cos(sphericalTheta);
    const double mZ = sin(sphericalPhi);
    p(index, 0) = mX;
    p(index, 1) = mY;
    p(index, 2) = mZ;
    index++;
  }
}

Eigen::MatrixXi f;
igl::write_triangle_mesh(path, p, f);

I was thinking that it could create a "face" of a sphere, I mean that using that piece 6 times rotated I could create a sphere but it doesn't work take a look at 3 patches together


回答1:


So simply project a cube onto sphere ...

  1. create cube as a NxN grid of points in range <-1,+1>

    so simply each face of cube is NxN regular grid of points. Each face have its own color. Each point has its position and normal.

  2. project all points to sphere surface.

    simply normalize the points size to radius of your sphere. And recompute the normals (unit vector of point)

Here small GL/C++ example:

//---------------------------------------------------------------------------
List<double> pnt;       // (x,y,z) all points
List<double> nor;       // (x,y,z) per point
List<int   > fac;       // (ix,p0,p1,p2) per triangle
List<double> col;       // (r,g,b) per ix

void sphere_init()
    {
    int i,j,n=10,n3=3*n,i0,i1,ix;
    double x,y,z,d=2.0/double(n-1);

    // clear mesh
    pnt.num=0;
    nor.num=0;
    fac.num=0;
    col.num=0;

    #define face0                \
        for (j=0;j<n-1;j++)      \
         for (i=0;i<n-1;i++)     \
            {                    \
            i1=i0+(3*(i+(j*n))); \
            fac.add(ix);         \
            fac.add(i1+n3+0);    \
            fac.add(i1   +3);    \
            fac.add(i1   +0);    \
            fac.add(ix);         \
            fac.add(i1+n3+0);    \
            fac.add(i1+n3+3);    \
            fac.add(i1   +3);    \
            }

    #define face1                \
        for (j=0;j<n-1;j++)      \
         for (i=0;i<n-1;i++)     \
            {                    \
            i1=i0+(3*(i+(j*n))); \
            fac.add(ix);         \
            fac.add(i1+n3+0);    \
            fac.add(i1   +0);    \
            fac.add(i1   +3);    \
            fac.add(ix);         \
            fac.add(i1+n3+3);    \
            fac.add(i1+n3+0);    \
            fac.add(i1   +3);    \
            }

    // init cube faces as 6 x N x N grid of points
    ix=0; z=-1.0; i0=pnt.num;
    col.add(0.0); 
    col.add(0.0); 
    col.add(1.0);
    for (y=-1.0,j=0;j<n;j++,y+=d)
     for (x=-1.0,i=0;i<n;i++,x+=d)
        {
        pnt.add(x); nor.add( 0.0);
        pnt.add(y); nor.add( 0.0);
        pnt.add(z); nor.add(-1.0);
        }
    face0;

    ix+=3; z=+1.0; i0=pnt.num;
    col.add(0.2); 
    col.add(0.2); 
    col.add(1.0);
    for (y=-1.0,j=0;j<n;j++,y+=d)
     for (x=-1.0,i=0;i<n;i++,x+=d)
        {
        pnt.add(x); nor.add( 0.0);
        pnt.add(y); nor.add( 0.0);
        pnt.add(z); nor.add(+1.0);
        }
    face1;

    ix+=3; x=-1.0; i0=pnt.num;
    col.add(1.0);
    col.add(0.0);
    col.add(0.0);
    for (y=-1.0,j=0;j<n;j++,y+=d)
     for (z=-1.0,i=0;i<n;i++,z+=d)
        {
        pnt.add(x); nor.add(-1.0);
        pnt.add(y); nor.add( 0.0);
        pnt.add(z); nor.add( 0.0);
        }
    face1;

    ix+=3; x=+1.0; i0=pnt.num;
    col.add(1.0); 
    col.add(0.2); 
    col.add(0.2);
    for (y=-1.0,j=0;j<n;j++,y+=d)
     for (z=-1.0,i=0;i<n;i++,z+=d)
        {
        pnt.add(x); nor.add(+1.0);
        pnt.add(y); nor.add( 0.0);
        pnt.add(z); nor.add( 0.0);
        }
    face0;

    ix+=3; y=-1.0; i0=pnt.num;
    col.add(0.0); 
    col.add(1.0); 
    col.add(0.0);
    for (x=-1.0,j=0;j<n;j++,x+=d)
     for (z=-1.0,i=0;i<n;i++,z+=d)
        {
        pnt.add(x); nor.add( 0.0);
        pnt.add(y); nor.add(-1.0);
        pnt.add(z); nor.add( 0.0);
        }
    face0;

    ix+=3; y=+1.0; i0=pnt.num;
    col.add(0.2); 
    col.add(1.0); 
    col.add(0.2);
    for (x=-1.0,j=0;j<n;j++,x+=d)
     for (z=-1.0,i=0;i<n;i++,z+=d)
        {
        pnt.add(x); nor.add( 0.0);
        pnt.add(y); nor.add(+1.0);
        pnt.add(z); nor.add( 0.0);
        }
    face1;

    // project to sphere
    for (i=0;i<pnt.num;i+=3)
        {
        x=pnt.dat[i+0];
        y=pnt.dat[i+1];
        z=pnt.dat[i+2];
        d=sqrt((x*x)+(y*y)+(z*z));
        if (d>1e-10) d=1.0/d;
        x*=d; nor.dat[i+0]=x; pnt.dat[i+0]=x;
        y*=d; nor.dat[i+1]=y; pnt.dat[i+1]=y;
        z*=d; nor.dat[i+2]=z; pnt.dat[i+2]=z;
        }
    #undef face0
    #undef face1
    }
void sphere_draw()
    {
    glEnable(GL_CULL_FACE);
    glFrontFace(GL_CCW);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_COLOR_MATERIAL);
    int i,ix;
    glBegin(GL_TRIANGLES);
    for (i=0;i<fac.num;)
        {
        ix=fac.dat[i]; i++;
        glColor3dv(col.dat+ix);
        glNormal3dv(nor.dat+fac.dat[i]); glVertex3dv(pnt.dat+fac.dat[i]); i++;
        glNormal3dv(nor.dat+fac.dat[i]); glVertex3dv(pnt.dat+fac.dat[i]); i++;
        glNormal3dv(nor.dat+fac.dat[i]); glVertex3dv(pnt.dat+fac.dat[i]); i++;
        }
    glEnd();
    }

I also use mine dynamic list template so:


List<double> xxx; is the same as double xxx[];
xxx.add(5); adds 5 to end of the list
xxx[7] access array element (safe)
xxx.dat[7] access array element (unsafe but fast direct access)
xxx.num is the actual used size of the array
xxx.reset() clears the array and set xxx.num=0
xxx.allocate(100) preallocate space for 100 items

Here preview:



来源:https://stackoverflow.com/questions/61735571/reconstruct-a-sphere-from-6-patches

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!