小编Wil*_*ker的帖子

C++中的内部typedef - 好风格还是坏风格?

我最近发现自己经常做的事情是声明与该类中的特定类相关的typedef,即

class Lorem
{
    typedef boost::shared_ptr<Lorem> ptr;
    typedef std::vector<Lorem::ptr>  vector;

//
// ...
//
};
Run Code Online (Sandbox Code Playgroud)

然后在代码中的其他地方使用这些类型:

Lorem::vector lorems;
Lorem::ptr    lorem( new Lorem() );

lorems.push_back( lorem );
Run Code Online (Sandbox Code Playgroud)

我喜欢它的原因:

  • 它减少了类模板引入的噪音,std::vector<Lorem>变成了Lorem::vector等等.
  • 它用作意图陈述 - 在上面的示例中,Lorem类旨在通过boost::shared_ptr向量计数并存储在向量中.
  • 它允许实现改变 - 即如果Lorem需要boost::intrusive_ptr在稍后阶段被改变为侵入式引用计数(via ),那么这将对代码产生最小的影响.
  • 我认为它看起来"更漂亮",可以说更容易阅读.

我不喜欢它的原因:

  • 有时依赖性问题 - 如果你想Lorem::vector在另一个类中嵌入,但只需要(或想要)转发声明Lorem(而不是引入对其头文件的依赖),那么你最终必须使用显式类型(例如boost::shared_ptr<Lorem>而不是Lorem::ptr),这有点不一致.
  • 它可能不是很常见,因此难以理解?

我试着对我的编码风格保持客观,所以最好能得到一些其他意见,这样我就可以稍微剖析一下我的想法.

c++ coding-style typedef

168
推荐指数
4
解决办法
8万
查看次数

是否有将四元数旋转转换为欧拉角旋转的算法?

是否存在将旋转的四元数表示转换为欧拉角表示的现有算法?欧拉表示的旋转顺序是已知的,并且可以是六个排列中的任何一个(即xyz,xzy,yxz,yzx,zxy,zyx).我已经看到了固定旋转顺序的算法(通常是NASA标题,银行,滚动惯例),但不是任意旋转顺序.

此外,因为存在单个方向的多个欧拉角表示,所以该结果将是模糊的.这是可以接受的(因为方向仍然有效,它可能不是用户期望看到的方向),但是如果存在一个采用旋转限制的算法(即自由度数和考虑到每个自由度的限制,并在给定这些约束条件下产生"最明智的"欧拉表示.

我有一种感觉,这个问题(或类似的东西)可能存在于IK或刚体动力学领域.


解决:我刚刚意识到我可能不清楚我是通过遵循图形宝石的Ken Shoemake的算法来解决这个问题的.当时我确实回答了我自己的问题,但是我发现它可能并不清楚我这样做了.有关详细信息,请参阅下面的答案.


只是为了澄清 - 我知道如何从四元数转换为所谓的' Tait-Bryan '表示 - 我称之为'NASA'约定.这是zxy的旋转顺序(假设'Z'轴向上)的惯例.我需要一个适用于所有轮换订单的算法.

那么,解决方案可能是采用zxy顺序转换,并从其中获得其他五个转换以获得其他旋转顺序.我想我希望有一个更"全面"的解决方案.无论如何,我很惊讶我找不到现有的解决方案.

另外,这也许应该是一个单独的问题,任何转换(假设已知的旋转顺序,当然)将选择一个欧拉表示,但实际上有很多.例如,给定yxz的旋转顺序,两个表示(0,0,180)和(180,180,0)是等价的(并且将产生相同的四元数).有没有办法用限制自由度来约束解决方案?就像你在IK和僵硬的身体动力学中做的那样?即,在上述示例中,如果关于Z轴仅存在一个自由度,则可以忽略第二表示.


我已经找到了一篇可能是这个pdf算法的论文,但我必须承认,我发现逻辑和数学有点难以理解.当然还有其他解决方案吗?任意轮换顺序真的如此罕见吗?当然,每个允许骨架动画和四元数插值(即Maya,Max,Blender等)的主要3D包必须解决这个问题吗?

language-agnostic math animation quaternions euler-angles

27
推荐指数
4
解决办法
2万
查看次数

欧拉角与四元数 - 由内部存储和呈现给用户之间的张力引起的问题?

四元数可以说是在内部表示对象旋转的合适选择.它们简单有效地插入并明确表示单个方向.

但是,在用户界面中显示四元数通常是不合适的 - 欧拉角通常对用户来说更为熟悉,并且它们的值更直观和可预测.

欧拉角在代码级别上变得复杂 - 它们需要存储旋转顺序,并且使用该顺序和相关联的角度组成实际方向(无论是矩阵还是四元数)是麻烦的,至少可以说是麻烦的.

使用四元数表示最方便地执行可靠的插值 - 这是否意味着我们必须在Euler表示和四元数表示之间不断转换?这在绩效方面是否可行?

我们可以将方向存储为四元数并将它们转换为仅显示给用户吗?这可能是不可能的,因为对于任何给定的方向,只有一个四元数表示,但有许多欧拉表示.我们如何"选择"与最初定义该方向的Euler表示相对应的Euler表示?这似乎是一项不可能完成的任务 - 我们在转换为四元数时已经有效地丢失了信息.

我们可以存储为欧拉角,然后根据需要转换为四元数吗?这可能是不可扩展的 - 从欧拉角到四元数的转换,插值,然后再转换回来可能是相对昂贵的代码.

我们可以简单地存储两种表示并使用最适合任何给定情况的表示吗?在存储器方面的大量成本(想象具有大约60个骨骼的骨架的动画曲线)并保持这些值同步可能是昂贵的,或者至少是麻烦的.

有没有人看到,使用或者解决这个问题的任何聪明的解决方案?当然上面的三个选项不仅仅是一个吗?是否有任何其他的问题领域类似这样已经解决了吗?

3d user-interface animation quaternions euler-angles

11
推荐指数
1
解决办法
1万
查看次数

有没有办法阻止Boost.Build递归扫描#include指令的头文件?

有没有办法限制Boost.Build递归扫描#include指令到特定目录或目录集的头文件?即我希望它仅以递归方式扫描项目中的头文件.我知道他们的外部依赖关系不会改变(并且Boost和Qt他们相当大).我最终在依赖树中有大约50,000个目标,这需要一段时间来处理(即使没有实际更改文件,也会导致1-2分钟的构建时间).

到目前为止我发现的唯一解决方案是利用INCLUDE环境变量(我正在使用MSVC) - 这意味着Boost.Build不需要被告知包含路径(我正在使用该功能),因此不扫描它们.这看起来有点像黑客.

我觉得我必须遗漏一些明显的东西,因为我无法找到遇到类似问题的其他人,即使我几乎立即遇到了这个问题.我最近的就在这里.

从调试输出(bjam -d 3)判断它还会多次扫描大多数头文件...我不知道这是否意味着它们被多次添加为依赖项,但肯定是加载一个文件和扫描整个内容必须加起来?

如果我可以告诉它不要打扰扫描一个特定的目录或一组目录,我可以保证头文件不会改变,那将是完美的.

c++ dependencies boost-build

5
推荐指数
1
解决办法
771
查看次数