Qhull庫C++接口修改

Qhull(http://www.qhull.org/)是一個強大的計算幾何庫,可以用於計算高維的convex hull, Delaunay triangulation, Voronoi diagram等,在python中調用非常方便,最近由於需要將項目遷移到C++,因此折騰了一下。qhull的c++接口並不太完善,很多接口是基於Rbox(生成數據),因此我根據自身需要,修改了qhull的c++接口。

總體要求:輸入:3D/4D點集,輸出:對應的凸包。

主要修改libqhullcpp文件夾中的:Qhull.h 和 Qhull.cpp

1 Qhull.h 代碼修改

1 .1 Qhull.h 中增加3D/4D點集數據結構

struct vec3 {
		double v[3];
		vec3(double x_ = 0, double y_ = 0, double z_ = 0) {
			v[0] = x_;
			v[1] = y_;
			v[2] = z_;
		}
	};

	struct vec4 {
		double v[4];
		vec4(double x_ = 0, double y_ = 0, double z_ = 0, double w_ = 0) {
			v[0] = x_;
			v[1] = y_;
			v[2] = z_;
			v[3] = w_;
		}
	};

1 .2 Qhull.h 中增加接口

	public:
		void runQhull3D(const std::vector<vec3> &points, const char* args);
		void runQhull4D(const std::vector<vec4> &points, const char* args);
		void runQhull(const PointCoordinates &points, const char *qhullCommand2);

2 Qhull.cpp 代碼修改

	void Qhull::runQhull3D(const std::vector<vec3> &points, const char* args)
	{
		m_externalPoints = new PointCoordinates(3, "");  //3 = dimension
		vector<double> allPoints;
		for each (vec3 p in points)
		{
			allPoints.push_back(p.v[0]);
			allPoints.push_back(p.v[1]);
			allPoints.push_back(p.v[2]);
		}

		m_externalPoints->append(allPoints); //convert to vector<double>
		runQhull(*m_externalPoints, args);
	}

	void Qhull::runQhull4D(const std::vector<vec4> &points, const char* args)
	{
		m_externalPoints = new PointCoordinates(4, "");  //3 = dimension
		vector<double> allPoints;
		for each (vec4 p in points)
		{
			allPoints.push_back(p.v[0]);
			allPoints.push_back(p.v[1]);
			allPoints.push_back(p.v[2]);
			allPoints.push_back(p.v[3]);
		}

		m_externalPoints->append(allPoints); //convert to vector<double>
		runQhull(*m_externalPoints, args);
	}

	void Qhull::runQhull(const PointCoordinates &points, const char *qhullCommand2)
	{
		runQhull(points.comment().c_str(), points.dimension(), points.count(), &*points.coordinates(), qhullCommand2);
	}

3.測試代碼

求如下立方體的凸包:
在這裏插入圖片描述

#include "libqhullcpp/QhullFacetList.h"
#include "libqhullcpp/Qhull.h"
#include <iostream>
#include <vector>

using namespace orgQhull;
using namespace std;


void print_facets(Qhull& qhull) {
	QhullFacetList facets = qhull.facetList();
	for (QhullFacetList::iterator it = facets.begin(); it != facets.end(); ++it)
	{
		if (!(*it).isGood()) continue;
		QhullFacet f = *it;
		QhullVertexSet vSet = f.vertices();
		for (QhullVertexSet::iterator vIt = vSet.begin(); vIt != vSet.end(); ++vIt)
		{
			QhullVertex v = *vIt;

			QhullPoint p = v.point();
			cout << p.id() << " ";
		}
		cout << endl;
	}
	cout << endl;
}

int main(int argc, char **argv) {
	Qhull qhull;
	std::vector<vec3> vertices1(9);

	vertices1[0] = vec3(0, 0, 0);
	vertices1[1] = vec3(2, 0, 0);
	vertices1[2] = vec3(2, 2, 0);
	vertices1[3] = vec3(0, 2, 0);
	vertices1[4] = vec3(0, 0, 2);
	vertices1[5] = vec3(2, 0, 2);
	vertices1[6] = vec3(2, 2, 2);
	vertices1[7] = vec3(0, 2, 2);
	vertices1[8] = vec3(0, 0, 0);

	qhull.runQhull3D(vertices1, "Qt");
	print_facets(qhull);
}

輸出:
3 2 1
3 1 0
5 1 0
5 4 0
7 3 0
7 4 0
6 2 1
6 5 1
6 3 2
6 7 3
6 5 4
6 7 4

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章