我目前正在用c ++实现一个简单的光线跟踪器。我有一个名为OrthonormalBasis的类,它从一个或两个指定的向量生成三个正交单位向量,例如:
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,并且仍然代表有效的标准正交基础。有没有办法指定多个预期值?或者你知道另一种方法吗?
重要的是,我将实际值和期望值打印到stdout,以便调试方法,以便此解决方案无法完成工作:
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() );
}
答案 0 :(得分: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));
答案 1 :(得分:0)
一种可能性是创建自己的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);
}
答案 2 :(得分:0)
我会使用实用功能或类,所以你可以这样做:
CHECK_EQUAL(VectorList(0,0,1)(0,0,-1), onb.v());
鉴于,对平等的解释有些奇怪,但它应该打印出您想要看到的所有值,而无需引入自定义宏。
如果您在该上下文中担心EQUAL
,那么像CHECK_CONTAINS()
这样的自定义宏应该不会太难做到。
VectorList
将构建为临时的operator()
,用于将值插入包含的Vector
列表中,类似于 Boost.Assign 。
基本方法:
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();
}
};