00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "main.h"
00026 #include <Eigen/Geometry>
00027 #include <Eigen/LU>
00028 #include <Eigen/SVD>
00029
00030
00031
00032
00033
00034 template<typename Scalar> void orthomethods_3()
00035 {
00036 typedef typename NumTraits<Scalar>::Real RealScalar;
00037 typedef Matrix<Scalar,3,3> Matrix3;
00038 typedef Matrix<Scalar,3,1> Vector3;
00039
00040 typedef Matrix<Scalar,4,1> Vector4;
00041
00042 Vector3 v0 = Vector3::Random(),
00043 v1 = Vector3::Random(),
00044 v2 = Vector3::Random();
00045
00046
00047 VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(v2).dot(v1), Scalar(1));
00048 VERIFY_IS_MUCH_SMALLER_THAN(v1.dot(v1.cross(v2)), Scalar(1));
00049 VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(v2).dot(v2), Scalar(1));
00050 VERIFY_IS_MUCH_SMALLER_THAN(v2.dot(v1.cross(v2)), Scalar(1));
00051 Matrix3 mat3;
00052 mat3 << v0.normalized(),
00053 (v0.cross(v1)).normalized(),
00054 (v0.cross(v1).cross(v0)).normalized();
00055 VERIFY(mat3.isUnitary());
00056
00057
00058
00059 mat3.setRandom();
00060 Vector3 vec3 = Vector3::Random();
00061 Matrix3 mcross;
00062 int i = internal::random<int>(0,2);
00063 mcross = mat3.colwise().cross(vec3);
00064 VERIFY_IS_APPROX(mcross.col(i), mat3.col(i).cross(vec3));
00065 mcross = mat3.rowwise().cross(vec3);
00066 VERIFY_IS_APPROX(mcross.row(i), mat3.row(i).cross(vec3));
00067
00068
00069 Vector4 v40 = Vector4::Random(),
00070 v41 = Vector4::Random(),
00071 v42 = Vector4::Random();
00072 v40.w() = v41.w() = v42.w() = 0;
00073 v42.template head<3>() = v40.template head<3>().cross(v41.template head<3>());
00074 VERIFY_IS_APPROX(v40.cross3(v41), v42);
00075
00076
00077 typedef Matrix<RealScalar, 3, 1> RealVector3;
00078 RealVector3 rv1 = RealVector3::Random();
00079 VERIFY_IS_APPROX(v1.cross(rv1.template cast<Scalar>()), v1.cross(rv1));
00080 VERIFY_IS_APPROX(rv1.template cast<Scalar>().cross(v1), rv1.cross(v1));
00081 }
00082
00083 template<typename Scalar, int Size> void orthomethods(int size=Size)
00084 {
00085 typedef typename NumTraits<Scalar>::Real RealScalar;
00086 typedef Matrix<Scalar,Size,1> VectorType;
00087 typedef Matrix<Scalar,3,Size> Matrix3N;
00088 typedef Matrix<Scalar,Size,3> MatrixN3;
00089 typedef Matrix<Scalar,3,1> Vector3;
00090
00091 VectorType v0 = VectorType::Random(size),
00092 v1 = VectorType::Random(size),
00093 v2 = VectorType::Random(size);
00094
00095
00096 VERIFY_IS_MUCH_SMALLER_THAN(v0.unitOrthogonal().dot(v0), Scalar(1));
00097 VERIFY_IS_APPROX(v0.unitOrthogonal().norm(), RealScalar(1));
00098
00099 if (size>=3)
00100 {
00101 v0.template head<2>().setZero();
00102 v0.tail(size-2).setRandom();
00103
00104 VERIFY_IS_MUCH_SMALLER_THAN(v0.unitOrthogonal().dot(v0), Scalar(1));
00105 VERIFY_IS_APPROX(v0.unitOrthogonal().norm(), RealScalar(1));
00106 }
00107
00108
00109 Vector3 vec3 = Vector3::Random();
00110 int i = internal::random<int>(0,size-1);
00111
00112 Matrix3N mat3N(3,size), mcross3N(3,size);
00113 mat3N.setRandom();
00114 mcross3N = mat3N.colwise().cross(vec3);
00115 VERIFY_IS_APPROX(mcross3N.col(i), mat3N.col(i).cross(vec3));
00116
00117 MatrixN3 matN3(size,3), mcrossN3(size,3);
00118 matN3.setRandom();
00119 mcrossN3 = matN3.rowwise().cross(vec3);
00120 VERIFY_IS_APPROX(mcrossN3.row(i), matN3.row(i).cross(vec3));
00121 }
00122
00123 void test_geo_orthomethods()
00124 {
00125 for(int i = 0; i < g_repeat; i++) {
00126 CALL_SUBTEST_1( orthomethods_3<float>() );
00127 CALL_SUBTEST_2( orthomethods_3<double>() );
00128 CALL_SUBTEST_4( orthomethods_3<std::complex<double> >() );
00129 CALL_SUBTEST_1( (orthomethods<float,2>()) );
00130 CALL_SUBTEST_2( (orthomethods<double,2>()) );
00131 CALL_SUBTEST_1( (orthomethods<float,3>()) );
00132 CALL_SUBTEST_2( (orthomethods<double,3>()) );
00133 CALL_SUBTEST_3( (orthomethods<float,7>()) );
00134 CALL_SUBTEST_4( (orthomethods<std::complex<double>,8>()) );
00135 CALL_SUBTEST_5( (orthomethods<float,Dynamic>(36)) );
00136 CALL_SUBTEST_6( (orthomethods<double,Dynamic>(35)) );
00137 }
00138 }