圆锥的OpenGL / GLUT曲面法线

时间:2013-10-08 10:34:50

标签: c++ opengl glut

我用GL_TRIANGLE_FAN

创建了一个圆锥体
// draw the upper part of the cone
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0, 0, height);
for (int angle = 0; angle < 360; angle++) {
    glVertex3f(sin(angle) * radius, cos(angle) * radius, 0);
}
glEnd();

// draw the base of the cone
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0, 0, 0);
for (int angle = 0; angle < 360; angle++) {
    // normal is just pointing down
    glNormal3f(0, -1, 0);
    glVertex3f(sin(angle) * radius, cos(angle) * radius, 0);
}
glEnd();

如何获得表面法线?对于底部我是正确的说正常只是指向下方?

更新

我尝试使用

for (int angle = 0; angle < 360; angle++) {
    glNormal3f(sin(angle), cos(angle), 0);
    glVertex3f(sin(angle) * radius, cos(angle) * radius, 0);
}

但在某些角度看起来很奇怪......

enter image description here

enter image description here

第二张图片看起来只有1种纯色?

1 个答案:

答案 0 :(得分:8)

假设您的圆锥体具有高度h和半径r并且其直立(比如其尖端指向+ Y方向),则横向面法线取决于两个角度:圆形地面区域的角度和锥形尖端的角度(我们称之为锥角或α)。该锥角又取决于hr的比率。

观察圆锥体的横截面,我们基本上看到一个直角三角形,其中一个主体的长度为h,另一个为r。让我们假设h cathetus从原点沿Y轴直线上升,r cathetus沿X轴做同样的事。现在我们想要向外计算hypothenuse点的法线。

Angle proof and normal coordinates

在三角形上做一些角度数学我们可以看到hyponetuse的法线有以下形式:

(cos(coneAngle), sin(coneAngle))

coneAngle = atan(r / h)

这当然只在2D中,我们需要3D等效物。 首先,我们需要XZ平面中的圆的法线。 这可以写成

(cos(circleAngle), 0, sin(circleAngle))

现在我们可以将这两个结合到一个正规方程中。我们的斜率法线有一个水平和一个垂直部分。垂直部分直接进入Y坐标,而水平部分有助于水平方向(X和Z):

(cos(coneAngle) * cos(circleAngle), sin(coneAngle), cos(coneAngle) * sin(circleAngle))

基本上有两个向量:向上矢量指向锥体的尖端,水平向量是由圆形法线生成的向量。这两个向量形成一个基础,我在这里所做的是应用从XY二维空间(锥法线)到圆形法线和向上矢量(Y轴)跨越的空间的线性变换。要进行此转换,您可以将XY空间矢量的分量与其他空间的相应基矢量相乘,并将结果相加,因此您基本上计算:

cos(coneAngle) * (cos(circleAngle), 0, sin(circleAngle)) + sin(coneAngle) * (0, 1, 0)

更新

我刚注意到,hypothenuse正常图像中的两个三角形是相似的,这意味着,可以计算没有三角函数的法线: 鉴于连字符c = sqrt(h * h + r * r)的长度,我们从三角形的相似性中知道:

n_x / 1 = n_x = h / c

n_y / 1 = n_y = r / c

因此,hypothenuse normal是:

1/c * (h, r)

顺便说一下,乘以因子1/c仅仅是向量(h, r)的标准化。