首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >把CGAL和四元数结合起来是否合乎逻辑?

把CGAL和四元数结合起来是否合乎逻辑?
EN

Stack Overflow用户
提问于 2017-08-16 14:32:46
回答 1查看 259关注 0票数 0

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

问题:可以以某种方式将Boost四元数和CGAL结合起来,或者有什么简单的方法来实现这一点。如果是这样的话,这是否是一个合乎逻辑的想法呢?

我认为我还有其他选择:

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

我想出的任何建议或其他选择都会受到极大的赞赏。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-04 11:46:36

第一个选项:使用Aff_transformation_3类

CGAL不提供四元数类,而是提供3级。你可以很容易地像这样使用:

代码语言:javascript
复制
CGAL::Surface_mesh<Kernel> P;
std::transform( P.points_begin(), P.points_end(), P.points_begin(), yourAffineTransformation);

有关定义转换矩阵的信息,请参见

第二个选项:使用四元数

如果要使用四元数,则需要使用外部库构造四元数。例如,您可以使用Eigen:

代码语言:javascript
复制
#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大小写长。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45716415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档