qhull库( qhull.org)在他的网站上有几个例子,但是所有关于C++的信息对我来说都不是很有用。
我正在尝试从文件中读取的3D点的简单凸包,我不能使用网站中建议的技术,调用qhull.exe作为外部应用程序,因为我需要从我在数据点中所做的一些修改中制作几个凸包。
我找不到一个简单的例子来做这件事,有人能在这项任务中给我一些帮助吗?任何信息都是有用的。
谢谢
发布于 2015-03-28 06:29:13
由于我自己在c++上使用Qhull很困难,并且在网上找不到任何有用的例子,hard最终成功地获得了有效的结果,所以我在这里发布了我的代码以备将来使用。
此答案适用于windows和visual studio 2012/3。我不知道它如何或是否适用于其他平台
因此,首先,在从here下载qhull源文件并在VS中打开项目后,您需要添加的文件只有以下两个目录:
libqhull/
libqhullcpp/将这些文件添加到项目中后,添加以下代码(这是我的方式,显然您可以使用自己的方式):
Qhull.h
namespace orgQhull{
//...
private:
PointCoordinates *m_externalPoints;
//...
public:
void runQhull3D(const std::vector<vec3> &points, const char* args);
void runQhull(const PointCoordinates &points, const char *qhullCommand2);
//...
}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.x());
allPoints.push_back(p.y());
allPoints.push_back(p.z());
}
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);
}最后是如何使用代码:
//not sure all these includes are needed
#include "RboxPoints.h"
#include "QhullError.h"
#include "Qhull.h"
#include "QhullQh.h"
#include "QhullFacet.h"
#include "QhullFacetList.h"
#include "QhullLinkedList.h"
#include "QhullVertex.h"
#include "QhullSet.h"
#include "QhullVertexSet.h"
#include <vector>
int main()
{
orgQhull::Qhull qhull;
std::vector<vec3> vertices;
qhull.runQhull3D(vertices, "Qt");
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();
double * coords = p.coordinates();
vec3 aPoint = vec3(coords[0], coords[1], coords[2]);
// ...Do what ever you want
}
}
// Another way to iterate (c++11), and the way the get the normals
std::vector<std::pair<vec3, double> > facetsNormals;
for each (QhullFacet facet in qhull.facetList().toStdVector())
{
if (facet.hyperplane().isDefined())
{
auto coord = facet.hyperplane().coordinates();
vec3 normal(coord[0], coord[1], coord[2]);
double offset = facet.hyperplane().offset();
facetsNormals.push_back(std::pair<vec3, double>(normal, offset));
}
}
}请注意,我从我的项目中复制了此代码,并对其进行了一些修改以提供更多信息,但没有编译此示例。
发布于 2021-10-20 04:15:00
下面是一个使用来自c++的可重入qhull的简单示例。我想这可能会很有用。
#include <iostream>
#include <vector>
#include <string>
#include "Qhull.h"
int main(int argc, char const *argv[])
{
std::vector<double> points_3D = {0, 0, 0,
0, 1, 0,
1, 1, 0,
1, 0, 0,
0, 0, 1,
0, 1, 1,
1, 1, 1,
1, 0, 1};
int ndim = 3;
int num_points = points_3D.size() / ndim;
std::string comment = ""; // rbox commands, see http://www.qhull.org/html/rbox.htm
std::string qhull_command = ""; // For qhull commands, see http://www.qhull.org/html/qhull.htm
try
{
orgQhull::Qhull qhull = orgQhull::Qhull(comment.c_str(), ndim, num_points, points_3D.data(), qhull_command.c_str());
std::cout << "qhull.hullDimension(): " << qhull.hullDimension() << "\n";
std::cout << "qhull.volume(): " << qhull.volume() << "\n";
std::cout << "qhull.area(): " << qhull.area() << "\n";
}
catch (orgQhull::QhullError &e)
{
std::cerr << e.what() << std::endl;
return e.errorCode();
}
}https://stackoverflow.com/questions/19530731
复制相似问题