1

現在、C++ で単純なレイ トレーサーを実装しています。OrthonormalBasis という名前のクラスがあります。これは、1 つまたは 2 つの指定されたベクトルから 3 つの直交単位ベクトルを生成します。次に例を示します。

void
OrthonormalBasis::init_from_u ( const Vector& u )
{
    Vector n(1,0,0);
    Vector m(0,1,0);
    u_ = unify(u);
    v_ = cross(u_,n);
    if ( v_.length() < ONB_EPSILON )
        v_ = cross(u_,m);
    w_ = cross(u_,v_);
}

Unittest++ フレームワークですべてのメソッドをテストしています。問題は、有効な正規直交基底に対して複数の可能な解があることです。たとえば、このテスト:

TEST ( orthonormalbasis__should_init_from_u )
{
    Vector u(1,0,0);
    OrthonormalBasis onb;

    onb.init_from_u(u);

    CHECK_EQUAL( Vector( 1, 0, 0 ), onb.u() );
    CHECK_EQUAL( Vector( 0, 0, 1 ), onb.v() );
    CHECK_EQUAL( Vector( 0, 1, 0 ), onb.w() );
}

ベクトル v と w は負の 1 を持つこともあり、それでも有効な正規直交基底を表しているため、成功することも失敗することもあります。複数の期待値を指定する方法はありますか? または、それを行う別の方法を知っていますか?

メソッドをデバッグするために、実際の値と期待される値を標準出力に出力して、このソリューションが機能しないようにすることが重要です。

TEST ( orthonormalbasis__should_init_from_u )
{
    Vector u(1,0,0);
    OrthonormalBasis onb;

    onb.init_from_u(u);

    CHECK_EQUAL( Vector( 1, 0, 0 ), onb.u() );
    CHECK(
        Vector( 0, 0, 1 ) == onb.v() ||
        Vector( 0, 0,-1 ) == onb.v() );
    CHECK(
        Vector( 0, 1, 0 ) == onb.w() ||
        Vector( 0,-1, 0 ) == onb.w() );
}
4

3 に答える 3

1

確かに、あなたがテストしているのは、基底が正規直交であるかどうかだけである場合、それをテストする必要がありますか?

// check orthogonality

CHECK_EQUAL( 0, dot(onb.u(), onb.v));
CHECK_EQUAL( 0, dot(onb.u(), onb.w));
CHECK_EQUAL( 0, dot(onb.v(), onb.w));

// check normality

CHECK_EQUAL( 1, dot(onb.u(), onb.u));
CHECK_EQUAL( 1, dot(onb.v(), onb.v));
CHECK_EQUAL( 1, dot(onb.w(), onb.w));
于 2010-01-25T20:39:01.697 に答える
0

次のようなことができるように、ユーティリティ関数またはクラスを使用します。

CHECK_EQUAL(VectorList(0,0,1)(0,0,-1), onb.v());

等式の解釈はやや奇妙ですが、カスタム マクロを導入する必要なく、表示したいすべての値を出力する必要があります。そのコンテキストで
心配している場合は、次のようなカスタム マクロを実行するのはそれほど難しくありません。EQUALCHECK_CONTAINS()

VectorListBoost.Assignと同様に、一時的なものとして構築され、含まれているs のoperator()リストに値を挿入するために使用されます。Vector

基本的なアプローチ:

class VectorList {
    std::vector<Vector> data_;
public:
    VectorList(double a, double b, double c) {
        data_.push_back(Vector(a,b,c));
    }
    VectorList& operator()(double a, double b, double c) {
        data_.push_back(Vector(a,b,c));
        return *this;
    }
    bool operator==(const Vector& rhs) const {
        return std::find(data_.begin(), data_.end(), rhs) != data_.end();
    }
};
于 2010-01-25T19:29:51.930 に答える
0

1 つの可能性は、独自の CHECK_MULTI 関数を作成することです。

void CHECK_MULTI(TYPE actual, vector<TYPE> expected, const char* message)
{
  for (element in expected) {
    if (element == actual) {
      // there's a test here so the test count is correct
      CHECK(actual, element);
      return;   
    }
  }
  CHECK(actual, expected);
}
于 2010-01-25T19:05:08.243 に答える