在VTK中有一类vtkPointsProjectedHull,关于该类的说明是这样的:
the convex hull of the orthogonal projection of the vtkPoints in the 3 coordinate directions
意思就是,将一空间点集投影到某一坐标平面并求解2d凸包,投影平面有三种:XY平面,XZ平面,YZ平面。 该类包含成员以下成员函数:
// Description:
// Returns the coordinates (y,z) of the points in the convex hull
// of the projection of the points down the positive x-axis. pts has
// storage for len*2 values.
int GetCCWHullX(float *pts, int len);
int GetCCWHullX(double *pts, int len);
// Description:
// Returns the coordinates (z, x) of the points in the convex hull
// of the projection of the points down the positive y-axis. pts has
// storage for len*2 values.
int GetCCWHullY(float *pts, int len);
int GetCCWHullY(double *pts, int len);
// Description:
// Returns the coordinates (x, y) of the points in the convex hull
// of the projection of the points down the positive z-axis. pts has
// storage for len*2 values.
int GetCCWHullZ(float *pts, int len);
int GetCCWHullZ(double *pts, int len);
为了代码避免重复,成员函数的实现很有技巧性:
#define VTK_GETCCWHULL(which, dim)
int vtkPointsProjectedHull::GetCCWHull##which(float *pts, int len)
{
int i;
double *dpts = new double [len*2];
int copypts = this->GetCCWHull##which(dpts, len);
for (i=0; i<copypts*2; i++)
{
pts[i] = static_cast<float>(dpts[i]);
}
delete [] dpts;
return copypts;
}
int vtkPointsProjectedHull::GetCCWHull##which(double *pts, int len)
{
if ((this->HullSize[dim] == 0) || (this->GetMTime() > this->HullTime[dim]))
{
GrahamScanAlgorithm(dim);
}
int copylen = (this->HullSize[dim] <= len) ? this->HullSize[dim] : len;
if (copylen <= 0) return 0;
memcpy(pts, this->CCWHull[dim], sizeof(double) * 2 * copylen);
return copylen;
}
VTK_GETCCWHULL(X, 0);
VTK_GETCCWHULL(Y, 1);
VTK_GETCCWHULL(Z, 2);
首先, 根据输入点集的数据类型(double,float),调用了对应类型的方法;其次,利用#define宏定义实现了对应float、double两种类型的函数,注意#define后面的内容每行末尾的“”,表示同一行;最后,通过##操作符将VTK_GETCCWHULL与which进行连接,分别对应了VTK_GETCCWHULLX, VTK_GETCCWHULLY和VTK_GETCCWHULLZ。