平均法线高度场

问题描述

我正在创建高度场,我想创建其法线(面/顶点),我正在使用“三角形”创建网格。我已经计算了GL Quad法线,但是在这里对Triangles而不是Quads感到困惑。 我在互联网上搜索后发现,存在两种类型的法线,例如每个面和每个顶点,但是找不到与我的代码相关的任何帮助。 这是我现在正在创建的高度场。

int average_normal()

{ 
glPushMatrix();


GLfloat xdelta=xsize/xsteps;
GLfloat zdelta=zsize/zsteps;
   
glNormal3f(0,1,0);

for (int x=0; x<xsteps-1; x++)
    for (int z=0; z<zsteps-1; z++)
    {
    
    glBegin(GL_TRIANGLES);
    setMaterialHeight(map[x][z]);
    glNormal3f(0,1);
    glVertex3f(xdelta*x,map[x][z],zdelta*z);
    setMaterialHeight(map[x+1][z]);
    glNormal3f(0,1);
    glVertex3f(xdelta*x+xdelta,map[x+1][z],zdelta*z);
    setMaterialHeight(map[x][z+1]);
    glNormal3f(0,map[x][z+1],zdelta*z+zdelta);   
    glEnd();

    glBegin(GL_TRIANGLES);
    setMaterialHeight(map[x+1][z+1]);
    glNormal3f(0,map[x+1][z+1],zdelta*z+zdelta);  
    setMaterialHeight(map[x][z+1]);
    glNormal3f(0,zdelta*z+zdelta);       
    setMaterialHeight(map[x+1][z]);
    glNormal3f(0,zdelta*z);
    glEnd();
    }
glPopMatrix();
return true;
}

如何计算其正常值?

解决方法

法线向量可以由2个向量中的Cross product计算。创建一个函数,计算叉积并设置法线向量属性:

void set_normal_from_cross_product(
    float x1,float y1,float z1,float x2,float y2,float z2)
{
    float nx = y1*z2 - z1*y2;
    float ny = z1*x2 - x1*z2;
    float nz = x1*y2 - y1*x2;
    float len = sqrt(nx*nx + ny*ny + nz*nz);
    if (len != 0.0f)
        glNormal3f(nx/len,ny/len,nz/len);
}

在网格中,法线向量可以通过相邻顶点之间的向量来计算。写函数,用于计算相邻顶点之间的向量并调用set_normal_from_cross_product

void set_grid_normal(int x,int z)
{
    int prev_x = x > 0 ? x - 1 : x;
    int next_x = x < xsteps - 1 ? x + 1 : x;
    int prev_z = z > 0 ? z - 1 : z;
    int next_z = z < zsteps - 1 ? z + 1 : z;

    set_normal_from_cross_product(
        xdelta * 2,map[next_x][z]-map[prev_x][z],map[x][next_z]-map[x][prev_z],zdelta * 2);
}

使用该函数来设置法线向量:

void set_attributes(int x,int z)
{
    setMaterialHeight(map[x][z]);
    set_grid_normal(x,z);
    glVertex3f(xdelta*x,map[x][z],zdelta*z);
}
for (int x=0; x<xsteps-1; x++)
{
    for (int z=0; z<zsteps-1; z++)
    {
        glBegin(GL_TRIANGLES);
        set_attributes(x,z);
        set_attributes(x+1,z);
        set_attributes(x,z+1);
        glEnd();

        glBegin(GL_TRIANGLES);
        set_attributes(x+1,z+1);
        set_attributes(x,z+1);
        set_attributes(x+1,z);
        glEnd();
    }
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...