qhull 库 - C++ 接口

Posted

技术标签:

【中文标题】qhull 库 - C++ 接口【英文标题】:qhull Library - C++ Interface 【发布时间】:2013-11-01 01:58:56 【问题描述】:

qhull 库 (qhull.org) 在他的网站上提供了几个示例,但所有关于 C++ 的信息对我来说都不是很有用。

我正在尝试制作从文件中读取的 3D 点的简单凸包,我无法使用网站中建议的将 qhull.exe 作为外部应用程序调用的技术,因为我需要制作我在数据点中所做的一些修改的几个凸包。

我找不到执行此操作的简单示例,有人可以帮我完成这项任务吗?任何信息都会很有用。

谢谢

【问题讨论】:

我用的是windows 天哪,那个库太复杂了。我只是想查找它用于做凸包的一堆函数,它是......就像在俄罗斯 【参考方案1】:

由于我自己在使用 Qhull 和 c++ 时遇到了困难,并且在网上找不到任何有用的示例,并且 dddd 终于成功获得了有效的结果,所以我将我的代码发布在这里以供将来使用。

此答案适用于带有 Visual Studio 2012/3 的 Windows。我不知道它在其他平台上如何或是否有效

所以,从 here 下载 qhull 源文件后开始做事 并在 VS 中打开一个项目,您需要添加的唯一文件是以下 2 个目录:

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));
        
    

请注意,我从我的项目中复制了此代码,并对其进行了一些修改以提供更多信息,但尚未编译此示例。

【讨论】:

@Raaj 感谢您为他人指出这一点。随意使用线程安全代码编辑我的答案,我会审核并接受它 没有。我浏览了整个 internet/github/codeproject 的所有内容。没有凸/凹壳算法的 C/C++ 示例。 如果我没记错的话..qhull 提出了这个线程安全的新可重入 qhull。我没有找到任何使用该代码的示例 qhull 2015 是可重入的,但不是线程安全的:参见 qhull.org/html/qh-code.htm#reentrant 和 qhull.org/html/qh-code.htm#cpp 谢谢你,这篇文章真的很有用。【参考方案2】:

这是一个使用 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();
    

【讨论】:

以上是关于qhull 库 - C++ 接口的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C++ 封装的 COM 接口部署 C# 库?

C#调用C++动态库接口函数和回调函数

C#调用C++动态库接口函数和回调函数

如何在 C++ 共享库中隐藏业务对象的实现细节并提供接口

Visual C++ GC 接口 如何启用它以及包含哪个库

Scipy ConvexHull 和 QHull:等级/维度不是最大的