我尝试在 STL 容器中使用 GLM 矢量类。只要我不尝试使用<algorithm>
. 大多数算法依赖于==
没有为 GLM 类实现的运算符。
有人知道解决此问题的简单方法吗?无需(重新)实现 STL 算法 :(
GLM是一个很棒的数学库,在 c++ 中实现了 GLSL 函数
更新
我刚刚发现 glm 实际上在扩展中实现了比较运算符(here)。但是我如何在 stl 中使用它们?
更新 2
这个问题已经被这个问题所取代:如何在stl算法中使用glm的operator==?
许多 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 甚至重新发明轮子。
您应该能够将 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;
}
James Curran 和 Greg S 已经向您展示了解决问题的两种主要方法。
==
以及使用哪些 STL 算法。<
这两种解决方案都非常好且惯用,但是在定义运算符时要记住的一点是它们有效地扩展了类型。一旦你定义operator<
了 a glm::vec3
,这些向量就被扩展为定义一个“小于”关系,这意味着任何时候有人想要测试一个向量是否“小于”另一个,他们将使用你的运算符。因此,只有在普遍适用的情况下才应使用运算符。如果这始终是定义 3D 向量之间的小于关系的唯一且唯一的方法,请继续将其设为运算符。
问题是,它可能不是。我们可以用几种不同的方式对向量进行排序,但显然没有一个是“正确的”。例如,您可以按长度对向量进行排序。或者x
具体地通过组件的大小,忽略y
and z
。或者您可以使用所有三个组件定义一些关系(例如,如果 ax == bx,检查 y 坐标。如果它们相等,检查 z 坐标)
没有明显的方法来定义一个向量是否“小于”另一个向量,因此运算符可能是一个不好的方法。
对于相等,运算符可能会更好。对于向量,我们确实有一个相等的定义:如果每个分量相等,则两个向量相等。
这里唯一的问题是向量由浮点值组成,因此您可能想要进行某种 epsilon 比较,以便在所有成员几乎相等的情况下它们是相等的。但是您可能还希望 epsilon 是可变的,而这不能在 中完成operator==
,因为它只需要两个参数。
当然,operator==
可以只使用某种默认的 epsilon 值,并且可以定义仿函数以与变量 epsilon 进行比较。
没有明确的答案可以选择。这两种技术都是有效的。只需选择最适合您需求的那个。