你如何以编程方式生成一个球体?

有人能解释一下如何创建一个球体顶点,索引和纹理坐标吗? 有一个惊人的文件缺乏如何这样做,这是我有兴趣学习的东西。

我已经尝试了明显的,谷歌search,看在gamedev.net等等。但是,没有什么涵盖球形点的世代,索引他们,纹理。

有两种一般的方法:

在这里输入图像描述

最左边的是紫外线,最右边是一个icosphere。

GLUT倾向于使用uv方法:查看freeglut源代码中的函数glutSolidSphere()

这是一个关于生产icosphere的优秀文章: http ://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html

紫外线看起来像一个地球仪。 对于很多目的来说,这是非常好的,但是对于一些使用情况,例如,如果要使球体变形,围绕极点的顶点密度更大是不利的。 这里icosphere更好,它的顶点分布均匀。

你也可能会发现这个有趣的东西: http : //kiwi.atmos.colostate.edu/BUGS/geodesic/text.html它描述了一种将面部组织成区域的方法。

http://vterrain.org/Textures/spherical.html给出了一个很好的描述,你可以select纹理他们。

有两种方法可以做到这一点:

  1. 在球坐标上走θ和φ,生成面和tris

  2. 创建一个二十面体,并recursion地细分面,直到达到所需的曲面细分。

球体使用球坐标走

对于第一种方法,你只需要使用一个双重嵌套的步行theta和phi。 当你走theta和phi,你旋转三角形来创建你的球体。

在这里输入图像描述

这样做的代码将如下所示:

 for( int t = 0 ; t < stacks ; t++ ) // stacks are ELEVATION so they count theta { real theta1 = ( (real)(t)/stacks )*PI ; real theta2 = ( (real)(t+1)/stacks )*PI ; for( int p = 0 ; p < slices ; p++ ) // slices are ORANGE SLICES so the count azimuth { real phi1 = ( (real)(p)/slices )*2*PI ; // azimuth goes around 0 .. 2*PI real phi2 = ( (real)(p+1)/slices )*2*PI ; //phi2 phi1 // | | // 2------1 -- theta1 // |\ _ | // | \ | // 3------4 -- theta2 // //vertex1 = vertex on a sphere of radius r at spherical coords theta1, phi1 //vertex2 = vertex on a sphere of radius r at spherical coords theta1, phi2 //vertex3 = vertex on a sphere of radius r at spherical coords theta2, phi2 //vertex4 = vertex on a sphere of radius r at spherical coords theta2, phi1 // facing out if( t == 0 ) // top cap mesh->addTri( vertex1, vertex3, vertex4 ) ; //t1p1, t2p2, t2p1 else if( t + 1 == stacks ) //end cap mesh->addTri( vertex3, vertex1, vertex2 ) ; //t2p2, t1p1, t1p2 else { // body, facing OUT: mesh->addTri( vertex1, vertex2, vertex4 ) ; mesh->addTri( vertex2, vertex3, vertex4 ) ; } } } 

因此,请注意,上面的帽子和底帽只能用三角而不是四边形。

二十面体球体

要使用一个二十面体,你只需要生成二十面体的点,然后把三角形卷起来。 坐在原点的二十面体的顶点是:

 (0, ±1, ±φ) (±1, ±φ, 0) (±φ, 0, ±1) where φ = (1 + √5) / 2 

然后你只需要看一个二十面体的graphics和那些垂直的风面。 我已经有这样做的代码。

如果点不必是局部统一的,而应该是全局统一的,并且不必遵循任何设定的模式,则可以使用飞镖投掷algorithm的变体将半径为r的球体上的n个点分布,平均相距几分。 这些值大致如下:

  1. 如果你想有一个特定数量的顶点:
    • n =(期望的顶点数量)
    • dist = 2× r ×√( π / n
  2. 如果你想在顶点之间有一个特定的平均距离:
    • n = 4× π ×( r / dist2
    • dist =(所需的平均距离)

在最简单的情况下,可以通过从(0,1)中选取两个均匀分布的variablesuv并根据公式θ = 2× π × uφ = arc从它们中计算极坐标, cos(2× v -1); 然后解散任何靠近已经选取的点的点。 对于一个稍微复杂一点,performance更好的algorithm,请参阅Cline,Jeschke,White,Razdan和Wonka的“ Dart Throwing on Surfaces ”。

在你select了前四个点之后(假设他们中没有三个是堕落的 ,那就是 – 他们不是在同一个大圆圈上,但是这不太可能),你可以在它们之间创建四个面,每次添加新的点,你可以把它所属的面分成三个子面。

为了纹理的目的,你可以将这些点映射到一个立方体贴图。