一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

一种基于OpenGL的多系统三维模型表面积计算方法与流程

2022-07-16 18:53:08 来源:中国专利 TAG:

一种基于opengl的多系统三维模型表面积计算方法
技术领域
1.本发明属于计算机图形技术领域,涉及一种基于opengl的多系统三维模型表面积计算方法。


背景技术:

2.在空间航天器在轨运行期间、航空器在大气层飞行期间、火箭或导弹升空及飞行期间、地面轨道列车或车辆行驶期间等诸多场景中,需要考虑目标所受环境的各种影响,例如外热流、空间碎片、风阻等,严重制约着目标性能发挥、安全运行以及寿命等各个方面,为评估目标所受影响大小必须要知道其外露表面积。而实际情况是上述目标通常形状复杂不规则,且各分系统通常由于材料组成不同、性能参数不同、位置不同等需要对各分系统进行逐一分析,而各分系统间存在相互遮挡的问题,导致各分系统外露表面积的计算难度较大,无法分别对目标各分系统进行准确评估。现有方法通常是利用商用三维建模软件对某一具体模型进行具体分析,对于暴露表面积通常是手动划分进行计算,即将模型各分系统细分成不同大小的网格或面片,通过人眼主观判别的方法,判断分系统哪些部分受到遮挡,然后用鼠标操作将各分系统被遮挡的网格部分进行手动剔除,然后再根据网格大小和数量计算表面积。上述方法有一定的主观性,不仅准确率无法保证,且效率较低、不具有通用性。因此需要构建一种针对多系统三维模型表面积计算模型通用的自动化的计算方法。


技术实现要素:

