gpt4 book ai didi

c++ - 为球体生成顶点

转载 作者:IT老高 更新时间:2023-10-28 21:45:43 24 4
gpt4 key购买 nike

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

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


最终解决方案。感谢 Quarternion 提供的所有帮助。

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

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

最佳答案

基本思路:

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

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

参数化定义的单位圆:

Where 0 =< theta < 2pi 
x = sin(theta);
y = cos(theta);

现在我们可以定义一个圆,想象一下 x,y 平面上的同心环。现在想象一下,举起最里面的圆圈,当你举起它时,它会拉起下一个环,就像一个紧身的……这个视觉效果只适用于半个球体。

因此,从同心环产生球体形状的形式当然是另一个与环正交的圆,即 (z,y) 平面...当然我们只对找到偏移量感兴趣环(它需要从 (x,y) 平面偏移多高或多低。

因为我们只需要偏移量,我们只需要半个圆......而且极点将只有一个点。在每个环之间的杆和条上使用三角形风扇。

在这个心理练习之后,请参阅 http://en.wikipedia.org/wiki/Sphere并搜索“半径为 r 的球体上的点可以通过参数化”,您将在该行之后看到参数形式。

法线非常简单,球体应始终围绕 (0,0,0) 构建,并且球体应始终以半径 1 构建(因此您可以简单地将其缩放到所需的大小),然后是每个顶点圆面上等于法线。


上面的方法使用了两个三角扇和一系列三角带......另一种方法可以产生一个顶点分布均匀的球体,并且可以用单个三角带绘制,虽然此时我会发疯尝试对其进行编码涉及以下想法:

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

四面体球体(整数递归){}

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


方法一产生一个点分布,看起来像经度和纬度线,并产生非均匀分布(如果使用四边形和线框,它看起来就像一个地球),它很容易实现。第二种方法需要递归,所以它有点困难,但看起来更统一。如果你想变得非常复杂并伤害你的头......然后尝试分布 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

关于c++ - 为球体生成顶点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4405787/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com