6

我必须用较小的均匀分布的球制作一个球体。我认为最佳方法是构建一个基于三角形的测地线球体并将顶点用作我的球的中点。但是我没有编写生成顶点的算法。用 C++ 或伪代码回答会更好。

测地线球体示例:http: //i.stack.imgur.com/iNQfP.png

4

4 回答 4

11

使用@Muckle_ewe 给我的链接,我能够编写以下算法:main()

class Vector3d {  // this is a pretty standard vector class
public:
    double x, y, z;
    ...
}

void subdivide(const Vector3d &v1, const Vector3d &v2, const Vector3d &v3, vector<Vector3d> &sphere_points, const unsigned int depth) {
    if(depth == 0) {
        sphere_points.push_back(v1);
        sphere_points.push_back(v2);
        sphere_points.push_back(v3);
        return;
    }
    const Vector3d v12 = (v1 + v2).norm();
    const Vector3d v23 = (v2 + v3).norm();
    const Vector3d v31 = (v3 + v1).norm();
    subdivide(v1, v12, v31, sphere_points, depth - 1);
    subdivide(v2, v23, v12, sphere_points, depth - 1);
    subdivide(v3, v31, v23, sphere_points, depth - 1);
    subdivide(v12, v23, v31, sphere_points, depth - 1);
}

void initialize_sphere(vector<Vector3d> &sphere_points, const unsigned int depth) {
    const double X = 0.525731112119133606;
    const double Z = 0.850650808352039932;
    const Vector3d vdata[12] = {
        {-X, 0.0, Z}, { X, 0.0, Z }, { -X, 0.0, -Z }, { X, 0.0, -Z },
        { 0.0, Z, X }, { 0.0, Z, -X }, { 0.0, -Z, X }, { 0.0, -Z, -X },
        { Z, X, 0.0 }, { -Z, X, 0.0 }, { Z, -X, 0.0 }, { -Z, -X, 0.0 }
    };
    int tindices[20][3] = {
        {0, 4, 1}, { 0, 9, 4 }, { 9, 5, 4 }, { 4, 5, 8 }, { 4, 8, 1 },
        { 8, 10, 1 }, { 8, 3, 10 }, { 5, 3, 8 }, { 5, 2, 3 }, { 2, 7, 3 },
        { 7, 10, 3 }, { 7, 6, 10 }, { 7, 11, 6 }, { 11, 0, 6 }, { 0, 1, 6 },
        { 6, 1, 10 }, { 9, 0, 11 }, { 9, 11, 2 }, { 9, 2, 5 }, { 7, 2, 11 }
    };
    for(int i = 0; i < 20; i++)
        subdivide(vdata[tindices[i][0]], vdata[tindices[i][1]], vdata[tindices[i][2]], sphere_points, depth);
}

然后在main()

vector<Vector3d> sphere_points;
initialize_sphere(sphere_points, DEPTH);  // where DEPTH should be the subdivision depth
for(const Vector3d &point : sphere_points)
    const Vector3d point_tmp = point * RADIUS + CENTER;  // Then for the sphere I want to draw, I  iterate over all the precomputed sphere points and with a linear function translate the sphere to its CENTER and chose the proper RADIUS

实际上,您只需要使用initialize_sphere()一次并将结果用于您要绘制的每个球体。

于 2013-07-22T18:59:14.877 回答
2

我以前为一个图形项目做过这个,我使用的算法在这个网站上有详细说明

http://www.opengl.org.ru/docs/pg/0208.html

忽略任何openGL绘图调用,只编写处理创建实际顶点的部分

于 2013-07-17T17:03:38.873 回答
1

有众所周知的对表面进行三角剖分的算法。如果您不想自己编写其中一个网格,您应该能够使用GNU Triangulated Surface Library生成合适的网格。

于 2013-07-17T16:58:36.880 回答
0

这取决于您希望球体具有的三角形数量。您可能拥有无限的分辨率。

首先专注于创建一个圆顶,稍后您可以通过获取上圆顶的负坐标来将其加倍。您将通过互锁三角形行来生成球体。你的三角形是等边的,所以决定一个长度。将 2(pi)r 除以您希望位于圆顶底行的三角形数量。这将是每个三角形每一边的长度。

接下来,您需要创建一个与球体表面相交的同心圆。在这个圆圈和圆顶底部之间将是你的第一行。您将需要找到每个三角形倾斜的角度。(我稍后会在我弄清楚这一点时发布)

对每个同心圆(生成行)重复该过程,直到行的高度 * 行数大约等于您开始时的 2(pi)r。

如果有机会,我会尝试稍后对其进行编程。您也可以尝试在数学论坛上发帖。

于 2013-07-17T17:05:26.980 回答