本篇介绍一种近似平面的算法和实现,要解决的问题是:给定点集,确定尽可能经过这些点集的近似平面。
文章目录:
- 算法介绍
- 源码实现
- 参考
算法介绍
在三维空间上,有一个多边形
计算经过多边形的平面,有一种非常简单的方法,就是从中任选三个顶点,使用叉积,计算出法向量,再计算出平面表示中的常量。这种方法存在两个问题:(1)如果所有点不能精确的在同一个平面上,任选的三个点不具代表性,无法代表点集中所有的点;(2)如果选择的三个点,“几乎”(很接近,但是又不是)是同一条直线上,计算叉积的结果会非常的小,则误差就会变得非常的大。
另外一种方法,是从顶点集中任选三个点匹配,那么就会有
Martin Newell提出了一种计算经过多边形
其中,
举个例子,给定多边形的三个点
在求得法向量
知道了平面的法向量和平面上的点V,就可以很容易计算出平面的表示公式。接下来,介绍该公式的推导过程,解释为什么它能表示成经过经过多边形的“近似”平面。
把一个多边形正交投影到
1. 假设多边形P是一个三角形(多边形可以表示成多个三角形的和),如图2所示。三角形T所在的平面的法向量是
(a)
(c)把
接下来,考虑计算多边形P在3个平面上的投影面积,以xy平面为例,即
每条边的面积和为
同理,可以计算出多边形P在xz平面上的投影面积
源码实现
基础库源码链接,参见这里,下面是前面所描述的算法的实现。
#include "SrGeometricTools.h"
#include "SrDataType.h"
namespace {
/**
brief 3D plane class.
This is a 3D plane class with public data members.
The line is parameterized as ^n*^X+d=0,in which ^n is the 'normal' data,d is the 'd' data.
The normal isn't normalized.
*/
class SrPlane3D
{
public:
/**
brief Initialize a plane by a set of points.
*/
bool initPlane(const SrPoint3D* point, int numPoint)
{
SrVector3D normal(0, 0, 0);
if (!computeNormal(point, numPoint, normal))
return false;
SrPoint3D avePoint = SrPoint3D(0, 0, 0);
int i;
for (i = 0; i < numPoint; i++)
{
avePoint += point[i];
}
avePoint /= numPoint;
mNormal = normal;
mD = -mNormal.dot(avePoint);
return true;
}
protected:
bool computeNormal(const SrPoint3D* point, int number, SrVector3D& result) const
{
SrVector3D normal(0, 0, 0);
int i;
for (i = 0; i < number; i++)
{
normal.x += (point[i].y - point[(i + 1) % number].y)*(point[i].z + point[(i + 1) % number].z);
normal.y += (point[i].z - point[(i + 1) % number].z)*(point[i].x + point[(i + 1) % number].x);
normal.z += (point[i].x - point[(i + 1) % number].x)*(point[i].y + point[(i + 1) % number].y);
}
if (EQUAL(normal.x, 0) && EQUAL(normal.y, 0) && EQUAL(normal.z, 0))
return false;
result = normal;
return true;
}
public:
SrVector3D mNormal;
SrReal mD;
};
}
参考
[1] Hill, F., and S. Kelley. Computer Graphics Using OpenGL, 3/E, Pearson, 2007.
[2] Philip Schneider, and David H. Eberly. Geometric tools for computer graphics, Morgan Kaufmann, 2002.