GLM + STL:缺少运算符==

发布于 2024-09-14 12:17:15 字数 579 浏览 2 评论 0原文

我尝试在 STL 容器中使用 GLM 向量类。只要我不尝试使用 就没什么大不了的。大多数算法依赖于 GLM 类未实现的 == 运算符。

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

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

更新

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

https://stackoverflow.com/questions/3891497/how-to-use-glms-operator-in

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

I try to use GLM vector classes in STL containers. No big deal as long as I don't try to use <algorithm>. Most algorithms rely on the == operator which is not implemented for GLM classes.

Anyone knows an easy way to work around this? Without (re-)implementing STL algorithms :(

GLM is a great math library implementing GLSL functions in c++

Update

I just found out that glm actually implements comparison operators in an extension (here). But how do i use them in stl?

Update 2

This question has been superseded by this one: how to use glm's operator== in stl algorithms?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

Spring初心 2024-09-21 12:17:16

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

示例:

要对 std::list 进行排序(以这种方式对向量进行排序是否具有任何实际意义取决于您),您可以使用

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

So

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

,值得庆幸的是,没有需要修改 GLM 甚至重新发明轮子。

Many STL algorithms accept a functor for object comparison (of course, you need to exercise special care when comparing two vectors containing floating point values for equality).

Example:

To sort a std::list<glm::vec3> (it's up to you whether sorting vectors that way would make any practical sense), you could use

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

with

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

So, thankfully, there is no need to modify GLM or even reinvent the wheel.

著墨染雨君画夕 2024-09-21 12:17:16

您应该能够将运算符 == 实现为独立函数:

// (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;
} 

You should be able to implement a operator== as a stand-alone function:

// (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;
} 
π浅易 2024-09-21 12:17:16

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

  • 定义要在需要它的 STL 算法中显式使用的函子,或者
  • 定义 STL 算法在未指定函子时使用的实际运算符 ==<

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

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

没有明显的方法来定义一个向量是否“小于”另一个向量,所以运算符可能是一个糟糕的方法。

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

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

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

没有明确的答案来选择哪个。两种技术都是有效的。只需选择最适合您需求的一款即可。

James Curran and Greg S have already shown you the two major approaches to solving the problem.

  • define a functor to be used explicitly in the STL algorithms that need it, or
  • define the actual operators == and < which STL algorithms use if no functor is specified.

Both solutions are perfectly fine and idiomatic, but a thing to remember when defining operators is that they effectively extend the type. Once you've defined operator< for a glm::vec3, these vectors are extended to define a "less than" relationship, which means that any time someone wants to test if one vector is "less than" another, they'll use your operator. So operators should only be used if they're universally applicable. If this is always the one and only way to define a less than relationship between 3D vectors, go ahead and make it an operator.

The problem is, it probably isn't. We could order vectors in several different ways, and none of them is obviously the "right one". For example, you might order vectors by length. Or by magnitude of the x component specifically, ignoring the y and z ones. Or you could define some relationship using all three components (say, if a.x == b.x, check the y coordinates. If those are equal, check the z coordinates)

There is no obvious way to define whether one vector is "less than" another, so an operator is probably a bad way to go.

For equality, an operator might work better. We do have a single definition of equality for vectors: two vectors are equal if every component is equal.

The only problem here is that the vectors consist of floating point values, and so you may want to do some kind of epsilon comparison so they're equal if all members are nearly equal. But then the you may also want the epsilon to be variable, and that can't be done in operator==, as it only takes two parameters.

Of course, operator== could just use some kind of default epsilon value, and functors could be defined for comparisons with variable epsilons.

There's no clear cut answer on which to prefer. Both techniques are valid. Just pick the one that best fits your needs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文