-1

特定のアルゴリズムを実装するために std::set を使用しています。セットには重複があったため、オペレーターをオーバーロードする必要があったと思います。オーバーロードはこんな感じ。

class Vec3f {
    ...

    bool operator () ( const Vector3f& v0, const Vector3f& v1 ) const {
    float epsilon = 1e-7;
    return ((v1[0] - v0[0]) > epsilon) &&  ((v1[1] - v0[1]) > epsilon) && ((v1[2] - v0[2]) > epsilon);
}       ...


"Vec3f.h"

int main(){
    ...
    std::set<Vec3f,Vec3f> visited;
    ...
}

std::set で必要な < 演算子を使用できるようにオーバーロードしました。この関数は、v0 < v1 からある程度の余裕がある場合に true を返します。重複は削除されますが、セット内の有効な値も削除されます。私のセットには12個のVec3fsが必要であることを知っています。重複すると、24 個の Vec3fs があります。私の比較関数では、Vec3f は 3 つしかありません。絶対差を使用することを検討しましたが、それは厳密な弱い順序付け基準に違反しています。私の質問は次のとおりです。重複を削除して一意のアイテムのみを保持する比較関数を作成するにはどうすればよいですか?

4

3 に答える 3

2

現在のように、 のすべてのコンポーネントは のv0すべてのコンポーネントよりも少なくする必要がありますv1。これは厳密な弱い順序付けではありません。一度に 1 つのコンポーネントをチェックする必要があります。現在チェックしているコンポーネントが等しい場合にのみ、後続のコンポーネントをチェックします。また、イプシロンをドロップする必要があります。これは浮動小数点計算の結果の等価性をチェックするのに役立ちますが、厳密な弱い順序付けにも違反するため、順序付けには役立ちません。これを行う最も簡単な方法は、 for を使用することoperator<ですstd::tuple

return std::tie(v0[0], v0[1], v0[2]) < std::tie(v1[0], v1[1], v1[2]);

それ以外の場合、これを手動で実装する場合は、次のようになります。

if (v0[0] < v1[0]) return true;
if (v0[0] > v1[0]) return false;
if (v0[1] < v1[1]) return true;
if (v0[1] > v1[1]) return false;
if (v0[2] < v1[2]) return true;
if (v0[2] > v1[2]) return false;
return false;
于 2014-11-20T02:48:58.777 に答える
1

のようstd::absに との違いを比較するために使用しますepsilon

if(std::abs(v1[0]-v0[1]) > epsilon && ...){...} // not zero

そうしないと、常に よりも小さい負の結果が得られる可能性がepsilonあり、ノルム テストは失敗します。

PS: 一般に、直感的な数学的順序付けがなく、多くの奇妙で直感に反する状況に陥る可能性があるため、ベクトルを順序付けようとするのは悪い考えです。

于 2014-11-20T02:42:15.170 に答える