выпуклая оболочка — библиотека qhull — интерфейс C ++

Библиотека qhull (qhull.org) имеет несколько примеров для запуска на своем веб-сайте, но вся информация, касающаяся C ++, не очень полезна для меня.

Я пытаюсь создать простую выпуклую оболочку из трехмерных точек, которую я читаю из файла, я не могу использовать метод, предложенный на веб-сайте, для вызова qhull.exe как внешнего приложения, потому что мне нужно сделать несколько выпуклых оболочек от некоторых изменений, которые я сделал в точках данных.

Я не могу найти простой пример для этого, кто-то может мне помочь с этой задачей? Любая информация будет полезна.

Спасибо

14

Решение

Поскольку мне было очень трудно использовать Qhull с c ++ и я не смог найти в Интернете никаких полезных примеров, и наконец, DDDD удалось получить достоверные результаты, я публикую здесь свой код для дальнейшего использования.

Этот ответ работает для Windows, с Visual Studio 2012/3. Я не знаю, как или если это работает на других платформах

Итак, для начала, после загрузки исходных файлов 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));
}
}
}

Обратите внимание, что я скопировал этот код из своего проекта и немного изменил его, чтобы сделать его более информативным, но не скомпилировал этот пример.

13

Другие решения

Других решений пока нет …