将 CGAL 与四元数结合起来合乎逻辑吗

Is it logical wanting to combine CGAL with Quaternions

我正在创建一个离散元法模拟程序,我正在使用 CGAL 来描述多面体。由于更好的数值稳定性和缺少万向节锁,我计划通过阅读文献来使用四元数来计算旋转的微分方程。但是 CGAL 似乎不支持基于四元数的旋转。 (如果我在这里不正确,请告诉我)我发现这似乎缺失有点令人惊讶,当然是因为 CGAL 喜欢绝对的准确性,这似乎很适合四元数的数值稳定性。

问题:我能否以某种方式将 Boost 四元数与 CGAL 结合使用,或者是否有任何简单的方法来实现它。如果是这样,尝试这样做是否合乎逻辑?

我认为我有的其他选择是:

非常感谢我可能想到的任何建议或其他选项。

第一个选项:使用 Aff_transformation_3 class

CGAL 不提供四元数 class,但它确实提供了 Aff_transformation_3 class。您可以像这样轻松使用:

CGAL::Surface_mesh<Kernel> P;
std::transform( P.points_begin(), P.points_end(), P.points_begin(), yourAffineTransformation);

定义变换矩阵见this

第二种选择:使用四元数

如果您想使用四元数,您需要使用外部库构建一个。例如你可以使用 Eigen:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> //or whichever kernel suits your needs
#include <CGAL/Surface_mesh.h>
#include <Eigen/Geometry>

using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using Polyhedron = CGAL::Surface_mesh<Kernel>;
using Point = CGAL::Point_3<Kernel>;

// define the function that rotates your mesh
template <typename Vect, typename Quaternion>
void rotateCGALPolyhedron(Polyhedron P, Vect to_rotation_center,
                          Quaternion quat) {
  for (auto vi : P.vertices()) {
    Point p = P.point(vi);
    // translate your point to the rotation center. In your case this would be
    // the center of mass of the Polyhderon
    Vect V(p[0] - to_rotation_center[0], p[1] - to_rotation_center[1],
           p[2] - to_rotation_center[2]);
    // construct the translation vector that moves your point to the rotated
    // position
    Vect v = quat * V; //the Vect operator*(Quaternion, Vect) must be implemented!! If you use Eigen::Quaternion you could use Eigen::Vector3d
    // retranslate the point back to its initial position and translate it using
    // the previously created translation vector
    P.point(size_t(vi)) =
        Point(to_rotation_center[0] + v[0], to_rotation_center[1] + v[1],
              to_rotation_center[2] + v[2]);
  }
}

int main() {

  // define your rotation using eigen's quaternion class
  Eigen::Quaternion<double> quad(..);
  Eigen::Vector_3d centerOfMass; //find the center of mass of the mesh you want to rotate
  rotateCGALPolyhedron(P.vertices.begin(), P.vertices.end(), centerOfMass,
                       quad);

return 0;
}

如您所见,由于 cgal 没有四元数的实现,如果您想使用四元数,则与 Aff_transformation_3 情况相比,代码很长。