00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef OST_GEOM_VEC_MAT_PREDICATES_HH
00020 #define OST_GEOM_VEC_MAT_PREDICATES_HH
00021 #include <boost/version.hpp>
00022 #include <boost/test/unit_test.hpp>
00023 #include <boost/test/floating_point_comparison.hpp>
00024 #include <ost/geom/geom.hh>
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 template<class V>
00035 boost::test_tools::predicate_result vec_is_close(const V& v1, const V& v2,
00036 Real tolerance,
00037 unsigned int dim)
00038 {
00039 std::string labels[]={"x","y","z","w"};
00040 bool flag=true;
00041 boost::test_tools::predicate_result res( false );
00042 #if BOOST_VERSION<105900
00043 boost::test_tools::close_at_tolerance<Real> close_test(boost::test_tools::percent_tolerance(tolerance));
00044 #else
00045 boost::math::fpc::close_at_tolerance<Real> close_test(boost::math::fpc::percent_tolerance(tolerance));
00046 #endif
00047 for(unsigned int i=0;i<dim;++i){
00048 if(v1[i]==0.0){
00049 if(!boost::test_tools::check_is_small(v2[i],tolerance)){
00050 flag=false;
00051 res.message() << "Value for " << labels[i] << " differs: ( " << v1[i] << " != " << v2[i] << " ). ";
00052 }
00053 }else if (v2[i]==0.0){
00054 if(!boost::test_tools::check_is_small(v1[i],tolerance)){
00055 flag=false;
00056 res.message() << "Value for "<< labels[i] << " differs: ( " << v1[i] << " != " << v2[i] << " ). ";
00057 }
00058 }else{
00059 if(!close_test(v1[i],v2[i])){
00060 flag=false;
00061 res.message() << "Value for " << labels[i] << " differs: ( " << v1[i] << " != " << v2[i] << " ). ";
00062 }
00063 }
00064 }
00065 if(flag){
00066 return true;
00067 }else{
00068 return res;
00069 }
00070 }
00071
00072 boost::test_tools::predicate_result vec2_is_close(const geom::Vec2& v1,
00073 const geom::Vec2& v2,
00074 Real tolerance=geom::EPSILON)
00075 {
00076 return vec_is_close<geom::Vec2>(v1,v2,tolerance,2);
00077 }
00078
00079 boost::test_tools::predicate_result vec3_is_close(const geom::Vec3& v1,
00080 const geom::Vec3& v2,
00081 Real tolerance=geom::EPSILON)
00082 {
00083 return vec_is_close<geom::Vec3>(v1,v2,tolerance,3);
00084 }
00085
00086 boost::test_tools::predicate_result vec4_is_close(const geom::Vec4& v1,
00087 const geom::Vec4& v2,
00088 Real tolerance=geom::EPSILON)
00089 {
00090 return vec_is_close<geom::Vec4>(v1,v2,tolerance,4);
00091 }
00092
00093 template<class M>
00094 boost::test_tools::predicate_result mat_is_close(const M& m1, const M& m2,
00095 Real tolerance,
00096 unsigned int dim)
00097 {
00098 bool flag=true;
00099 boost::test_tools::predicate_result res( false );
00100 #if BOOST_VERSION<105900
00101 boost::test_tools::close_at_tolerance<Real> close_test(boost::test_tools::percent_tolerance(tolerance));
00102 #else
00103 boost::math::fpc::close_at_tolerance<Real> close_test(boost::math::fpc::percent_tolerance(tolerance));
00104 #endif
00105 for(unsigned int i=0;i<dim;++i){
00106 for(unsigned int j=0;j<dim;++j){
00107 if(m1(i,j)==0.0){
00108 if(!boost::test_tools::check_is_small(m2(i,j),tolerance)){
00109 flag=false;
00110 res.message() << "Value for (" << i << "," << j << ") differs: (" << m1(i,j) << "!=" << m2(i,j) << "). ";
00111 }
00112 }else if (m2(i,j)==0.0){
00113 if(!boost::test_tools::check_is_small(m1(i,j),tolerance)){
00114 flag=false;
00115 res.message() << "Value for (" << i << "," << j << ") differs: (" << m1(i,j) << "!=" << m2(i,j) << "). ";
00116 }
00117 }else{
00118 if(!close_test(m1(i,j),m2(i,j))){
00119 flag=false;
00120 res.message() << "Value for (" << i << "," << j << ") differs: (" << m1(i,j) << "!=" << m2(i,j) << "). ";
00121 }
00122 }
00123 }
00124 }
00125 if(flag){
00126 return true;
00127 }else{
00128 return res;
00129 }
00130 }
00131
00132 boost::test_tools::predicate_result mat2_is_close(const geom::Mat2& m1,
00133 const geom::Mat2& m2,
00134 Real tolerance=geom::EPSILON)
00135 {
00136 return mat_is_close<geom::Mat2>(m1,m2,tolerance,2);
00137 }
00138
00139 boost::test_tools::predicate_result mat3_is_close(const geom::Mat3& m1,
00140 const geom::Mat3& m2,
00141 Real tolerance=geom::EPSILON)
00142 {
00143 return mat_is_close<geom::Mat3>(m1,m2,tolerance,3);
00144 }
00145
00146 boost::test_tools::predicate_result mat4_is_close(const geom::Mat4& m1,
00147 const geom::Mat4& m2,
00148 Real tolerance=geom::EPSILON)
00149 {
00150 return mat_is_close<geom::Mat4>(m1,m2,tolerance,4);
00151 }
00152
00153 #endif