So simply project a cube onto sphere ...
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.
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:
