5

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

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

在此处输入图像描述

在此处输入图像描述

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

4

1 回答 1

8

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

查看圆锥的横截面,我们基本上看到一个直角三角形,它的一个导管有长度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)

更新

我刚刚注意到,假设法线图像中的两个三角形是相似的,这意味着,可以在没有三角函数的情况下计算法线: 给定假设的长度,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)

于 2013-10-08T11:29:31.660 回答