3

我尝试在 STL 容器中使用 GLM 矢量类。只要我不尝试使用<algorithm>. 大多数算法依赖于==没有为 GLM 类实现的运算符。

有人知道解决此问题的简单方法吗?无需(重新)实现 STL 算法 :(

GLM是一个很棒的数学库,在 c++ 中实现了 GLSL 函数

更新

我刚刚发现 glm 实际上在扩展中实现了比较运算符(here)。但是我如何在 stl 中使用它们?

更新 2

这个问题已经被这个问题所取代:如何在stl算法中使用glm的operator==?

4

3 回答 3

5

许多 STL 算法接受函子进行对象比较(当然,在比较两个包含浮点值的向量是否相等时需要特别小心)。

例子:

要对 a 进行排序std::list<glm::vec3>(由您决定以这种方式对向量进行排序是否有任何实际意义),您可以使用

std::sort(myVec3List.begin(), myVec3List.end(), MyVec3ComparisonFunc)

bool MyVec3ComparisonFunc(const glm::vec3 &vecA, const glm::vec3 &vecB)
{
 return vecA[0]<vecB[0] 
        && vecA[1]<vecB[1] 
        && vecA[2]<vecB[2];
}

所以,幸运的是,没有必要修改 GLM 甚至重新发明轮子。

于 2010-08-17T10:45:55.543 回答
3

您应该能够将 operator== 实现为独立函数:

// (Actually more Greg S's code than mine.....)

bool operator==(const glm::vec3 &vecA, const glm::vec3 &vecB) 
{ 
   const double epsilion = 0.0001;  // choose something apprpriate.

   return    fabs(vecA[0] -vecB[0]) < epsilion   
          && fabs(vecA[1] -vecB[1]) < epsilion   
          && fabs(vecA[2] -vecB[2]) < epsilion;
} 
于 2010-08-17T11:01:15.850 回答
2

James Curran 和 Greg S 已经向您展示了解决问题的两种主要方法。

  • 定义要在需要它的 STL 算法中显式使用的函子,或
  • 如果没有指定函子,则定义实际的运算符==以及使用哪些 STL 算法。<

这两种解决方案都非常好且惯用,但是在定义运算符时要记住的一点是它们有效地扩展了类型。一旦你定义operator<了 a glm::vec3,这些向量就被扩展为定义一个“小于”关系,这意味着任何时候有人想要测试一个向量是否“小于”另一个,他们将使用你的运算符。因此,只有在普遍适用的情况下才应使用运算符。如果这始终是定义 3D 向量之间的小于关系的唯一且唯一的方法,请继续将其设为运算符。

问题是,它可能不是。我们可以用几种不同的方式对向量进行排序,但显然没有一个是“正确的”。例如,您可以按长度对向量进行排序。或者x具体地通过组件的大小,忽略yand z。或者您可以使用所有三个组件定义一些关系(例如,如果 ax == bx,检查 y 坐标。如果它们相等,检查 z 坐标)

没有明显的方法来定义一个向量是否“小于”另一个向量,因此运算符可能是一个不好的方法。

对于相等,运算符可能会更好。对于向量,我们确实有一个相等的定义:如果每个分量相等,则两个向量相等。

这里唯一的问题是向量由浮点值组成,因此您可能想要进行某种 epsilon 比较,以便在所有成员几乎相等的情况下它们是相等的。但是您可能还希望 epsilon 是可变的,而这不能在 中完成operator==,因为它只需要两个参数。

当然,operator==可以只使用某种默认的 epsilon 值,并且可以定义仿函数以与变量 epsilon 进行比较。

没有明确的答案可以选择。这两种技术都是有效的。只需选择最适合您需求的那个。

于 2010-08-18T11:27:31.687 回答