34 #include <boost/assign/std/vector.hpp> 35 #include <boost/numeric/ublas/io.hpp> 36 #include <boost/numeric/ublas/matrix.hpp> 37 #include <boost/numeric/ublas/matrix_proxy.hpp> 75 if (matrix.size1() != matrix.size2())
return false;
77 for (
unsigned int row = 0;
row < matrix.size1();
row++) {
78 for (
unsigned int col = 0; col < matrix.size2(); col++) {
80 if (!qFuzzyCompare(matrix(
row, col), 1.0))
return false;
85 if (!qFuzzyCompare(1.0 + matrix(
row, col), 1.0))
return false;
103 if (matrix.size1() != matrix.size2())
return false;
128 if (matrix.size1() != matrix.size2())
return false;
184 Matrix unitMatrix(matrix.size1(), matrix.size2());
186 for (
unsigned int i = 0; i < unitMatrix.size1(); i++) {
190 double columnMagnitude =
magnitude(columnVector);
191 if ( columnMagnitude < 0.9 || columnMagnitude > 1.1 ) {
196 setColumn(unitMatrix, columnVector / columnMagnitude, i);
204 if ( det >= 0.9 && det <= 1.1 ) {
210 QString msg =
"Unable to determine whether the given matrix is a rotation matrix.";
225 for (
unsigned int i = 0; i < matrix.size1(); i++) {
226 for (
unsigned int j = 0; j < matrix.size2(); j++) {
229 if (!qFuzzyCompare(matrix(i, j) + 1.0, 1.0))
return false;
245 for (
unsigned int i = 0; i <
vector.size(); i++) {
248 if (!qFuzzyCompare(
vector(i) + 1.0, 1.0))
return false;
304 if (qFuzzyCompare(det + 1.0, 1.0)) {
306 QString msg =
"The given matrix is not invertible. The determinant is 0.0.";
311 double scale = 1 / det;
315 if (matrix.size1() == 2) {
316 inverse(0, 0) = scale * matrix(1, 1);
317 inverse(0, 1) = -scale * matrix(0, 1);
319 inverse(1, 0) = -scale * matrix(1, 0);
320 inverse(1, 1) = scale * matrix(0, 0);
324 inverse(0, 0) = scale * ( matrix(1, 1) * matrix(2, 2) - matrix(2, 1) * matrix(1, 2) );
325 inverse(0, 1) = scale * ( matrix(0, 2) * matrix(2, 1) - matrix(2, 2) * matrix(0, 1) );
326 inverse(0, 2) = scale * ( matrix(0, 1) * matrix(1, 2) - matrix(1, 1) * matrix(0, 2) );
328 inverse(1, 0) = scale * ( matrix(1, 2) * matrix(2, 0) - matrix(2, 2) * matrix(1, 0) );
329 inverse(1, 1) = scale * ( matrix(0, 0) * matrix(2, 2) - matrix(2, 0) * matrix(0, 2) );
330 inverse(1, 2) = scale * ( matrix(0, 2) * matrix(0, 1) - matrix(1, 2) * matrix(0, 0) );
332 inverse(2, 0) = scale * ( matrix(1, 0) * matrix(2, 1) - matrix(2, 0) * matrix(1, 1) );
333 inverse(2, 1) = scale * ( matrix(0, 1) * matrix(2, 0) - matrix(2, 1) * matrix(0, 0) );
334 inverse(2, 2) = scale * ( matrix(0, 0) * matrix(1, 1) - matrix(1, 0) * matrix(0, 1) );
339 QString msg =
"Unable to invert the given matrix.";
354 return boost::numeric::ublas::trans(matrix);
369 QString msg =
"Can not create identity matrix of negative size [" 375 for (
int i = 0; i < size; i++) {
392 boost::numeric::ublas::zero_matrix<double> m(rows, columns);
405 boost::numeric::ublas::zero_vector<double> v(size);
424 if ( (matrix.size1() != matrix.size2()) || (matrix.size1() != 2 && matrix.size1() != 3) ) {
425 QString msg =
"Unable to calculate the determinant for the given matrix. " 426 "This method only calculates the determinant for 2x2 or 3x3 matrices." 427 "The given matrix is [" +
toString((
int) matrix.size1()) +
"x" 428 +
toString((
int) matrix.size2()) +
"].";
432 if (matrix.size1() == 2) {
433 return matrix(0, 0) * matrix(1, 1) - matrix(1, 0) * matrix(0, 1);
437 return matrix(0, 0) * (matrix(1, 1)*matrix(2, 2) - matrix(1, 2)*matrix(2, 1))
438 - matrix(0, 1) * (matrix(1, 0)*matrix(2, 2) - matrix(1, 2)*matrix(2, 0))
439 + matrix(0, 2) * (matrix(1, 0)*matrix(2, 1) - matrix(1, 1)*matrix(2, 0));
463 QString msg =
"Unable to normalize the zero vector.";
515 return boost::numeric::ublas::norm_inf(
vector);
534 if (matrix1.size2() != matrix2.size1()) {
535 QString msg =
"Unable to multiply matrices with mismatched dimensions. " 536 "The left matrix has [" +
toString((
int) matrix1.size2())
537 +
"] columns and the right matrix has [" +
toString((
int) matrix2.size1())
544 return boost::numeric::ublas::prod(matrix1, matrix2);
565 if (matrix.size2() !=
vector.size()) {
566 QString msg =
"Unable to multiply matrix and vector with mismatched dimensions." 568 +
"] components and the given matrix has [" 569 +
toString((
int) matrix.size2()) +
"] columns.";
574 return boost::numeric::ublas::prod(matrix,
vector);
602 return scalar * matrix;
619 if (vector1.size() != vector2.size()) {
620 QString msg =
"Unable to add vectors with mismatched sizes." 621 "Vector1 has [" +
toString((
int) vector1.size())
622 +
"] components and vector2 has [" 623 +
toString((
int) vector2.size()) +
"] components.";
627 return vector1 + vector2;
645 if (vector1.size() != vector2.size()) {
646 QString msg =
"Unable to subtract vectors with mismatched sizes." 647 "Vector1 has [" +
toString((
int) vector1.size())
648 +
"] components and vector2 has [" 649 +
toString((
int) vector2.size()) +
"] components.";
653 return vector1 - vector2;
672 if ((vector1.size() != 3) || (vector2.size() != 3)) {
673 QString msg =
"Unable to calculate the cross product on vectors that are not size 3. " 674 "Vector1 has [" +
toString((
int) vector1.size())
675 +
"] components and vector2 has [" 676 +
toString((
int) vector2.size()) +
"] components.";
681 crossProd(0) = vector1(1)*vector2(2) - vector1(2)*vector2(1);
682 crossProd(1) = vector1(2)*vector2(0) - vector1(0)*vector2(2);
683 crossProd(2) = vector1(0)*vector2(1) - vector1(1)*vector2(0);
713 if (maxVector1 != 0.0) {
714 normalizedVector1 /= maxVector1;
717 if (maxVector2 != 0.0) {
718 normalizedVector2 /= maxVector2;
741 if (vector1.size() != vector2.size()) {
742 QString msg =
"Unable to compute the outer product for vectors with mismatched sizes." 743 "Vector1 has [" +
toString((
int) vector1.size())
744 +
"] components and vector2 has [" 745 +
toString((
int) vector2.size()) +
"] components.";
748 return boost::numeric::ublas::outer_prod(vector1, vector2);
785 if (vector1.size() != vector2.size()) {
786 QString msg =
"Unable to compute the dot product for vectors with mismatched sizes." 787 "Vector1 has [" +
toString((
int) vector1.size())
788 +
"] components and vector2 has [" 789 +
toString((
int) vector2.size()) +
"] components.";
792 return boost::numeric::ublas::inner_prod(vector1, vector2);
817 if (vector1.size() != vector2.size()) {
818 QString msg =
"Unable to project vector1 onto vector2 with mismatched sizes." 819 "Vector1 has [" +
toString((
int) vector1.size())
820 +
"] components and vector2 has [" 821 +
toString((
int) vector2.size()) +
"] components.";
835 return v1Dotv2/v2Dotv2 * vector2;
857 if ((
vector.size() != 3) || (axis.size() != 3)) {
858 QString msg =
"Unable to rotate vector about the given axis and angle. " 859 "Vectors must be of size 3 to perform rotation. " 861 +
"] components and the given axis has [" 862 +
toString((
int) axis.size()) +
"] components.";
884 double c = cos(angle.
radians());
885 double s = sin(angle.
radians());
886 Vector rplane = (c*v1) + (s*v2);
890 return (rplane + projVectorOnAxis);
930 Vector parallelVector =
project(vector1 / max1, vector2 / max2);
932 Vector perpendicularVector = vector1 - parallelVector * max1;
934 return perpendicularVector;
958 if ((rotationMatrix.size1() != 3) || (rotationMatrix.size2() != 3)) {
959 QString msg =
"Unable to convert the given matrix to an axis of rotation " 960 "and a rotation angle. A 3x3 matrix is required. The given matrix is [" 961 +
toString((
int) rotationMatrix.size1()) +
"x" 962 +
toString((
int) rotationMatrix.size2()) +
"].";
968 QString msg =
"Unable to convert the given matrix to an axis of rotation " 969 "and a rotation angle. The given matrix is not a rotation matrix.";
980 subQuaternion[0] = quaternion[1];
981 subQuaternion[1] = quaternion[2];
982 subQuaternion[2] = quaternion[3];
991 if (
isZero(subQuaternion)) {
998 else if (qFuzzyCompare(quaternion(0) + 1.0, 1.0)) {
999 axis = subQuaternion;
1007 return qMakePair(axis, angle);
1038 if (axes.size() != 3) {
1039 QString msg =
"Unable to convert the given matrix to Euler angles. " 1040 "Exactly 3 axis codes are required. The given list has [" 1041 +
toString((
int) axes.size()) +
"] axes.";
1046 validAxes << 1 << 2 << 3;
1047 if (!validAxes.contains(axes[0])
1048 || !validAxes.contains(axes[1])
1049 || !validAxes.contains(axes[2])) {
1050 QString msg =
"Unable to convert the given matrix to Euler angles using the given axis codes " 1052 +
"]. Axis codes must be 1, 2, or 3.";
1056 if (axes[0] == axes[1] || axes[1] == axes[2]) {
1057 QString msg =
"Unable to convert the given matrix to Euler angles using the given axis codes " 1059 +
"]. The middle axis code must differ from its neighbors.";
1064 if ((rotationMatrix.size1() != 3) || (rotationMatrix.size2() != 3)) {
1065 QString msg =
"Unable to convert the given matrix to Euler angles. A 3x3 matrix is required. " 1066 "The given matrix is [" 1067 +
toString((
int) rotationMatrix.size1()) +
"x" 1068 +
toString((
int) rotationMatrix.size2()) +
"].";
1073 QString msg =
"Unable to convert the given matrix to Euler angles. " 1074 "The given matrix is not a rotation matrix.";
1086 for (
int i = 0; i < 3; i++) {
1093 nextAxis << 2 << 3 << 1;
1098 Angle angle1, angle2, angle3;
1099 if ( axes[0] == axes[2] ) {
1100 if ( axes[1] == nextAxis[axes[0] - 1] ) {
1106 int c = 6 - axes[0] - axes[1];
1108 change( axes[0] - 1, 2 ) = 1.0;
1109 change( axes[1] - 1, 0 ) = 1.0;
1110 change( c - 1, 1 ) = sign * 1.0;
1114 bool degen = ( qFuzzyCompare(tempRotation(0, 2) + 1.0, 1.0)
1115 && qFuzzyCompare(tempRotation(1, 2) + 1.0, 1.0) )
1116 || ( qFuzzyCompare(tempRotation(2, 0) + 1.0, 1.0)
1117 && qFuzzyCompare(tempRotation(2, 1) + 1.0, 1.0) )
1118 || qFuzzyCompare( qAbs(tempRotation(2, 2)), 1.0 );
1123 angle2.
setRadians( acos( tempRotation(2, 2) ) );
1124 angle1.
setRadians( atan2( tempRotation(0, 1), tempRotation(0, 0) ) );
1129 angle3.
setRadians( atan2( tempRotation(0, 2), tempRotation(1, 2) ) );
1130 angle2.
setRadians( acos( tempRotation(2, 2) ) );
1131 angle1.
setRadians( atan2( tempRotation(2, 0), -tempRotation(2, 1) ) );
1140 if ( axes[1] == nextAxis[axes[0] - 1] ) {
1146 change( axes[0] - 1, 0 ) = 1.0;
1147 change( axes[1] - 1, 1 ) = 1.0;
1148 change( axes[2] - 1, 2 ) = sign * 1.0;
1151 bool degen = ( qFuzzyCompare(tempRotation(0, 0) + 1.0, 1.0)
1152 && qFuzzyCompare(tempRotation(0, 1) + 1.0, 1.0) )
1153 || ( qFuzzyCompare(tempRotation(1, 2) + 1.0, 1.0)
1154 && qFuzzyCompare(tempRotation(2, 2) + 1.0, 1.0) )
1155 || qFuzzyCompare( qAbs(tempRotation(0, 2)), 1.0 );
1160 angle2.
setRadians( asin( -tempRotation(0, 2) ) );
1161 angle1.
setRadians( sign * atan2( -tempRotation(1, 0), tempRotation(1, 1) ) );
1166 angle3.
setRadians( atan2( tempRotation(1, 2), tempRotation(2, 2) ) );
1167 angle2.
setRadians( asin( -tempRotation(0, 2) ) );
1168 angle1.
setRadians( sign * atan2( tempRotation(0, 1), tempRotation(0, 0) ) );
1173 eulerAngles << qMakePair(angle3, axes[0])
1174 << qMakePair(angle2, axes[1])
1175 << qMakePair(angle1, axes[2]);
1196 if ((rotationMatrix.size1() != 3) || (rotationMatrix.size2() != 3)) {
1197 QString msg =
"Unable to convert the given matrix to a quaternion. " 1198 "A 3x3 matrix is required. The given matrix is [" 1199 +
toString((
int) rotationMatrix.size1()) +
"x" 1200 +
toString((
int) rotationMatrix.size2()) +
"].";
1206 QString msg =
"Unable to convert the given matrix to an axis of rotation " 1207 "and a rotation angle. The given matrix is not a rotation matrix.";
1302 double trace = rotationMatrix(0, 0) + rotationMatrix(1, 1) + rotationMatrix(2, 2);
1303 double mtrace = 1.0 - trace;
1306 double cc4 = 1.0 + trace;
1308 double s114 = mtrace + 2.0*rotationMatrix(0, 0);
1309 double s224 = mtrace + 2.0*rotationMatrix(1, 1);
1310 double s334 = mtrace + 2.0*rotationMatrix(2, 2);
1314 double normalizingFactor;
1318 quaternion[0] = sqrt( cc4 * 0.25 );
1319 normalizingFactor = 1.0 / ( quaternion[0] * 4.0 );
1324 quaternion[1] = ( rotationMatrix(2, 1) - rotationMatrix(1, 2) ) * normalizingFactor;
1325 quaternion[2] = ( rotationMatrix(0, 2) - rotationMatrix(2, 0) ) * normalizingFactor;
1326 quaternion[3] = ( rotationMatrix(1, 0) - rotationMatrix(0, 1) ) * normalizingFactor;
1329 else if ( s114 >= 1.0 ) {
1331 quaternion[1] = sqrt( s114 * 0.25 );
1332 normalizingFactor = 1.0 /( quaternion[1] * 4.0 );
1334 quaternion[0] = ( rotationMatrix(2, 1) - rotationMatrix(1, 2) ) * normalizingFactor;
1335 quaternion[2] = ( rotationMatrix(0, 1) + rotationMatrix(1, 0) ) * normalizingFactor;
1336 quaternion[3] = ( rotationMatrix(0, 2) + rotationMatrix(2, 0) ) * normalizingFactor;
1339 else if ( s224 >= 1.0 ) {
1341 quaternion[2] = sqrt( s224 * 0.25 );
1342 normalizingFactor = 1.0 /( quaternion[2] * 4.0 );
1344 quaternion[0] = ( rotationMatrix(0, 2) - rotationMatrix(2, 0) ) * normalizingFactor;
1345 quaternion[1] = ( rotationMatrix(0, 1) + rotationMatrix(1, 0) ) * normalizingFactor;
1346 quaternion[3] = ( rotationMatrix(1, 2) + rotationMatrix(2, 1) ) * normalizingFactor;
1350 quaternion[3] = sqrt( s334 * 0.25 );
1351 normalizingFactor = 1.0 /( quaternion[3] * 4.0 );
1353 quaternion[0] = ( rotationMatrix(1, 0) - rotationMatrix(0, 1) ) * normalizingFactor;
1354 quaternion[1] = ( rotationMatrix(0, 2) + rotationMatrix(2, 0) ) * normalizingFactor;
1355 quaternion[2] = ( rotationMatrix(1, 2) + rotationMatrix(2, 1) ) * normalizingFactor;
1360 if ( !
isUnit(quaternion) ) {
1365 if ( quaternion[0] < 0.0 ) {
1389 if (axis.size() != 3) {
1390 QString msg =
"Unable to convert the given vector and angle to a rotation matrix. " 1391 "The given vector with size [" +
toString((
int) axis.size())
1392 +
"] is not a 3D axis vector.";
1403 for (
unsigned int i = 0; i < axis.size(); i++) {
1412 return rotationMatrix;
1449 validAxes << 1 << 2 << 3;
1450 if (!validAxes.contains(angle3.second)
1451 || !validAxes.contains(angle2.second)
1452 || !validAxes.contains(angle1.second)) {
1453 QString msg =
"Unable to convert the given Euler angles to a matrix using the given axis " 1454 "codes [" +
toString(angle3.second) +
", " +
toString(angle2.second) +
", " 1455 +
toString(angle1.second) +
"]. Axis codes must be 1, 2, or 3.";
1466 double sinAngle = sin(angle1.first.radians());
1467 double cosAngle = cos(angle1.first.radians());
1469 double indexOffset = ((angle1.second % 3) + 3) % 3;
1471 indexSet << 2 << 0 << 1 << 2 << 0;
1472 int index1 = indexSet[indexOffset + 0];
1473 int index2 = indexSet[indexOffset + 1];
1474 int index3 = indexSet[indexOffset + 2];
1475 m(index1, index1) = 1.0; m(index1, index2) = 0.0; m(index1, index3) = 0.0;
1476 m(index2, index1) = 0.0; m(index2, index2) = cosAngle; m(index2, index3) = sinAngle;
1477 m(index3, index1) = 0.0; m(index3, index2) = -sinAngle; m(index3, index3) = cosAngle;
1485 sinAngle = sin(angle2.first.radians());
1486 cosAngle = cos(angle2.first.radians());
1487 indexOffset = ((angle2.second % 3) + 3) % 3;
1488 index1 = indexSet[indexOffset + 0];
1489 index2 = indexSet[indexOffset + 1];
1490 index3 = indexSet[indexOffset + 2];
1493 for (
int i = 0; i < 3; i++) {
1494 tempMatrix(index1, i) = m(index1, i);
1495 tempMatrix(index2, i) = cosAngle*m(index2, i) + sinAngle*m(index3, i);
1496 tempMatrix(index3, i) = -sinAngle*m(index2, i) + cosAngle*m(index3, i);
1500 sinAngle = sin(angle3.first.radians());
1501 cosAngle = cos(angle3.first.radians());
1502 indexOffset = ((angle3.second % 3) + 3) % 3;
1503 index1 = indexSet[indexOffset + 0];
1504 index2 = indexSet[indexOffset + 1];
1505 index3 = indexSet[indexOffset + 2];
1506 for (
int i = 0; i < 3; i++) {
1507 m(index1, i) = tempMatrix(index1, i);
1508 m(index2, i) = cosAngle*tempMatrix(index2, i) + sinAngle*tempMatrix(index3, i);
1509 m(index3, i) = -sinAngle*tempMatrix(index2, i) + cosAngle*tempMatrix(index3, i);
1530 if (eulerAngles.size() != 3) {
1531 QString msg =
"Unable to convert the given Euler angles to a matrix. " 1532 "Exactly 3 Euler angles are required. The given list has [" 1533 +
toString((
int) eulerAngles.size()) +
"] angles.";
1556 if (quaternion.size() != 4) {
1557 QString msg =
"Unable to convert the given vector to a rotation matrix. " 1558 "The given vector with [" +
toString((
int) quaternion.size())
1559 +
"] components is not a quaternion.";
1570 double q0q1 = q[0] * q[1];
1571 double q0q2 = q[0] * q[2];
1572 double q0q3 = q[0] * q[3];
1574 double q1q1 = q[1] * q[1];
1575 double q1q2 = q[1] * q[2];
1576 double q1q3 = q[1] * q[3];
1578 double q2q2 = q[2] * q[2];
1579 double q2q3 = q[2] * q[3];
1581 double q3q3 = q[3] * q[3];
1583 matrix(0, 0) = 1.0 - 2.0 * ( q2q2 + q3q3 );
1584 matrix(0, 1) = 2.0 * ( q1q2 - q0q3 );
1585 matrix(0, 2) = 2.0 * ( q1q3 + q0q2 );
1587 matrix(1, 0) = 2.0 * ( q1q2 + q0q3 );
1588 matrix(1, 1) = 1.0 - 2.0 * ( q1q1 + q3q3 );
1589 matrix(1, 2) = 2.0 * ( q2q3 - q0q1 );
1591 matrix(2, 0) = 2.0 * ( q1q3 - q0q2 );
1592 matrix(2, 1) = 2.0 * ( q2q3 + q0q1 );
1593 matrix(2, 2) = 1.0 - 2.0 * ( q1q1 + q2q2 );
1610 if ( (rowIndex+1 > (
int) matrix.size1()) ) {
1611 QString msg =
"Unable to set the matrix row to the given vector. Row index " 1612 +
toString(rowIndex) +
" is out of bounds. The given matrix only has " 1613 +
toString((
int) matrix.size1()) +
" rows." ;
1616 boost::numeric::ublas::row(matrix, rowIndex) =
vector;
1631 if ( (columnIndex+1 > (
int) matrix.size2()) ) {
1632 QString msg =
"Unable to set the matrix column to the given vector. Column index " 1633 +
toString(columnIndex) +
" is out of bounds. The given matrix only has " 1634 +
toString((
int) matrix.size1()) +
" columns." ;
1637 boost::numeric::ublas::column(matrix, columnIndex) =
vector;
1654 if ( (rowIndex+1 > (
int) matrix.size1()) ) {
1655 QString msg =
"Unable to get the matrix row to the given vector. Row index " 1656 +
toString(rowIndex) +
" is out of bounds. The given matrix only has " 1657 +
toString((
int) matrix.size1()) +
" rows." ;
1660 return boost::numeric::ublas::row(matrix, rowIndex);
1677 if ( (columnIndex+1 > (
int) matrix.size2()) ) {
1678 QString msg =
"Unable to get the matrix column to the given vector. Column index " 1679 +
toString(columnIndex) +
" is out of bounds. The given matrix only has " 1680 +
toString((
int) matrix.size1()) +
" columns." ;
1683 return boost::numeric::ublas::column(matrix, columnIndex);
1774 for (
int i = 0; i < size; i++) {
1775 sub[i] = v[i + startIndex];
1794 QDebugStateSaver saver(dbg);
1812 QDebugStateSaver saver(dbg);
1813 for (
unsigned int i = 0; i < matrix.size1(); i++) {
1814 dbg.noquote() <<
" ";
1815 for (
unsigned int j = 0; j < matrix.size2(); j++) {
1816 dbg.noquote() <<
toString(matrix(i, j), 15) <<
" ";
1818 dbg.noquote() << endl;
1836 QString result =
"( ";
1837 for (
unsigned int i = 0; i < vector.size(); i++) {
1838 result +=
toString(vector(i), precision);
1839 if (i != vector.size() - 1) result +=
", ";
static Vector project(const Vector &vector1, const Vector &vector2)
Compute the vector projection of vector1 onto vector2.
static Vector vector(double v0, double v1, double v2)
Constructs a 3 dimensional vector with the given component values.
static double innerProduct(const Vector &vector1, const Vector &vector2)
Computes the inner product of the given vectors.
static Matrix transpose(const Matrix &matrix)
Returns the transpose of the given matrix.
static Vector subtract(const Vector &vector1, const Vector &vector2)
Subtracts the right vector from the left vector.
void setRadians(double radians)
Set the angle in units of Radians.
const double PI
The mathematical constant PI.
static bool isRotationMatrix(const Matrix &matrix)
Determines whether the given matrix is a rotation matrix.
double radians() const
Convert an angle to a double.
static bool isIdentity(const Matrix &matrix)
Determines whether the given matrix is the identity.
static Vector column(const Matrix &matrix, int columnIndex)
Returns a vector whose components match those of the given matrix column.
static Matrix multiply(const Matrix &matrix1, const Matrix &matrix2)
Returns the product of two matrices.
static double magnitude(const Vector &vector)
Computes the magnitude (i.e., the length) of the given vector using the Euclidean norm (L2 norm)...
static Vector toQuaternion(const Matrix &rotationMatrix)
Converts a rotation's representation from a matrix to a unit quaternion.
static Vector rotate(const Vector &vector, const Vector &axis, Angle angle)
Rotates a vector about an axis vector given a specified angle.
static Vector subVector(const Vector &v, int start, int size)
Constructs a vector of given size using the given vector and starting index.
LinearAlgebra()
Default constructor for a LinearAlgebra object.
static void setColumn(Matrix &matrix, const Vector &vector, int columnIndex)
Sets the column of the given matrix to the values of the given vector.
boost::numeric::ublas::matrix< double > Matrix
Definition for an Isis::LinearAlgebra::Matrix of doubles.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
static Vector normalize(const Vector &vector)
Returns a unit vector that is codirectional with the given vector by dividing each component of the v...
This error is for when a programmer made an API call that was illegal.
static Matrix zeroMatrix(int rows, int columns)
Returns a matrix with given dimensions that is filled with zeroes.
static double dotProduct(const Vector &vector1, const Vector &vector2)
Computes the dot product of the given vectors.
static Matrix outerProduct(const Vector &vector1, const Vector &vector2)
Computes the outer product of the given vectors.
static Matrix toMatrix(const AxisAngle &axisAngle)
Converts a rotation's representation from an axis of rotation and its corresponding rotation angle to...
static Vector add(const Vector &vector1, const Vector &vector2)
Adds the two given vectors.
boost::numeric::ublas::vector< double > Vector
Definition for an Isis::LinearAlgebra::Vector of doubles.
static QList< EulerAngle > toEulerAngles(const Matrix &rotationMatrix, const QList< int > axes)
Converts a rotation's representation from a matrix to a set of Euler angles with corresponding axes...
static bool isEmpty(const Vector &vector)
Determines whether the given vector is empty (i.e.
static Vector row(const Matrix &matrix, int rowIndex)
Returns a vector whose components match those of the given matrix row.
static Matrix inverse(const Matrix &matrix)
Returns the inverse of a 2x2 or 3x3 matrix.
static AxisAngle toAxisAngle(const Matrix &rotationMatrix)
Converts a rotation's representation from a matrix to a axis of rotation and its corresponding rotati...
static bool isZero(const Matrix &matrix)
Determines whether the given matrix is filled with zereos.
static double determinant(const Matrix &matrix)
Returns the determinant of the given 3x3 matrix.
#define _FILEINFO_
Macro for the filename and line number.
static Matrix identity(int size)
Returns the identity matrix of size NxN.
static Vector zeroVector(int size)
Returns a vector of given length that is filled with zeroes.
A type of error that cannot be classified as any of the other error types.
static void setRow(Matrix &matrix, const Vector &vector, int rowIndex)
Sets the row of the given matrix to the values of the given vector.
static void setVec4(Vector *v, double v0, double v1, double v2, double v3)
Fills the first four elements of the given vector with the given values.
static Vector normalizedCrossProduct(const Vector &vector1, const Vector &vector2)
Divides each vector by its corresponding absolute maximum, computes the cross product of the new vect...
static bool isUnit(const Vector &vector)
Determines whether the given vector is a unit vector.
Defines an angle and provides unit conversions.
Namespace for ISIS/Bullet specific routines.
static bool isOrthogonal(const Matrix &matrix)
Determines whether the given matrix is orthogonal by verifying that the matrix and its tranpose are i...
static Vector crossProduct(const Vector &vector1, const Vector &vector2)
Returns the cross product of two vectors.
QDebug operator<<(QDebug debug, const Hillshade &hillshade)
Print this class out to a QDebug object.
~LinearAlgebra()
Destructor for a LinearAlgebra object.
static void setVec3(Vector *v, double v0, double v1, double v2)
Fills the first three elements of the given vector with the given values.
static double absoluteMaximum(const Vector &vector)
Returns the maximum norm (L-infinity norm) for the given vector.
static Vector perpendicular(const Vector &vector1, const Vector &vector2)
Finds the unique vector P such that A = V + P, V is parallel to B and P is perpendicular to B...