【问题标题】:Is it logical wanting to combine CGAL with Quaternions将 CGAL 与四元数结合起来合乎逻辑吗
【发布时间】:2017-08-16 14:32:46
【问题描述】:

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

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

我认为我还有其他选择:

  • 为所使用的仿射旋转编写我的微分方程是 CGAL 并处理那里的缺点。
  • 将方向存储为仿射旋转矩阵并将其转换为四元数并在差异中使用它。方程。显然,我担心每个时间步所需的转换步骤。

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

【问题讨论】:

    标签: c++ boost quaternions cgal


    【解决方案1】:

    第一个选项:使用 Aff_transformation_3 类

    CGAL 不提供四元数类,但它确实提供了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 的情况相比,代码很长。

    【讨论】:

      猜你喜欢
      • 2011-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-23
      • 2016-09-03
      • 2021-09-28
      • 1970-01-01
      相关资源
      最近更新 更多