3

STLコンテナでGLMベクトルクラスを使用しようとしています。私が使用しようとしない限り、大したことはありません<algorithm>==ほとんどのアルゴリズムは、GLMクラスに実装されていない演算子に依存しています。

誰もがこれを回避する簡単な方法を知っていますか?STLアルゴリズムを(再)実装せずに:(

GLMは、C++でGLSL関数を実装する優れた数学ライブラリです。

アップデート

glmが実際に拡張で比較演算子を実装していることを知りました(ここ)。しかし、どうすればstlでそれらを使用できますか?

アップデート2

この質問はこれに取って代わられました:stlアルゴリズムでglmのoperator ==を使用する方法は?

4

3 に答える 3

5

多くの STL アルゴリズムは、オブジェクトの比較にファンクターを受け入れます (もちろん、浮動小数点値を含む 2 つのベクトルを比較して等しいかどうかを判断する場合は、特別な注意が必要です)。

例:

をソートするには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 は、問題を解決するための 2 つの主要なアプローチを既に示しています。

  • それを必要とする STL アルゴリズムで明示的に使用されるファンクターを定義する、または
  • 実際の演算子==<、ファンクタが指定されていない場合に使用する STL アルゴリズムを定義します。

どちらのソリューションもまったく問題なく慣用的ですが、演算子を定義するときに覚えておくべきことは、それらが効果的に型を拡張するということです。を定義operator<するとglm::vec3、これらのベクトルは「より小さい」関係を定義するように拡張されます。つまり、誰かが 1 つのベクトルが別のベクトルよりも「小さい」かどうかをテストしたいときはいつでも、演算子を使用します。したがって、演算子は、普遍的に適用できる場合にのみ使用する必要があります。これが常に3D ベクトル間の「より小さい」関係を定義する唯一の方法である場合は、先に進んでそれを演算子にします。

問題は、おそらくそうではないということです。いくつかの異なる方法でベクトルを並べ替えることができますが、どれも明らかに「正しいもの」ではありません。たとえば、ベクトルを長さで並べ替えることができます。または、具体的にはコンポーネントの大きさによって、 とxを無視しyますz。または、3 つのコンポーネントすべてを使用して関係を定義することもできます (たとえば、ax == bx の場合は y 座標を確認し、それらが等しい場合は z 座標を確認します)。

あるベクトルが別のベクトルよりも「小さい」かどうかを定義する明確な方法はないため、演算子はおそらく悪い方法です。

同等性については、演算子の方が適切に機能する可能性があります。ベクトルの等価性の定義は 1 つあります。すべてのコンポーネントが等しい場合、2 つのベクトルは等価です。

ここでの唯一の問題は、ベクトルが浮動小数点値で構成されているため、何らかのイプシロン比較を実行して、すべてのメンバーがほぼ等しい場合に等しいことです。しかし、イプシロンを変数にすることもできますが、operator==2 つのパラメーターしかとらないため、 では実行できません。

もちろん、operator==ある種のデフォルトのイプシロン値を使用することもできますし、可変イプシロンとの比較のためにファンクターを定義することもできます。

どちらを優先するかという明確な答えはありません。どちらのテクニックも有効です。ニーズに最も適したものを選択してください。

于 2010-08-18T11:27:31.687 に答える