3.本发明的目的在于提供一种基于opengl的多系统三维模型表面积计算方法,解决现有多系统三维模型表面积计算过程复杂且不具有通用性的问题。
4.有鉴于此,本发明提供一种基于opengl的多系统三维模型表面积计算方法,其特征在于,包括:
5.步骤一:导入或基于opengl构建多系统三维模型,进行位移、旋转、缩放操作并构建模型矩阵;
6.步骤二:以目标系统为中心,以随机均匀分布的方式形成一个观察位置球面,构建某一随机观察位置的观察矩阵;
7.步骤三:遍历三维模型的所有分系统,找到三个方向坐标的最大值和最小值,作为裁剪空间边界,生成正射投影矩阵;
8.步骤四:传入所述模型矩阵、所述观察矩阵和所述投影矩阵,开展深度测试,目标分系统暴露部分将通过测试,被其他分系统遮挡的部分测试将不通过;
9.步骤五:将观察方向上获取的表面暴露信息生成2d纹理;
10.步骤六:遍历三维模型的每个分系统,重复步骤四-步骤五,生成每个分系统暴露表面的纹理贴图;
11.步骤七:重复步骤二到步骤六,完成多次循环,将绘制的纹理内容叠加,生成各分系统完整的表面分布;
12.步骤八:将分系统表面三角形面片面积加和,依据步骤七生成的纹理,被遮挡部分被剔除,得到各分系统暴露表面积。
13.进一步地,步骤一还包括:
14.构建多系统三维模型包括顶点坐标、uv坐标、法向量坐标、面片信息;
15.使用gl_triangles将所有的点装配成三角形的图元形状,然后创建用于渲染三角形的片段着色器。
16.进一步地,步骤二还包括:采用theta=pi*t(rd)函数生成一个定义域为(0,2π)的弧度值,使得生成的随机值覆盖全角度。
17.进一步地,步骤三还包括:采用glm::min/glm::max比较的方法,遍历目标分系统所有顶点坐标。
18.进一步地,步骤四还包括:将所述模型矩阵、观察矩阵、投影矩阵按照投影矩阵*观察矩阵*模型矩阵的顺序相乘,传入着色器中。
19.进一步地,步骤五还包括:使用单色的纹理,长宽设置为2048。
20.进一步地,步骤七还包括:将循环次数设置为1000次。
21.进一步地,步骤八还包括:提取目标分系统三角形顶点坐标值并使用偏导数dfdxfine/dfdyfine求取叉积得到三角形面片法向量。
22.本发明实现了以下显著的有益效果:
23.实现简单,包括:构建多系统三维模型,构建某观察角度上的观察矩阵和投影矩阵,对目标分系统开展深度测试,丢弃被其他分系统遮挡的像素,形成该角度的分系统表面分布纹理贴图,重复上述步骤形成随机均匀分布的多观察角度的纹理,叠加形成目标分系统的全角度暴露表面分布纹理,并依据该纹理完成表面积计算,最后遍历所有分系统获得各分系统的暴露表面积。相较于单一模型具体分析的情况,通过该方法可以快速计算出三维模型各分系统的外露表面积,具有极高的准确性。本发明可以构建导入任意形状的三维模型,且对于多系统三维模型,不需要手动划分,能够自动准确判别各分系统之间遮挡的位置关系,计算模型各个分系统暴露位置的表面积,计算结果精度较高,具有较好的推广性。
附图说明
24.图1为本发明的一种基于opengl的多系统三维模型表面积计算方法的流程图;
25.图2为本发明实施例的多系统三维模型示意图;
26.图3为本发明多系统三维模型示例在opengl显示图;
27.图4为本发明三维模型各分系统循环前表面分布纹理图;
28.图5为本发明三维模型各分系统循环后表面分布纹理图。
具体实施方式
29.以下结合附图和具体实施例对本发明作进一步详细说明,根据下面说明和权利要求书,本发明的优点和特征将更清楚。需要说明的是,附图均采用非常简化的形式且均适用非精准的比例,仅用以方便、明晰地辅助说明本发明实施例的目的。
30.需要说明的是,为了清楚地说明本发明的内容,本发明特举多个实施例以进一步阐释本发明的不同实现方式,其中,该多个实施例是列举式而非穷举式。此外,为了说明的
简洁,前实施例中已提及的内容往往在后实施例中予以省略,因此,后实施例中未提及的内容可相应参考前实施例。
31.虽然该发明可以以多种形式的修改和替换来扩展,说明书中也列出了一些具体的实施图例并进行详细阐述。应当理解的是,发明者的出发点不是将该发明限于所阐述的特定实施例,正相反,发明者的出发点在于保护所有给予由本权利声明定义的精神或范围内进行的改进、等效替换和修改。同样的元模块件号码可能被用于所有附图以代表相同的或类似的部分。
32.请参阅图1,本发明的一种基于opengl的多系统三维模型表面积计算方法,包括:
33.步骤一:构建三维模型。构建三维模型的方法有多种,表面构型复杂的几何体可以通过商用软件如3dsmax、blender等构建,并将构建好的模型导入到opengl中,一些简单的几何体如长方体、圆柱、球体等可以在opengl中直接构建,这些几何体可以通过坐标变换、旋转、缩放等操作构建成为多系统的三维模型,注意构建模型应包括必要的信息如顶点坐标、uv坐标、法向量坐标、面片信息等。
34.步骤二:创建观察矩阵。在opengl中,使用观察矩阵将世界空间转换为观察空间,在这里需要处理观察位置和目标位置的关系。观察位置和目标位置是相对的,在本发明中设置目标分系统位置坐标为原点,从不同的观察位置来观察目标分系统的暴露或遮挡位置关系。从某单一观察方向是无法获取到目标分系统全部暴露表面积信息的,因此必须从尽可能多且覆盖尽可能全面的角度完成观察,在本发明中使用球面分布函数进行解决:所有观察位置将形成一个以目标位置为球心的球面,在球面上的观察位置是随机均匀分布的。
35.步骤三:创建正射投影矩阵。投影矩阵决定了观察窗(也叫平截头体)的大小,在这空间外的顶点都会被裁剪掉,利用该矩阵定义的平截头体需要将整个三维模型都包含其中,因此在这里需要遍历三维模型的所有分系统,找到三个方向坐标的最大值和最小值,作为裁剪空间的宽、高和长度边界。
36.步骤四:完成深度测试。观察矩阵和投影矩阵创建好之后,需要明确在该观察方向上目标分系统是否有被其他分系统遮挡,因此需要比较各分系统的深度信息。在创建好的观察方向上,当目标分系统的某些部分被其他分系统遮挡,说明其他分系统深度值比目标分系统被遮挡部分的深度值更小,那么深度测试将会不通过,目标分系统被遮挡的这些像素则会被丢弃。
37.步骤五:生成纹理。为便于表面积计算,在本发明中将各分系统目标暴露表面生成纹理贴图,即在剔除深度测试未通过部分后目标分系统uv坐标的展开。生成的纹理为2d贴图,提取深度测试结果作为每个顶点的纹理值,因此也可以认为是深度测试的可视化。被遮挡的部分,即在步骤四中深度测试未通过的部分纹理值为0,因此该部分将不会显示在贴图中,这样就生产了一幅目标分系统暴露表面积分布图。
38.步骤六:遍历三维模型的每个分系统,重复步骤四-步骤五,生成每个分系统暴露表面的纹理贴图。
39.步骤七:从更多方向上完成观察。仅从一个方向上观察生成的纹理是不能获取到完整的表面积信息的,因此需要从尽可能多的方向上完成观察。由于在步骤二中生成的观察方向是随机均匀分布的,因此只需要重复步骤二到步骤五,即完成多次循环,每次循环都会生成一个新的随机观察方向。循环的次数是可以设定的,设置次数越高,观察方向能覆盖
尽可能全面的角度,相当于以目标为中心形成了一个均匀覆盖的观察球面,计算结果精度也就越高。每次循环都将绘制一幅纹理,在这里将其与前次绘制的内容直接叠加,可以理解为对新观察到的内容进行不断的补充,循环完成后,将产生一幅目标分系统完整的表面分布图。
40.步骤八:面积计算。在opengl中,片段最小存储单元是三角形面片,计算目标分系统uv贴图中每个三角形面片的面积,剔除被遮挡部分的三角形面片,将面积直接相加即可得到每个分系统暴露表面积总和。
41.作为具体的实施例,本发明提供的基于opengl的多系统三维模型表面积计算方法流程,以c 编程语言为例,包括以下步骤:
42.步骤一:构建三维模型。通过商用软件如3dsmax等构建三维几何体模型,并将其保存为obj格式并导入opengl中,注意模型应包括顶点坐标(v)、uv坐标(vt)、法向量坐标(vn)、面片信息(f)。数据读取完成后,首先创建顶点着色器来完成对模型的进一步处理,该操作包括缩放、旋转、位移等,实现的方式为:
43.m=glm::scale(m,scale);
44.m=glm::mat4_cast(glm::quat(radians(rotate)))*m;
45.m=glm::translate(m,translation);
46.最后得到一个模型矩阵m,将模型数据与顶点数据相乘,并赋值给gl_position变量,gl_position是opengl中预定义的变量,该值在幕后代表了顶点着色器的输出。在opengl中,绘制图元包括gl_points、gl_lines、gl_triangles、gl_quads等方式,即分别代表绘制点、线、三角形、四边形等,在本发明中,使用三角形面片计算表面积,因此使用gldrawarrays(gl_triangles,0,positionsize())函数,从顶点数据的第一个数据开始(即起始索引为0),每三个顶点绘制成一个三角形,需要将所有顶点数组全部完成绘制,因此使用positionsize()获取三维模型导入的顶点数量,这样就完成了图元形状的装配。然后,创建用于渲染三角形的片段着色器,为使三维模型展示出更好的可视化效果,在本发明中,增加一个漫反射分量,将三角形面片法向量与光源位置向量进行点乘(dot)计算光源对片段漫反射的影响,即result=max(0,dot(fs_in.normal,-fs_in.fragpos))*lightcolor*objectcolor;其中fs_in.normal为传入的三角形面片的法向量,-fs_in.fragpos为光源位置,默认为(0,0,0),lightcolor和objectcolor分别为光照颜色和物体颜色,可自定义设置rgb各分量的大小来获得需要的颜色,将得到的结果传给fragcolor,即opengl预定义的代表最终输出颜色的变量。编译后把顶点和片段着色器链接为一个着色器程序对象并激活,即完成了三维模型的构建并显示在界面中。
47.步骤二:创建观察矩阵。在opengl中,使用lookat函数把世界坐标转换为观察矩阵,将目标模型的世界坐标设置为glm::vec3(0,0,0),观察位置为围绕目标模型的随机均匀分布的球面函数,在c 中定义一个std::random_device随机数类型的变量rd,然后生成一个容器uniform_real_distribution《float》urd(0,2),里面存放的是(0,2)之间均匀分布的随机数,返回urd(rd)值即可获得一个随机数值。使用theta=pi*urd(rd)(rd)函数即可生成一个随机弧度值,值域即为(0,2π),可确保生成的随机值可以覆盖全角度,同理可生成另一个名为phi的弧度值。那么观察位置向量forward=normalize(glm::vec3{cos(theta)*sin(phi),sin(theta)*sin(phi),cos(phi)}),最终得到观察矩阵v=glm::
lookat(glm::vec3(0),forward,glm::vec3(0,1,0)),这样就生成了一个随机的观察位置。
48.步骤三:创建正射投影矩阵。在opengl中,使用glm::ortho函数创建一个正射投影矩阵将观察坐标变换为裁剪坐标,该函数是opengl中的内置函数,定义了一个裁剪空间,为保证构建的三维模型全部处于裁剪空间内部,需要找到三维模型在x、y、z三个方向上的坐标最大值和坐标最小值。提取三维模型的所有顶点坐标数据,使用函数maxx=glm::max(maxx,model.x),其中model.x为顶点坐标在x方向的分量,maxx定义为三维模型在x方向上的最大值,遍历所有顶点坐标并执行上述函数即完成了比较与maxx值的更新。同理,即可获得在三个方向上的最大值和最小值minz、maxz、minx、maxx、miny、maxy,为保证裁剪空间对三维模型的完全包含,在上述值的基础上再扩展0.1f,最终得到投影矩阵p=glm::ortho(minx-0.1f,maxx 0.1f,miny-0.1f,maxy 0.1f,minz-0.1f,maxz 0.1f)。
49.步骤四:完成深度测试。在这里需要对模型每个分系统受遮挡部分进行单独分析,因此使用for(auto&m:models)循环函数遍历各分系统,其中models是存储各分系统的容器,将前述步骤中创建的模型矩阵m、某一随机方向上的观察矩阵v、投影矩阵p按照p*v*m的顺序相乘,传入着色器中,在opengl中将会完成该观察方向上的透视除法和裁剪。在opengl中,模型每个面片都储存了深度缓冲值(gl_depth_buffer_bit),由于深度测试(gl_depth_test)默认是禁用的,因此需要使用glenable(gl_depth_test)函数开启深度测试。深度测试由opengl自动计算,在该观察方向上,当目标分系统某些片段没有受到任何遮挡,深度测试通过,该片段的深度值则更新到深度缓冲中;当有其他分系统遮挡了目标分系统的某些部分,说明其他分系统深度值比目标分系统被遮挡部分的深度值更小,那么深度测试将会不通过,目标分系统被遮挡的这些像素则会自动被丢弃。深度测试完成后,在下次渲染之前使用glclear(gl_depth_buffer_bit)将本次写入的深度值清除。
50.步骤五:生成纹理。将上述步骤中完成深度测试的模型表面创建纹理,在opengl中使用gltexsubimage2d(gl_texture_2d,0,0,0,2048,2048,gl_red,gl_false,0)将观察到的模型表面情况生成2d纹理,长宽设置为2048以保证纹理的精度,由于仅为计算表面积用,使用单色即可(在本发明中使用的是gl_red,即红色)。被遮挡的部分,即在步骤四中深度测试未通过的面片纹理值为0,因此该部分将不会显示在贴图中。这样就生产了一幅目标分系统暴露表面积分布图。
51.步骤六:遍历三维模型的每个分系统,重复步骤四-步骤五,生成每个分系统暴露表面的纹理贴图。
52.步骤七:从更多方向上完成观察。在本发明中,为使计算结果精度尽可能高,设置循环1000次,保证观察方向能覆盖尽可能全面的角度,每次循环都将绘制一幅纹理,然后使用颜色混合函数glblendfunc(gl_one,gl_one)将其与前次绘制的内容叠加,其中gl_one表示本次绘制纹理和上次绘制的纹理均使用全部颜色值(即使用因子为1.0)参与叠加。如果在某一观察方向上被丢弃的片段在另一观察方向没有被丢弃,说明该片段仍然是目标的外露表面,那么在纹理叠加的过程中就会得到补充;如果在所有观察方向上某片段都被丢弃,那么该片段即判断为被其他分系统遮挡,叠加后其纹理值依旧为0。循环完成后生成目标分系统完整的表面分布图。
53.步骤八:面积计算。在本发明中,模型表面被划分成了三角形面片,利用面片顶点坐标值,在本发明中用triangle.position表示,使用dx=dfdxfine(triangle.worldpos)
和dy=dfdyfine(triangle.worldpos)公式得到三角形两个方向向量,使用cross(dx,dy)即得到三角形的法向量,三角形面积为法向量模的一半,即area=0.5*length(cross(dx,dy))。同时,使用step函数得到一个系数coef=step(0.01,texture.r),函数第一个参数为一个边界值,第二个参数为三角形面片的纹理值,目标分系统被遮挡的部分纹理值为0,系数coef的返回值为0(0《0.01),当目标分系统没有被遮挡,系数coef的返回值为1。将三角形面积area与系数coef相乘,那么被遮挡的三角形面积变为0,未被遮挡的面积值保留。最后遍历计算所有三角形并完成加和,即可得到每个分系统的暴露表面积值。
54.试验
55.图2示出了一个卫星三维模型示例,下面结合该示例对本发明的一种基于opengl的多系统三维模型表面积计算方法进行试验验证。
56.步骤一:构建三维模型。图2示出的三维模型由3dsmax软件构建,将其保存为obj格式并导入到opengl中,模型包含了顶点坐标(v)、uv坐标(vt)、法向量坐标(vn)和面片信息(f)。在本实施例中,为真实对比表面积计算结果的准确性,对三维模型不再进行任何的缩放、旋转和位移等操作,因此三维模型各分系统缩放量均设置为(1,1,1),旋转量均设置为(1,1,1),位移量均设置为(0,0,0),设置完成后,在opengl后台将自动完成赋值和三角形图元装配,为使本实施例解释更加清晰,在这里给出最终得到的模型矩阵为:
[0057][0058]
同时,设置光照颜色为(0.2,0.2,0.2),设置物体颜色为(1,1,1),则在opengl中三维模型显示为一个深灰色的效果,见图3所示。公开资料显示,该卫星由平台主体、相机载荷、通信载荷、数传天线、太阳电池阵、热控等多个分系统组成,在本实施例中,针对其中四个分系统进行重点分析,即分系统1代表卫星平台,分系统2代表相机载荷,分系统3代表数传天线,分系统4代表通信载荷。
[0059]
步骤二:创建观察矩阵。在本实施例中,将三维模型分系统1的中心位置坐标设置为(0,0,0),观察位置为围绕目标模型的随机均匀分布的球面函数,随机数为c 自动生成,注意每次生成值均不同,为使本实施解释更加清晰,在这里示出一个随机生成值为1.107,则观察位置向量forward=(-0.405,-0.141,0.904),最终得到该观察观察矩阵v=glm::lookat((0,0,0),(-0.405,-0.141,0.904),(0,1,0))。
[0060]
步骤三:创建正射投影矩阵。该矩阵为opengl自动生成,在步骤二中生成的观察矩阵的基础上,三维模型投影矩阵p=glm::ortho(-4.470,4.488,-8.614,8.685,-2.956,2.837)。
[0061]
步骤四:完成深度测试。对每个分系统进行单独分析,在测试前,为使本实施例解释更加清晰,图4首先给出各分系统未被其他分系统影响时的表面展开图。接下来将步骤一至步骤三中创建的模型矩阵m、某一随机方向上的观察矩阵v、投影矩阵p按照p*v*m的顺序相乘,传入着色器中完成该观察方向上的透视除法和裁剪,使用glenable(gl_depth_test)函数开启深度测试,由opengl自动计算完成。
[0062]
步骤五:生成纹理。将上述步骤中完成深度测试的模型表面创建纹理,在该观察方向上深度测试不通过的部分面片纹理值为0,将不会显示在贴图中,注意生成的纹理为某一
观察方向上的表面展开,需要多次循环后才能生成准确的纹理贴图。
[0063]
步骤六:遍历三维模型的每个分系统,重复步骤四-步骤五,生成每个分系统暴露表面的纹理贴图。
[0064]
步骤七:从更多方向上完成观察。设置循环次数1000次,并将纹理值进行叠加,得到各分系统最终的纹理贴图,见图5所示。将图3与图5进行对比发现,对于分系统1,即平台主体,在 z方向上布设有数传天线和相机载荷,因此有两部分被遮挡;在-z方向上与过渡段相连接,因此该部分也被遮挡;在-y方向上布设有较大面积的散热面,因此该部分被遮挡。对于分系统2,即相机载荷,在 z方向上布设有相机镜头,因此该部分被遮挡;同时相机是部分嵌入进平台主体内部,因此-z方向以及部分侧边全部被遮挡。对于分系统3,即数传天线,该天线为圆形双抛物面形状,中间部分区域被馈源遮挡。对于分系统4,即通信载荷,该载荷为椭圆形单抛物面形状,独立在星体外,未受其他分系统影响。
[0065]
步骤八:面积计算。在生成纹理贴图后,采用三角形表面积计算方法在后台自动完成计算并给出各分系统暴露表面积。表1给出本实施例研究的四个分系统表面积公开资料值和计算结果的对比。需要特别说明的是,资料值由于有效数字位数较少,自身也存在一定误差。
[0066]
表1三维模型各分系统表面积资料值和计算结果对比
[0067] 资料值(m2)计算结果(m2)误差分系统118.218.2310.17%分系统20.60.6020.33%分系统31.01.0010.10%分系统45.55.5000.00%
[0068]
由表1可知,各分系统误差控制在0.33%以内,说明采用本发明提供的方法,在计算多系统表面积上具有较高的准确性和可靠性。
[0069]
从以上描述中,可以看出,本技术上述的实施例实现了如下的技术效果:
[0070]
实现简单,包括:构建多系统三维模型,构建某观察角度上的观察矩阵和投影矩阵,对目标分系统开展深度测试,丢弃被其他分系统遮挡的像素,形成该角度的分系统表面分布纹理贴图,重复上述步骤形成随机均匀分布的多观察角度的纹理,叠加形成目标分系统的全角度暴露表面分布纹理,并依据该纹理完成表面积计算,最后遍历所有分系统获得各分系统的暴露表面积。相较于单一模型具体分析的情况,通过该方法可以快速计算出三维模型各分系统的外露表面积,具有极高的准确性。本发明可以构建导入任意形状的三维模型,且对于多系统三维模型,不需要手动划分,能够自动准确判别各分系统之间遮挡的位置关系,计算模型各个分系统暴露位置的表面积,计算结果精度较高,具有较好的推广性。
[0071]
根据本发明技术方案和构思,还可以有其他任何合适的改动。对于本领域普通技术人员来说,所有这些替换、调整和改进都应属于本发明所附权利要求的保护范围。
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献