OpenCV矩阵运算之顶点法向量计算
来源:互联网 发布:淘宝购物积分怎么用 编辑:程序博客网 时间:2024/05/16 09:56
OpenCV进行顶点法向量计算
先介绍一下我接触此题的背景。我需要将一个.obj文件中的vn即顶点法向量计算出来。现在有的数据是f(三角面片索引),v(顶点坐标),但是网上找的代码不是很多,逻辑也不是很清楚,因此自己写了代码,并与大家分享。有错误敬请指出!
顶点法向量的计算方法
这里大概摘自这篇文章
最简单也是最直接的求顶点的法向量的方法是遍历此顶点所关联的所有三角形,将这些三角形上的法向量单位化后叠加,然后求出法向量的均值即可。
伪代码:
vertexNormal = (0,0,0);for each triangle connect to current vertex; vertexNormal += triangleNormal;vertexNormal /= connectedTriangleNums;
但这样求出的法向量往往效果不好,特别是当一些很小的多边形共面时。为了解决这个问题就需要使各个三角形并不是简单的等比例贡献法向量。直观上很容易发现,每个三角形与顶点相关联的那个角的大小是变化的,因此就可以使用此角度的大小来作为单个三角形对顶点法向量的贡献因子。
vertexNormal = 0,0,0;totalAngle = 0;for each triangle connect to current vertex;angle = acos(dot(edge1 , edge2)); vertexNormal += trangleNormal * angle; totalAngle += angle;vertexNormal /= totalAngle;
在实现时要注意,使用的角为关联当前顶点的那个角。
本文采用的算法是第二种
但是,根据数据结构不同,具体按需要编写代码
实现代码及解析
为每一个顶点定义一个存储法向量和与总角度的结构体:
using namespace cv;typedef struct vet_data { Vec3f vn; double total_angle;} vet_data;
新建点与面数据进行模拟:
Vec3f v[4] = { Vec3f(33.7193, 24.7910, 50.5333), Vec3f(34.6217, 23.1564, 51.2146), Vec3f(42.6307, 22.9352, 49.5766), Vec3f(41.6282, 24.5848, 48.7240)};Vec3f f[4] = { Vec3f(0, 1, 2), Vec3f(0, 2, 3), Vec3f(1, 2, 3), Vec3f(0, 1, 3)};
初始化:
vet_data v_data[4];for(int i = 0; i < 4; ++i) { v_data[i].vn = Vec3f(0,0,0); v_data[i].total_angle = 0;}
运算过程:
for(int i = 0; i < 4; ++i) { int indx[3]; for(int j = 0;j < 3; ++j) { indx[j] = f[i][j]; } Vec3f v0 = v[indx[0]], v1 = v[indx[1]], v2 = v[indx[2]]; Vec3f e1 = v1 - v0; Vec3f e2 = v2 - v1; Vec3f vn = normalize(e1.cross(e2)); double angle[3] = { 0.0, 0.0, 0.0 }; double t1, t2, t3; t1 = (v1 - v0).dot(v2 - v0) / mod(v1 - v0) / mod(v2 - v0) * CV_PI / 180.0; t2 = (v0 - v1).dot(v2 - v1) / mod(v0 - v1) / mod(v2 - v1) * CV_PI / 180.0; t3 = (v0 - v2).dot(v1 - v2) / mod(v0 - v2) / mod(v1 - v2) * CV_PI / 180.0; angle[0] = acos(t1); angle[1] = acos(t2); angle[2] = acos(t3); cout << angle[0] << " " << angle[1] << " " << angle[2] << "\t# " << t1 << " " << t2 << " " << t3 << std::endl; for(int i = 0; i < 3; ++i) { v_data[indx[i]].vn += vn * angle[i]; v_data[indx[i]].total_angle += angle[i]; } } ofstream out("outputvn.txt"); out << "-----vn-------" << endl; for(int i = 0; i < 4; ++i) { Vec3f vn = v_data[i].vn / v_data[i].total_angle; out << "vn" << " " << vn[0] << " " << vn[1] << " " << vn[2] << std::endl; cout << "vn" << " " << vn[0] << " " << vn[1] << " " << vn[2] << std::endl;}
阅读全文
0 0
- OpenCV矩阵运算之顶点法向量计算
- OpenCV矩阵(向量)运算
- 顶点法向量的计算
- 顶点法向量的矩阵变换
- OpenGL 模型顶点法向量的计算
- 计算三角网格的顶点法向量
- 计算三角网格的顶点法向量
- 计算三角网格的顶点法向量
- 解决opengl计算顶点法向量问题
- 解决opengl计算顶点法向量问题
- OpenGL 模型顶点法向量的计算
- 计算三角网格的顶点法向量
- 解决opengl计算顶点法向量问题
- 计算三角网格的顶点法向量
- 软件光栅器一之向量,顶点,矩阵
- opencv之矩阵运算Mat
- OpenCV之简单矩阵运算
- matlab 向量/矩阵运算
- 隐藏多余cell
- SMOJ 2201 D (线段树)
- 数位DP专题小结--by sgx 数位DP专题小结--by sgx
- POJ 1852 Ants
- iOS系统的各种设备识别码
- OpenCV矩阵运算之顶点法向量计算
- Eclipse快捷键大全
- ContentProvider--共享文件(.jepg文件)
- laravel笔记-数据库(迁移)
- 自练题20170721
- json动态过滤某些属性 之@jsonignore
- Android 热修复技术详解
- glibc源码分析之stat系列函数
- 生活与程序