OpenGL/GLUT 圆锥表面法线

Posted

技术标签:

【中文标题】OpenGL/GLUT 圆锥表面法线【英文标题】:OpenGL/GLUT surface normals of cone 【发布时间】:2013-10-08 10:34:50 【问题描述】:

我用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);

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

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

【问题讨论】:

这个问题可能会有所帮助:***.com/questions/12128129/smooth-cone-normals 您的地幔正常需要(sin, 0, cos),因为“向上”部分(Y 坐标)不会改变。但是,Y 坐标(以及其他两个坐标)取决于锥体斜度的角度,因此它更像(cos(slopeAngle) * sin(angle), sin(slopeAngle), cos(slopeAngle) * cos(angle)) @Nobody,斗篷在哪里? @JiewMeng:嗯,这是翻译错误。我只知道德语术语(Mantelfläche)。我的意思是不是底部的圆锥面。正确的词可能是侧面。 附带说明:不要忘记为圆锥的尖端设置正确的法线。由于它在所有三角形中都有贡献,因此它应该笔直向上。 【参考方案1】:

假设你的圆锥体有高度h 和半径r 并且它是站立的(比如它的尖端指向+Y方向)侧面法线取决于两个角度:圆形地面区域的角度和角度圆锥的尖端(我们称之为圆锥角或α)。这个锥角又取决于hr 的比率。

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

对三角形进行一些角度数学运算,我们可以看到斜线的法线具有以下形式:

(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 2D 空间的线性变换应用到由圆法线和向上向量(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

因此,假设正态为:

1/c * (h, r)

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

【讨论】:

感谢您非常详细的解释。有两件事我完全不明白。通过圆角,我相信它是代码中的angle 变量?还有,在最后一步,结合法线,为什么要相乘(不是我知道另一种方法,只是想了解为什么使用它)? 是的circleAngle 就像你的angle。至于第二个:我已经更新了我的答案以给出解释(因为它不适合评论)。 抱歉,我不太明白为什么“水平部分对水平方向(X 和 Z)都有贡献”,我认为这对最后一个术语 cos(coneAngle) * sin(circleAngle) 有贡献。在我看来,那个向量只有 XY 值? Z轴的贡献是怎么来的? 正如我已经解释过的,2D 圆锥法线(或更好的斜边法线)的 2 个坐标是每个基向量的因子。这两个向量是圆法线(cos(circleAngle), 0, sin(circleAngle)) 和上向量(0, 1, 0)。将向量乘以一个因子会将所有分量乘以该因子。也许这个wikipedia article 会帮助你。 法线起作用,但似乎它们遵循表面。我有一个球体(代码主要来自讲师),无论我如何旋转它,它的左侧都有突出显示。但是对于像我们讨论过的具有平滑阴影的圆锥体,它遵循圆锥体的表面。见screenr.com/yTqH

以上是关于OpenGL/GLUT 圆锥表面法线的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 一个OpenGL / GLUT代码模板。用于OpenGL / GLUT源代码的代码模板

重新计算规则网格表面的法线 (C++/OpenGL)

Opengl-法线贴图(用来细化表面的表现表现的凹凸)

OpenGL/Glut 无法在其上绘制 [

OpenGL、GLUT、Cygwin - 无法打开显示“”

推荐的 OpenGL / GLUT 参考 [关闭]