生成球体的顶点

Gay*_*yan 13 c++ directx 3d

在DirectX移动照明示例中,以下列方式生成圆柱体:

for( DWORD i=0; i<50; i++ )
            {
                FLOAT theta = (2*D3DMX_PI*i)/(50-1);
                pVertices[2*i+0].position = D3DMXVECTOR3( (float)sin(theta),-1.0f, (float)cos(theta) );
                pVertices[2*i+0].normal   = D3DMXVECTOR3( (float)sin(theta), 0.0f, (float)cos(theta) );
                pVertices[2*i+1].position = D3DMXVECTOR3( (float)sin(theta), 1.0f, (float)cos(theta) );
                pVertices[2*i+1].normal   = D3DMXVECTOR3( (float)sin(theta), 0.0f, (float)cos(theta) );
            }
Run Code Online (Sandbox Code Playgroud)

是否有类似的方法在DirectX Mobile中生成球体的顶点(如三角形条带或其他方式)?(AFAIK没有D3DMXCreateSphere方法)


最后的解决方案.感谢四分之一的帮助.

void CreateSphere()
{
    const int iFactor = 20;
    int iPos = 0;

    arr_Vertices = new CUSTOMVERTEX[ui_VCount];
    ui_ShapeCount = iFactor *iFactor * 2; // use when rendering

    float arrV[iFactor* iFactor][3];

    for (DWORD j= 0; j < iFactor; j ++)
    {
        FLOAT theta = (D3DMX_PI*j)/(iFactor);

        for( DWORD i=0; i<iFactor; i++ )
        {
            iPos = j*iFactor+i;
            FLOAT phi = (2*D3DMX_PI*i)/(iFactor);
            arrV[iPos][0] = (float)(sin(theta)*cos(phi));
            arrV[iPos][1] = (float)(sin(theta)*sin(phi));
            arrV[iPos][2] = (float)(cos(theta));

            /*std::cout << "[" << j <<"][" << i << "] = " << arrV[iPos][0]  
                << "," << arrV[iPos][1] << "," << arrV[iPos][2] <<std::endl;*/
        }
    }

    int iNext = 0;

    for (DWORD j= 0; j < iFactor; j ++)
    { 

        for( DWORD i=0; i<iFactor; i++ )
        {
            if (i == iFactor - 1)
                iNext = 0;
            else iNext = i +1;

            iPos = (j*iFactor*6)+(i*6);
            arr_Vertices[iPos].position = D3DMXVECTOR3( arrV[j*iFactor+i][0], arrV[j*iFactor+i][1], arrV[j*iFactor+i][2]);
            arr_Vertices[iPos + 1].position = D3DMXVECTOR3( arrV[j*iFactor+iNext][0], arrV[j*iFactor+iNext][1], arrV[j*iFactor+iNext][2]);


            if (j != iFactor -1)
                arr_Vertices[iPos + 2].position = D3DMXVECTOR3( arrV[((j+1)*iFactor)+i][0], arrV[((j+1)*iFactor)+i][1], arrV[((j+1)*iFactor)+i][2]);
            else
                arr_Vertices[iPos + 2].position = D3DMXVECTOR3( 0, 0, -1); //Create a pseudo triangle fan for the last set of triangles

            arr_Vertices[iPos].normal = D3DMXVECTOR3( arr_Vertices[iPos].position.x, arr_Vertices[iPos].position.y, arr_Vertices[iPos].position.z);
            arr_Vertices[iPos + 1].normal = D3DMXVECTOR3( arr_Vertices[iPos+1].position.x, arr_Vertices[iPos+1].position.y, arr_Vertices[iPos+1].position.z);
            arr_Vertices[iPos + 2].normal = D3DMXVECTOR3( arr_Vertices[iPos+2].position.x, arr_Vertices[iPos+2].position.y, arr_Vertices[iPos+2].position.z);

            arr_Vertices[iPos + 3].position = D3DMXVECTOR3( arr_Vertices[iPos+2].position.x, arr_Vertices[iPos+2].position.y, arr_Vertices[iPos+2].position.z);
            arr_Vertices[iPos + 4].position = D3DMXVECTOR3( arr_Vertices[iPos+1].position.x, arr_Vertices[iPos+1].position.y, arr_Vertices[iPos+1].position.z);

            if (j != iFactor - 1)
                arr_Vertices[iPos + 5].position = D3DMXVECTOR3( arrV[((j+1)*iFactor)+iNext][0], arrV[((j+1)*iFactor)+iNext][1], arrV[((j+1)*iFactor)+iNext][2]);
            else
                arr_Vertices[iPos + 5].position = D3DMXVECTOR3( 0,0,-1);

            arr_Vertices[iPos + 3].normal = D3DMXVECTOR3( arr_Vertices[iPos+3].position.x, arr_Vertices[iPos+3].position.y, arr_Vertices[iPos+3].position.z);
            arr_Vertices[iPos + 4].normal = D3DMXVECTOR3( arr_Vertices[iPos+4].position.x, arr_Vertices[iPos+4].position.y, arr_Vertices[iPos+4].position.z);
            arr_Vertices[iPos + 5].normal = D3DMXVECTOR3( arr_Vertices[iPos+5].position.x, arr_Vertices[iPos+5].position.y, arr_Vertices[iPos+5].position.z);

            //std::cout << "[" << iPos <<"] = " << arr_Vertices[iPos].position.x << 
            //  "," << arr_Vertices[iPos].position.y <<
            //  "," << arr_Vertices[iPos].position.z <<std::endl;

            //std::cout << "[" << iPos + 1 <<"] = " << arr_Vertices[iPos + 1].position.x << 
            //  "," << arr_Vertices[iPos+ 1].position.y <<
            //  "," << arr_Vertices[iPos+ 1].position.z <<std::endl;

            //std::cout << "[" << iPos + 2 <<"] = " << arr_Vertices[iPos].position.x << 
            //  "," << arr_Vertices[iPos + 2].position.y <<
            //  "," << arr_Vertices[iPos + 2].position.z <<std::endl;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

只需几个调整即可使用.这会创建一个TRIANGLELIST,但可以更改为输出一组三角形条带

Qua*_*ion 11

思考它的基本方法:

第一种不使用连续三角形条的方法......

已经有一段时间了,所以我可能会犯错误......

以参数方式定义的单位圆:

Where 0 =< theta < 2pi 
x = sin(theta);
y = cos(theta);
Run Code Online (Sandbox Code Playgroud)

现在我们可以定义一个圆圈,想象一下x,y平面上的同心环.现在想象一下提高了内心最圆,因为你提出来它拉了下环,像紧身...这个可视化只适用于半个球体.

使得从同心环产生的球的形状的形式是当然的另一个圆正交于所述环中,(Z,Y)平面...当然,我们仅在发现所述偏移环的(有兴趣的需要从(x,y)平面偏移的高低.

因为我们只需要偏移,我们只需要半个圆......而且极点只是一个点.在两极之间使用三角形风扇,在每个环之间使用条带.

这种心理练习后看到http://en.wikipedia.org/wiki/Sphere 并搜索"在半径为r的球的点可以通过被参数"和该行后,你会看到参数形式.

法线是很容易的球应始终围绕建设(0,0,0)和球体应始终为1(所以你可以简单地把它扩展到所需的大小)半径建立,然后每个顶点在圆表面等于正常值.


上述方法使用两个三角形扇等一系列三角形带的......其产生的球体均匀分布顶点,并可以用一个三角形带绘制的另一种方法,但在现阶段,我会发疯试图码它涉及以下想法:

想象一个以原点为中心的四面体(这些点是从0,0,0开始的1个单位).这是一个非常可悲的球体表示,但它是一个近似值.现在假设我们在四个面中的每个面上找到中点,然后将该点推出,直到它在球体的表面上.然后我们找到那些面的中点并将它们推到球体的表面......

tetrahdralSphere(int recursions){}

找到中点非常简单,它只是每个x,y,z分量的平均值.然后,由于球体是一个单位球体,将它们移动到表面就像归一化这个新的矢量一样简单.


方法一产生一个点分布,它看起来经度和纬度的线条并产生一个非均匀的分布(如果使用四边形和一个线框,它看起来就像一个地球仪),它很容易实现.第二种方法需要递归,因此它更难一点但看起来更均匀.如果你想变得非常复杂并且伤到你的头......然后尝试分配n点,然后模拟点之间的驱避力,将它们分开,然后将它们在表面上标准化.有一些令人头疼的问题需要解决才能使这项工作有效,但是你有相当均匀分布的点,你可以控制顶点的数量,你将开始了解建模工具所需的内容.找到表示模型的最小几何.


采用第一种方法.在(0,0,1)处画一个点然后你需要你的第一个同心环(为简单起见,每个环将具有相同数量的点).

让每个环画10个点...所以phi将以2pi/10的增量步进,并绘制10个同心环

我们将绘制10个环+2个极点,因此theta将以pi/12的增量增加.

//this psudo code places the points
//NOT TESTED
deltaTheta = pi/12;
deltaPhi = 2pi/10;
drawVertex(0,0,1) //north pole end cap
for(int ring; ring < 10; ring++){ //move to a new z - offset 
  theta += deltaTheta;
  for(int point; point < 10; point++){ // draw a ring
    phi += deltaPhi;
    x = sin(theta) * cos(phi)
    y = sin(theta) * sin(phi)
    z = cos(theta)
    drawVertex(x,y,z)
  }
}
drawVertex(0, 0, -1) //south pole end cap
Run Code Online (Sandbox Code Playgroud)


Ale*_* C. 5

三角测量单位球体通常的方式是建立一个四面体二十面体

  • 如果精度足够,请停止
  • 否则,对于每个现有面孔:
  • 在每条边的中点添加一个顶点并对其进行标准化,使其位于单位球面上
  • 用四个新面替换面部.其中一个面具有三个新的中点作为角点(在纸上绘制,其他三个面将变得明显)
  • 环.

为避免在边缘中点重复顶点,您需要跟踪现有顶点以便重复使用.