1、三角面法向量
空间已知三点的位置:
p1(x1,y1,z1),
p2(x2,y2,z2),
p3(x3,y3,z3),
令它们逆时针在空间摆放。这样就可以得到平面的两个向量:
p1p2 = (x2-x1,y2-y1,z2-z1),
p1p3 = (x3-x1,y3-y1,z3-z1),
而平面法线总是和这两个向量垂直。也就是说,p1p2与p1p3的向量积就是平面的法向量n。
向量积知识点:
已知向量a=(a1,a2,a3) b=(b1,b2,b3)
其向量积可表示为:a×b=(a2b3-a3b2,a3b1-a1b3,a1b2-a2b1)
简单C++实现代码如下:
// GetNormalBy3Points.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
using namespace std;
//三维double矢量
struct Vec3d
{
double x, y, z;
Vec3d()
{
x = 0.0;
y = 0.0;
z = 0.0;
}
Vec3d(double dx, double dy, double dz)
{
x = dx;
y = dy;
z = dz;
}
void Set(double dx, double dy, double dz)
{
x = dx;
y = dy;
z = dz;
}
};
//计算三点成面的法向量
void Cal_Normal_3D(const Vec3d& v1, const Vec3d& v2, const Vec3d& v3, Vec3d &vn)
{
//v1(n1,n2,n3);
//平面方程: na * (x – n1) + nb * (y – n2) + nc * (z – n3) = 0 ;
double na = (v2.y - v1.y)*(v3.z - v1.z) - (v2.z - v1.z)*(v3.y - v1.y);
double nb = (v2.z - v1.z)*(v3.x - v1.x) - (v2.x - v1.x)*(v3.z - v1.z);
double nc = (v2.x - v1.x)*(v3.y - v1.y) - (v2.y - v1.y)*(v3.x - v1.x);
//平面法向量
vn.Set(na, nb, nc);
}
int main()
{
Vec3d v1(1.0, 5.2, 0.0);
Vec3d v2(2.8, 3.9, 1.0);
Vec3d v3(7.6, 8.4, 2.0);
Vec3d vn;
Cal_Normal_3D(v1, v2, v3, vn);
cout << "法向量为:x= " << vn.x << " y= " << vn.y << " z= " << vn.z << endl;
return 0;
}
2、共用顶点法向量
在三角网中经常遇到同一个顶点被相邻的多个三角面共用的情况,此时这个顶点的法向量如何计算?其实很简单,只需要把该点对应面的法向量相加就可以了。可以不用求平均,因为反正最后是要正规化的。
具体到DEM上来说,可以将一个DEM的矩形网格分成两个同样顺序排列的三角形,每个点涉及1到6个不等的面法向量。将这些面法向量相加并正则化,就得到了每个点的法向量。
鸣谢:https://blog.csdn.net/charlee44/article/details/95900684