我用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);
}
但在某些角度看起来很奇怪......
第二张图片看起来只有1种纯色?
答案 0 :(得分:8)
假设您的圆锥体具有高度h
和半径r
并且其直立(比如其尖端指向+ Y方向),则横向面法线取决于两个角度:圆形地面区域的角度和锥形尖端的角度(我们称之为锥角或α)。该锥角又取决于h
和r
的比率。
观察圆锥体的横截面,我们基本上看到一个直角三角形,其中一个主体的长度为h
,另一个为r
。让我们假设h
cathetus从原点沿Y轴直线上升,r
cathetus沿X轴做同样的事。现在我们想要向外计算hypothenuse点的法线。
在三角形上做一些角度数学我们可以看到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)
的标准化。