球体模型中缺少顶点

时间:2015-12-18 17:20:02

标签: c++ opengl math graphics 3d

我正在学习OpenGL,我正在创建自己的球体模型。虽然有一些令人费解的结果,但我能画出一个完整的球体。我想知道是否有人可以解释(并可能更正)我的代码。

基本原理:使用从极坐标计算的贝叶斯坐标构建三角形。细分的数量告诉我生成球体点的phi或theta弧度的步骤。从特定点P(phi,theta),我为[phi,delta_phi],[theta,delta_tetha]构建扇区的其他边缘,其中phi从[0,pi](180度)变化,tetha从[0变化,2 * pi](360度)。

这是我提出的代码(我正在使用QT对象,但它应该非常谨慎):

QVector3D polarToCarthesian(float rho, float phi, float theta)
{
    float r = qSin(phi) * rho;
    float y = qCos(phi) * rho;

    float x = r * qSin(theta);
    float z = r * qCos(theta);

    return QVector3D{x, y, z};
}

void make_sector(QVector<QVector3D>& mesh, float phi, float theta, float rho, float deltaPhi, float deltaTheta)
{
    QVector3D p1 = polarToCarthesian(rho, phi, theta);
    QVector3D p2 = polarToCarthesian(rho, phi, theta + deltaTheta);
    QVector3D p3 = polarToCarthesian(rho, phi + deltaPhi, theta);
    QVector3D p4 = polarToCarthesian(rho, phi + deltaPhi, theta + deltaTheta);

    // First Triangle
    mesh.push_back(p1);
    mesh.push_back(p1); // Normal
    mesh.push_back(p3);
    mesh.push_back(p3); // Normal
    mesh.push_back(p2);
    mesh.push_back(p2); // Normal

    // Second Triangle
    mesh.push_back(p2);
    mesh.push_back(p2); // Normal
    mesh.push_back(p3);
    mesh.push_back(p3); // Normal
    mesh.push_back(p4);
    mesh.push_back(p4); // Normal
}

void build_sphere(QVector<QVector3D>& mesh, int ndiv)
{
    const float PHI_MAX = static_cast<float>(M_PI);
    const float THETA_MAX = static_cast<float>(M_PI) * 2;

    const float delta_phi = PHI_MAX / ndiv;
    const float delta_theta = THETA_MAX / ndiv;

    for (int i = 0; i < ndiv; ++i) {
        float phi = i * delta_phi;
        for (int j = 0; j < ndiv; ++j) {
            float theta = j * delta_theta;
            make_sector(mesh, phi, theta, 1.0f, delta_phi, delta_theta);
        }
    }
}

// Then I can generate the sphere with
build_sphere(sphere_mesh, 10);

但是,除非我将phi的迭代从ndiv迭代更改为3 * ndiv次迭代,否则我无法获得完整的范围。我不明白为什么! Phi应该从0到PI变化以覆盖整个Y轴,而Theta从0到2 * pi应该覆盖XZ平面。

有人可以解释发生了什么以及为什么3 * ndiv有效吗?

1 个答案:

答案 0 :(得分:0)

phi应该从-π/ 2到+π/ 2,而不是从0到π:

float phi = i * delta_phi - (M_PI / 2);

此外,您似乎错误地进行了ry计算。您希望r在赤道处最大(phi == 0时)。

认为如果您遇到2 * ndiv,您的代码可能已经有效(虽然产生的多边形数量应该是它应该有的两倍)。实际上,从0到π只会在北半球放置多边形,所以你必须继续超越它,才能在南半球有多边形。

P.S。笛卡儿中没有'h';)