我创建了一个锥形 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();
Run Code Online (Sandbox Code Playgroud)
我如何获得表面法线?对于底部我是正确的说正常只是指向下方?
UPDATE
我试过用
for (int angle = 0; angle < 360; angle++) {
glNormal3f(sin(angle), cos(angle), 0);
glVertex3f(sin(angle) * radius, cos(angle) * radius, 0);
}
Run Code Online (Sandbox Code Playgroud)
但从某些角度看它看起来很怪异......


第二张图片看起来只有1个纯色?
假设你的圆锥具有高度h和半径r以及它的直立(比如它的尖端指向+ Y方向),侧面法线取决于两个角度:圆形地面区域的角度和圆锥尖端的角度(我们称之为锥角)或α).反过来这锥角取决于比值h和r.
看着圆锥的横截面,我们看到的基本上是一个直角三角形,其中一个主要有一个长度h,另一个有长度r.让我们假设hcathetus从原点r沿Y轴直线上升,而cathetus沿着X轴做同样的事情.现在我们想要向外计算hypothenuse点的法线.
在三角形上做一些角度数学,我们可以看到hyponetuse的法线有以下形式:
(cos(coneAngle), sin(coneAngle))
Run Code Online (Sandbox Code Playgroud)
同
coneAngle = atan(r / h)
Run Code Online (Sandbox Code Playgroud)
这当然只在2D中,我们需要3D等价物.首先,我们需要XZ平面中的圆的法线.这可以写成
(cos(circleAngle), 0, sin(circleAngle))
Run Code Online (Sandbox Code Playgroud)
现在我们可以将这两个结合到一个正规方程中.我们的斜率法线有一个水平和一个垂直部分.垂直部分直接进入Y坐标,而水平部分直接进入水平方向(X和Z):
(cos(coneAngle) * cos(circleAngle), sin(coneAngle), cos(coneAngle) * sin(circleAngle))
Run Code Online (Sandbox Code Playgroud)
基本上有两个向量:指向锥体尖端的向上向量和水平向量,即由圆形法线生成的向量.这两个向量形成一个基础,我在这里所做的是应用从XY二维空间(锥法线)到圆形法线和向上矢量(Y轴)跨越的空间的线性变换.要进行此转换,您需要将XY空间矢量的分量与其他空间的相应基矢量相乘,并将结果相加,因此您基本上计算:
cos(coneAngle) * (cos(circleAngle), 0, sin(circleAngle)) + sin(coneAngle) * (0, 1, 0)
Run Code Online (Sandbox Code Playgroud)
我只是注意到,hypothenuse正常图像中的两个三角形是相似的,这意味着,可以在没有三角函数的情况下计算法线:给定了相关的长度,c = sqrt(h * h + r * r)我们从三角形的相似性中知道:
n_x / 1 = n_x = h / c
Run Code Online (Sandbox Code Playgroud)
和
n_y / 1 = n_y = r / c
Run Code Online (Sandbox Code Playgroud)
因此,hypothenuse正常是:
1/c * (h, r)
Run Code Online (Sandbox Code Playgroud)
顺便提一下,乘以因子1/c仅仅是矢量的归一化(h, r).