用6个补丁重建一个球体

问题描述 投票:0回答:1

这听起来很简单,直到我试过

实现使用lib igl,但问题不在这里,而是在我缺乏数学知识的情况下:-\\。

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);

我在想它可以创建一个球体的 "面",我的意思是说,使用那块旋转6次的球体,我可以创建一个球体,但这是行不通的,看看3个补丁在一起。 Doesn't match

c++ algorithm math trigonometry
1个回答
0
投票

所以简单地将一个立方体投影到球体上......。

  1. 创建一个立方体作为一个 NxN 点阵 <-1,+1>

    因此,简单地说,立方体的每个面都是 NxN 规则的网格点。每个面都有自己的颜色。每个点都有自己的位置和法线。

  2. 将所有点投射到球面上。

    简单地将点的大小归一化为球面的半径。并重新计算法线(点的单位向量)。

这里是GLC++的小例子。

//---------------------------------------------------------------------------
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();
    }

我的动态列表模板也是这么用的。

List<double> xxx; 是一样的 double xxx[];xxx.add(5); 补充 5 列表末尾xxx[7] 存取数组元素xxx.dat[7] 访问数组元素(不安全但快速直接访问)。xxx.num 是数组的实际使用大小xxx.reset() 清除阵列并设置 xxx.num=0xxx.allocate(100) 预留空间 100 物品

在此预览。

preview

© www.soinside.com 2019 - 2024. All rights reserved.