当前位置:网站首页>Polygon 3D(三维平面多边形)的法向量的计算(MeshLab默认的计算)
Polygon 3D(三维平面多边形)的法向量的计算(MeshLab默认的计算)
2022-07-30 05:49:00 【夕阳染色的坡道】
目的:网格法向量的计算
最近发现一个非常有意思的东西,网上的资料较少,所以记下来供大家查阅,
就是在网格化三维polygon 3d的时候,对于polygon 3d的法向量和网格化为三角形的时候。生成obj文件的时候三角面片的方向只和三角形的顶点顺序有关。如果三角面片上进行顶点的normal设置,可能毫无效果。在meshlab中只和顶点的顺序有关。polygon 3d的法向量和三角面片的法向量一致。
三角面片的法向量:
测试它是左手坐标系还是右手坐标系生成的法向量?从顶点的顺序(也是半面结构)来看它是左手坐标系生成的法向量。
为了测试我们要了解向量叉乘的几何意义,如果左乘的话,它是右手坐标系下做的(可以这样规定)。它的几何意义如下:
可以看出来,在 a × b a × b a×b 是左乘的角度可以看出来,右手坐标系,从 a a a到 b b b的方向。
对于三角形的面片的方向,可能不一样。它规定了一个顺序。如果 p 0 , p 1 , p 2 p0, p1, p2 p0,p1,p2三个顶点的顺序,然后我们需要计算它是哪个方向为主。需要看一下方向。在测试的途中,
v 0.0 0.0 0.0
v 0.0 1.0 0.0
v 1.0 0.0 0.0
f 3 2 1
从这个可以看到,
p 0 = ( 1 , 0 , 0 ) ; p 1 = ( 0 , 1 , 0 ) ; p 3 = ( 0 , 0 , 0 ) p0=(1,0,0); p1=(0,1,0); p3=(0,0,0) p0=(1,0,0);p1=(0,1,0);p3=(0,0,0),它的顺序,
可以得到normal =(0,0,1),
如果从顶点的顺序来看的话。
它是典型的左手坐标系。如果用数学中的向量来算的话,可能需要改变一下思路,需要计算两个向量的叉乘。会得到 a = ( p 1 − p 0 ) ; b = ( p 2 − p 0 ) a=(p1 - p0); b = (p2-p0) a=(p1−p0);b=(p2−p0),然后叉乘 a × b a × b a×b可以得到。就是那种从它其实和逻辑是自洽的,因为我们如果用 ( p 1 − p 0 ) × ( p 2 − p 1 ) (p1-p0)×(p2-p1) (p1−p0)×(p2−p1)这个不是三角形的夹角,而是180-夹角,。所以叉乘可能需要变化一下,对夹角的计算。代码如下:
Eigen::Vector3f GetNormalFrom3Points(Eigen::Vector3f& a, Eigen::Vector3f& b, Eigen::Vector3f& c)
{
Eigen::Vector3f e1 = b - a;
Eigen::Vector3f e2 = c - a;
Eigen::Vector3f e1_(e1.x, e1.y, e1.z), e2_(e2.x, e2.y, e2.z);
Eigen::Vector3f normal = e1.cross(e2);
if (normal.norm() < 0.0001) {
//如果太小了,可以返回(0,0,0)
#ifdef LIULINGFEI
printf("result = %f, %f, %f\n", 0, 0, 0);
#endif
return Eigen::Vector3f(0, 0, 0);
}
else {
Eigen::Vector3f temp = normal.normalized();
#ifdef LIULINGFEI
printf("result = %f, %f, %f\n", temp(0), temp(1), temp(2));
#endif
return normal.normalized();
}
}
网上可能对于三角面片的法向量有一些资料,但是对于polygon 面片的法向量可能需要一些,可能不一样。它需要对每一个顶点计算法向量(邻近的顶点构成三角形,然后计算这个三角形的法向量然后计算这个顶点的反向量),然后区平均值。但是也可以计算polygon的法向量了。代码如下:
Eigen::Vector3f GetPolygonNormalFrom3Points(std::vector<Eigen::Vector3f>& poly_pnts)
{
Eigen::Vector3f sum(0,0,0);
for(int i = 0; i < poly_pnts.size(); ++i)
{
Eigen::Vector3f pre_pnt = poly_pnts[(i-1)%poly_pnts.size()];
Eigen::Vector3f pnt = poly_pnts[(i)%poly_pnts.size()];
Eigen::Vector3f next_pnt = poly_pnts[(i+1)%poly_pnts.size()];
Eigen::Vector3f tmp_normal = GetNormalFrom3Points(pre_pnt, pnt, next_pnt);
//对于其中的tmp_normal 不一样,可能不同的权重,但是我都归一化了,得到相应的法向量。
sum += tmp_normal;
}
if(poly_pnts.empty())
{
return sum;
}
else
{
return sum.normal();
}
}
感悟:测试这个polygon的法向量得到。
边栏推荐
猜你喜欢

Linx常见目录&文件管理命令&VI编辑器使用 介绍

prometheus监控minio

如何使用xilinx的FFT ip

作为测试leader,考察求职者的几个方面
测试开发工程师成长日记010 - Jenkins中的CI/CD/CT(持续集成构建/持续交付/持续测试)

Test Development Engineer Growth Diary 017 - The Life Cycle of a Bug

Test Development Engineer Growth Diary 003 - Interface Automation Framework Construction

Install MySQL under Linux (centos7)

npm安装nodejs环境配置

计算矩阵的逆源码(使用伴随矩阵,3×3的矩阵)
随机推荐
OP 代币和不可转让的 NFT 致力于建立新的数字民主
Biotin-NHS LC(72040-63-2)生物素接头|站点特定探针
04-加壳和脱壳
prometheus-tls加密
RAID磁盘阵列
Software Testing Terminology - Scenario Testing
MongoDB - Introduction, Data Types, Basic Statements
Test Development Engineer Growth Diary 018 - Record of Required Questions for Test Interview (Continuous Update)
Test Development Engineer Growth Diary 003 - Interface Automation Framework Construction
测试开发工程师成长日记001 - 敏捷测试、CI/CD/CT、DecOps的一些介绍
prometheus监控minio
Selenium01
网络协议04 - 物理层和数据链路层
如何将modelsim仿真数据存成文件
MongoDB-CUD没有R
Advanced multi-threading (CountDownLatch, deadlock, thread-safe collection class)
删除openstack中的僵尸实例
MongoDB-介绍,数据类型,基本语句
从 Vertex 到 Subgraph 再到 PIE: 并行图计算编程模型概览
The concept and testing method of black box testing