当前位置:网站首页>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的法向量得到。
边栏推荐
猜你喜欢

Rodrigues:旋转矩阵的向量表达

多线程进阶(CountDownLatch,死锁,线程安全集合类)

多线程进阶(锁策略,自旋+CAS,Synchronized,JUC,信号量)

牛客:删除公共字符

Mastering JESD204B (2) – Debugging of AD6676

多线程基础(多线程内存,安全,通信,线程池和阻塞队列)

The Force Plan Microservices | Centralized Configuration Center Config Asymmetric Encryption and Security Management

prometheus-tls加密

Shortcut keys commonly used in the use of Word

Network Protocol 04 - Physical and Data Link Layers
随机推荐
Selenium02
Selenium01
MongoDB-介绍,数据类型,基本语句
GadgetInspector原理分析
Test Development Engineer Growth Diary 017 - The Life Cycle of a Bug
GCD的定时器
debian vsftpd + ssl
Test development engineer growth diary 016 - those things about the test
藏不住了,我要揭露云原生的那些不好
Software Testing Terminology - Scenario Testing
使用 Grafana 的 Redis Data Source 插件监控 Redis
Bull: remove common characters
图计算101:图计算的类型、语言与系统
Redis6的数据类型
Advanced multi-threading (lock strategy, spin+CAS, Synchronized, JUC, semaphore)
测试开发工程师成长日记007 - Bug的优先级定义及填写规范
Linx常见目录&文件管理命令&VI编辑器使用 介绍
如何使用xilinx的FFT ip
DNS域名解析服务
测试开发工程师成长日记001 - 敏捷测试、CI/CD/CT、DecOps的一些介绍