Mantid
Loading...
Searching...
No Matches
Quat.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7#include "MantidKernel/Quat.h"
11#include "MantidKernel/V3D.h"
12
13#include <boost/algorithm/string.hpp>
14#include <sstream>
15
16namespace Mantid::Kernel {
17namespace {
18Logger g_log("Quat");
19}
20
24Quat::Quat() : w(1), a(0), b(0), c(0) {}
25
37Quat::Quat(const V3D &src, const V3D &des) {
38 const V3D v = Kernel::normalize(src + des);
39
40 const V3D cross = v.cross_prod(des);
41
42 if (cross.nullVector()) {
43 w = 1.;
44 a = b = c = 0.;
45 } else {
46 w = v.scalar_prod(des);
47
48 a = cross[0];
49 b = cross[1];
50 c = cross[2];
51
52 double norm = a * a + b * b + c * c + w * w;
53 if (fabs(norm - 1) > FLT_EPSILON) {
54 norm = sqrt(norm);
55 w /= norm;
56 a /= norm;
57 b /= norm;
58 c /= norm;
59 }
60 }
61}
62Quat::Quat(const Kernel::DblMatrix &RotMat) { this->setQuat(RotMat); }
63
65Quat::Quat(const double _w, const double _a, const double _b, const double _c) : w(_w), a(_a), b(_b), c(_c) {}
66
75Quat::Quat(const double _deg, const V3D &_axis) { setAngleAxis(_deg, _axis); }
76
88Quat::Quat(const V3D &rX, const V3D &rY, const V3D &rZ) {
89 // Call the operator to do the setting
90 this->operator()(rX, rY, rZ);
91}
92
99void Quat::set(const double ww, const double aa, const double bb, const double cc) {
100 w = ww;
101 a = aa;
102 b = bb;
103 c = cc;
104}
105
114void Quat::setAngleAxis(const double _deg, const V3D &_axis) {
115 double deg2rad = M_PI / 180.0;
116 w = cos(0.5 * _deg * deg2rad);
117 double s = sin(0.5 * _deg * deg2rad);
118 const V3D temp = Kernel::normalize(_axis);
119 a = s * temp[0];
120 b = s * temp[1];
121 c = s * temp[2];
122}
123
124bool Quat::isNull(const double tolerance) const {
125 using namespace std;
126 double pw = fabs(w) - 1;
127 return (fabs(pw) < tolerance);
128}
129
135void Quat::getAngleAxis(double &_deg, double &_ax0, double &_ax1, double &_ax2) const {
136 // If it represents a rotation of 0(2\pi), get an angle of 0 and axis (0,0,1)
137 if (isNull(1e-5)) {
138 _deg = 0;
139 _ax0 = 0;
140 _ax1 = 0;
141 _ax2 = 1.0;
142 return;
143 }
144 // Semi-angle in radians
145 _deg = acos(w);
146 // Prefactor for the axis part
147 double s = sin(_deg);
148 // Angle in degrees
149 _deg *= 360.0 / M_PI;
150 _ax0 = a / s;
151 _ax1 = b / s;
152 _ax2 = c / s;
153}
154
158void Quat::setRotation(const double deg) {
159 double _deg, ax0, ax1, ax2;
160 this->getAngleAxis(_deg, ax0, ax1, ax2);
161 setAngleAxis(deg, V3D(ax0, ax1, ax2));
162}
163
170void Quat::operator()(const double ww, const double aa, const double bb, const double cc) { this->set(ww, aa, bb, cc); }
171
176void Quat::operator()(const double angle, const V3D &axis) { this->setAngleAxis(angle, axis); }
177
181void Quat::operator()(const Quat &q) {
182 w = q.w;
183 a = q.a;
184 b = q.b;
185 c = q.c;
186}
187
199void Quat::operator()(const V3D &rX, const V3D &rY, const V3D &rZ) {
200 // The quaternion will combine two quaternions.
201 (void)rZ; // Avoid compiler warning
202
203 // These are the original axes
204 constexpr V3D oX = V3D(1., 0., 0.);
205 constexpr V3D oY = V3D(0., 1., 0.);
206
207 // Axis that rotates X
208 const V3D ax1 = oX.cross_prod(rX);
209 // Create the first quaternion
210 Quat Q1;
211 if (!ax1.nullVector()) {
212 // Rotation angle from oX to rX
213 const double angle1 = oX.angle(rX);
214 Q1.setAngleAxis(angle1 * 180.0 / M_PI, ax1);
215 }
216 // Now we rotate the original Y using Q1
217 V3D roY = oY;
218 Q1.rotate(roY);
219 // Find the axis that rotates oYr onto rY
220 const V3D ax2 = roY.cross_prod(rY);
221 Quat Q2;
222 if (!ax2.nullVector()) {
223 const double angle2 = roY.angle(rY);
224 Q2.setAngleAxis(angle2 * 180.0 / M_PI, ax2);
225 }
226
227 // Final = those two rotations in succession; Q1 is done first.
228 const Quat final = Q2 * Q1;
229
230 // Set it
231 this->operator()(final);
232}
233
237 w = 1.0;
238 a = b = c = 0.0;
239}
240
245Quat Quat::operator+(const Quat &_q) const { return Quat(w + _q.w, a + _q.a, b + _q.b, c + _q.c); }
246
252 w += _q.w;
253 a += _q.a;
254 b += _q.b;
255 c += _q.c;
256 return *this;
257}
258
263Quat Quat::operator-(const Quat &_q) const { return Quat(w - _q.w, a - _q.a, b - _q.b, c - _q.c); }
264
270 w -= _q.w;
271 a -= _q.a;
272 b -= _q.b;
273 c -= _q.c;
274 return *this;
275}
276
285Quat Quat::operator*(const Quat &_q) const {
286 double w1, a1, b1, c1;
287 w1 = w * _q.w - a * _q.a - b * _q.b - c * _q.c;
288 a1 = w * _q.a + _q.w * a + b * _q.c - _q.b * c;
289 b1 = w * _q.b + _q.w * b - a * _q.c + c * _q.a;
290 c1 = w * _q.c + _q.w * c + a * _q.b - _q.a * b;
291 return Quat(w1, a1, b1, c1);
292}
293
299 double w1, a1, b1, c1;
300 w1 = w * _q.w - a * _q.a - b * _q.b - c * _q.c;
301 a1 = w * _q.a + _q.w * a + b * _q.c - _q.b * c;
302 b1 = w * _q.b + _q.w * b - a * _q.c + c * _q.a;
303 c1 = w * _q.c + _q.w * c + a * _q.b - _q.a * b;
304 w = w1;
305 a = a1;
306 b = b1;
307 c = c1;
308 return (*this);
309}
310
318bool Quat::operator==(const Quat &q) const {
319 using namespace std;
320 return !(fabs(w - q.w) > Tolerance || fabs(a - q.a) > Tolerance || fabs(b - q.b) > Tolerance ||
321 fabs(c - q.c) > Tolerance);
322
323 // return (quat_tol(w,q.w) && quat_tol(a,q.a) && quat_tol(b,q.b) &&
324 // quat_tol(c,q.c));
325}
326
334bool Quat::operator!=(const Quat &_q) const { return (!operator==(_q)); }
335
341 double overnorm;
342 if (len2() == 0)
343 overnorm = 1.0;
344 else
345 overnorm = 1.0 / len();
346 w *= overnorm;
347 a *= overnorm;
348 b *= overnorm;
349 c *= overnorm;
350}
351
358 a *= -1.0;
359 b *= -1.0;
360 c *= -1.0;
361}
362
366double Quat::len() const { return sqrt(len2()); }
367
371double Quat::len2() const { return (w * w + a * a + b * b + c * c); }
372
377 conjugate();
378 double overnorm = len2();
379 if (overnorm == 0)
380 overnorm = 1.0;
381 else
382 overnorm = 1.0 / overnorm;
383 w *= overnorm;
384 a *= overnorm;
385 b *= overnorm;
386 c *= overnorm;
387}
388
397void Quat::rotate(V3D &v) const {
398 Quat qinvert(*this);
399 qinvert.inverse();
400 Quat pos(0.0, v[0], v[1], v[2]);
401 pos *= qinvert;
402 pos = (*this) * pos;
403 v[0] = pos[1];
404 v[1] = pos[2];
405 v[2] = pos[3];
406}
407
413void Quat::GLMatrix(double *mat) const {
414 double aa = a * a;
415 double ab = a * b;
416 double ac = a * c;
417 double aw = a * w;
418 double bb = b * b;
419 double bc = b * c;
420 double bw = b * w;
421 double cc = c * c;
422 double cw = c * w;
423 *mat = 1.0 - 2.0 * (bb + cc);
424 ++mat;
425 *mat = 2.0 * (ab + cw);
426 ++mat;
427 *mat = 2.0 * (ac - bw);
428 ++mat;
429 *mat = 0;
430 ++mat;
431 *mat = 2.0 * (ab - cw);
432 ++mat;
433 *mat = 1.0 - 2.0 * (aa + cc);
434 ++mat;
435 *mat = 2.0 * (bc + aw);
436 ++mat;
437 *mat = 0;
438 ++mat;
439 *mat = 2.0 * (ac + bw);
440 mat++;
441 *mat = 2.0 * (bc - aw);
442 mat++;
443 *mat = 1.0 - 2.0 * (aa + bb);
444 mat++;
445 for (int i = 0; i < 4; ++i) {
446 *mat = 0;
447 mat++;
448 }
449 *mat = 1.0;
450}
453std::vector<double> Quat::getRotation(bool check_normalisation, bool throw_on_errors) const {
454 double aa = a * a;
455 double ab = a * b;
456 double ac = a * c;
457 double aw = a * w;
458 double bb = b * b;
459 double bc = b * c;
460 double bw = b * w;
461 double cc = c * c;
462 double cw = c * w;
463 if (check_normalisation) {
464 double normSq = aa + bb + cc + w * w;
465 if (fabs(normSq - 1) > FLT_EPSILON) {
466 if (throw_on_errors) {
467 g_log.error() << " A non-unit quaternion used to obtain a rotation "
468 "matrix; need to notmalize it first\n";
469 throw(std::invalid_argument("Attempt to use non-normalized quaternion "
470 "to define rotation matrix; need to "
471 "notmalize it first"));
472 } else {
473 g_log.information() << " Warning; a non-unit quaternion used to obtain "
474 "the rotation matrix; using normalized quat\n";
475 aa /= normSq;
476 ab /= normSq;
477 ac /= normSq;
478 aw /= normSq;
479 bb /= normSq;
480 bc /= normSq;
481 bw /= normSq;
482 cc /= normSq;
483 cw /= normSq;
484 }
485 }
486 }
487 std::vector<double> out(9);
488
489 out[0] = (1.0 - 2.0 * (bb + cc));
490 out[1] = 2.0 * (ab - cw);
491 out[2] = 2.0 * (ac + bw);
492
493 out[3] = 2.0 * (ab + cw);
494 out[4] = (1.0 - 2.0 * (aa + cc));
495 out[5] = 2.0 * (bc - aw);
496
497 out[6] = 2.0 * (ac - bw);
498 out[7] = 2.0 * (bc + aw);
499 out[8] = (1.0 - 2.0 * (aa + bb));
500 return out;
501}
502
506void Quat::setQuat(double mat[16]) {
507 double tr, s, q[4];
508 int nxt[3] = {1, 2, 0};
509 tr = mat[0] + mat[5] + mat[10];
510 if (tr > 0.0) {
511 s = sqrt(tr + 1.0);
512 w = s / 2.0;
513 s = 0.5 / s;
514 a = (mat[6] - mat[9]) * s;
515 b = (mat[8] - mat[2]) * s;
516 c = (mat[1] - mat[4]) * s;
517 } else {
518 int i = 0;
519 if (mat[5] > mat[0])
520 i = 1;
521 if (mat[10] > mat[i * 5])
522 i = 2;
523 int j = nxt[i];
524 int k = nxt[j];
525 s = sqrt(mat[i * 5] - (mat[j * 5] + mat[k * 5]) + 1.0);
526 q[i] = s * 0.5;
527 if (s != 0.0)
528 s = 0.5 / s;
529 q[3] = (mat[j * 4 + k] - mat[k * 4 + j]) * s;
530 q[j] = (mat[i * 4 + j] + mat[j * 4 + i]) * s;
531 q[k] = (mat[i * 4 + k] + mat[k * 4 + i]) * s;
532 a = q[0];
533 b = q[1];
534 c = q[2];
535 w = q[3];
536 }
537}
541 int i = 0, j, k;
542 if (rMat[1][1] > rMat[0][0])
543 i = 1;
544 if (rMat[2][2] > rMat[1][1])
545 i = 2;
546 j = (i + 1) % 3;
547 k = (j + 1) % 3;
548 double r = sqrt(1. + rMat[i][i] - rMat[j][j] - rMat[k][k]);
549 if (r == 0) {
550 a = 0.;
551 b = 0.;
552 c = 0.;
553 w = 1.;
554 } else {
555 double q[4], f = 0.5 / r;
556 q[i] = 0.5 * r;
557 q[j] = f * (rMat[i][j] + rMat[j][i]);
558 q[k] = f * (rMat[k][i] + rMat[i][k]);
559 q[3] = f * (rMat[k][j] - rMat[j][k]);
560 a = q[0];
561 b = q[1];
562 c = q[2];
563 w = q[3];
564 }
565}
571double Quat::operator[](const int Index) const {
572 switch (Index) {
573 case 0:
574 return w;
575 case 1:
576 return a;
577 case 2:
578 return b;
579 case 3:
580 return c;
581 default:
582 throw std::runtime_error("Quat::operator[] range error");
583 }
584}
585
591double &Quat::operator[](const int Index) {
592 switch (Index) {
593 case 0:
594 return w;
595 case 1:
596 return a;
597 case 2:
598 return b;
599 case 3:
600 return c;
601 default:
602 throw std::runtime_error("Quat::operator[] range error");
603 }
604}
605
609void Quat::printSelf(std::ostream &os) const { os << "[" << w << "," << a << "," << b << "," << c << "]"; }
610
615void Quat::readPrinted(std::istream &IX) {
616 std::string in;
617 std::getline(IX, in);
618 size_t i = in.find_first_of('[');
619 if (i == std::string::npos)
620 throw std::runtime_error("Wrong format for Quat input: " + in);
621 size_t j = in.find_last_of(']');
622 if (j == std::string::npos || j < i + 8)
623 throw std::runtime_error("Wrong format for Quat input: " + in);
624
625 size_t c1 = in.find_first_of(',');
626 size_t c2 = in.find_first_of(',', c1 + 1);
627 size_t c3 = in.find_first_of(',', c2 + 1);
628 if (c1 == std::string::npos || c2 == std::string::npos || c3 == std::string::npos)
629 throw std::runtime_error("Wrong format for Quat input: [" + in + "]");
630
631 w = std::stod(in.substr(i + 1, c1 - i - 1));
632 a = std::stod(in.substr(c1 + 1, c2 - c1 - 1));
633 b = std::stod(in.substr(c2 + 1, c3 - c2 - 1));
634 c = std::stod(in.substr(c3 + 1, j - c3 - 1));
635}
636
642std::ostream &operator<<(std::ostream &os, const Quat &q) {
643 q.printSelf(os);
644 return os;
645}
646
651std::istream &operator>>(std::istream &ins, Quat &q) {
652 q.readPrinted(ins);
653 return ins;
654}
655
657std::string Quat::toString() const {
658 std::ostringstream mess;
659 this->printSelf(mess);
660 return mess.str();
661}
662
665void Quat::fromString(const std::string &str) {
666 std::istringstream mess(str);
667 this->readPrinted(mess);
668}
669
670void Quat::rotateBB(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) const {
671 // Defensive
672 if (xmin > xmax)
673 std::swap(xmin, xmax);
674 if (ymin > ymax)
675 std::swap(ymin, ymax);
676 if (zmin > zmax)
677 std::swap(zmin, zmax);
678 // Get the min and max of the cube, and remove centring offset
679 Mantid::Kernel::V3D minT(xmin, ymin, zmin), maxT(xmax, ymax, zmax);
680 // Get the rotation matrix
681 double rotMatr[16];
682 GLMatrix(&rotMatr[0]);
683 // Now calculate new min and max depending on the sign of matrix components
684 // Much faster than creating 8 points and rotate them. The new min (max)
685 // can only be obtained by summing the smallest (largest) components
686 //
687 Mantid::Kernel::V3D minV, maxV;
688 // Looping on rows of matrix
689 int index;
690 for (int i = 0; i < 3; i++) {
691 for (int j = 0; j < 3; j++) {
692 index = j + i * 4; // The OpenGL matrix is linear and represent a 4x4
693 // matrix but only the 3x3 upper-left inner part
694 // contains the rotation
695 minV[j] += (rotMatr[index] > 0) ? rotMatr[index] * minT[i] : rotMatr[index] * maxT[i];
696 maxV[j] += (rotMatr[index] > 0) ? rotMatr[index] * maxT[i] : rotMatr[index] * minT[i];
697 }
698 }
699 // Adjust value.
700 xmin = minV[0];
701 ymin = minV[1];
702 zmin = minV[2];
703 xmax = maxV[0];
704 ymax = maxV[1];
705 zmax = maxV[2];
706}
707
729std::vector<double> Quat::getEulerAngles(const std::string &convention = "XYZ") const {
730 std::string conv(convention);
731
732 if (conv.length() != 3)
733 throw std::invalid_argument("Wrong convention name (string length not 3)");
734
735 boost::to_upper(conv);
736
737 // Check it's only XYZ in the string
738 if (conv.find_first_not_of("XYZ") != std::string::npos)
739 throw std::invalid_argument("Wrong convention name (characters other than XYZ)");
740
741 // Cannot be XXY, XYY, or similar. Only first and last may be the same: YXY
742 if ((conv[0] == conv[1]) || (conv[2] == conv[1]))
743 throw std::invalid_argument("Wrong convention name (repeated indices)");
744
745 boost::replace_all(conv, "X", "0");
746 boost::replace_all(conv, "Y", "1");
747 boost::replace_all(conv, "Z", "2");
748
749 std::stringstream s;
750 s << conv[0] << " " << conv[1] << " " << conv[2];
751
752 int first, second, last;
753 s >> first >> second >> last;
754
755 // Do we want Tait-Bryan angles, as opposed to 'classic' Euler angles?
756 const int TB = (first * second * last == 0 && first + second + last == 3) ? 1 : 0;
757
758 const int par01 = ((second - first + 9) % 3 == 1) ? 1 : -1;
759 const int par12 = ((last - second + 9) % 3 == 1) ? 1 : -1;
760
761 std::vector<double> angles(3);
762
763 const DblMatrix R = DblMatrix(this->getRotation());
764
765 const int i = (last + TB * par12 + 9) % 3;
766 const int j1 = (last - par12 + 9) % 3;
767 const int j2 = (last + par12 + 9) % 3;
768
769 const double s3 = (1.0 - TB - TB * par12) * R[i][j1];
770 const double c3 = (TB - (1.0 - TB) * par12) * R[i][j2];
771
772 V3D axis3(0, 0, 0);
773 axis3[last] = 1.0;
774
775 constexpr double rad2deg = 180.0 / M_PI;
776
777 angles[2] = atan2(s3, c3) * rad2deg;
778
779 DblMatrix Rm3(Quat(-angles[2], axis3).getRotation());
780 DblMatrix Rp = R * Rm3;
781
782 const double s1 = par01 * Rp[(first - par01 + 9) % 3][(first + par01 + 9) % 3];
783 const double c1 = Rp[second][second];
784 const double s2 = par01 * Rp[first][3 - first - second];
785 const double c2 = Rp[first][first];
786
787 angles[0] = atan2(s1, c1) * rad2deg;
788 angles[1] = atan2(s2, c2) * rad2deg;
789
790 return angles;
791}
792
793} // namespace Mantid::Kernel
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
#define fabs(x)
Definition: Matrix.cpp:22
double tolerance
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
void information(const std::string &msg)
Logs at information level.
Definition: Logger.cpp:105
Class for quaternions.
Definition: Quat.h:39
void readPrinted(std::istream &)
Read data from a stream in the format returned by printSelf ("[w,a,b,c]").
Definition: Quat.cpp:615
void init()
Re-initialize to identity.
Definition: Quat.cpp:236
double c
Internal value.
Definition: Quat.h:139
void normalize()
Normalize.
Definition: Quat.cpp:340
bool operator!=(const Quat &) const
Quaternion non-equal operator.
Definition: Quat.cpp:334
Quat operator-(const Quat &) const
Quaternion subtraction operator.
Definition: Quat.cpp:263
Quat()
Null Constructor Initialize the quaternion with the identity q=1.0+0i+0j+0k;.
Definition: Quat.cpp:24
Quat operator+(const Quat &) const
Overload operators.
Definition: Quat.cpp:245
void inverse()
Inverse a quaternion (in the sense of rotation inversion)
Definition: Quat.cpp:376
Quat & operator+=(const Quat &)
Quaternion self-addition operator.
Definition: Quat.cpp:251
double len() const
Norm of a quaternion.
Definition: Quat.cpp:366
double b
Internal value.
Definition: Quat.h:137
Quat & operator-=(const Quat &)
Quaternion self-substraction operator.
Definition: Quat.cpp:269
double w
Internal value.
Definition: Quat.h:133
bool operator==(const Quat &) const
Quaternion equal operator.
Definition: Quat.cpp:318
void getAngleAxis(double &_deg, double &_ax0, double &_ax1, double &ax2) const
Extracts the angle of roatation and axis.
Definition: Quat.cpp:135
void setQuat(double mat[16])
Convert GL Matrix into Quat.
Definition: Quat.cpp:506
void fromString(const std::string &str)
Sets the Quat using a string.
Definition: Quat.cpp:665
double len2() const
Norm squared.
Definition: Quat.cpp:371
void GLMatrix(double *mat) const
Convert quaternion rotation to an OpenGL matrix [4x4] matrix stored as an linear array of 16 double T...
Definition: Quat.cpp:413
void set(const double ww, const double aa, const double bb, const double cc)
Sets the quat values from four doubles.
Definition: Quat.cpp:99
Quat operator*(const Quat &) const
Quaternion multiplication operator.
Definition: Quat.cpp:285
void rotate(V3D &) const
Rotate a vector.
Definition: Quat.cpp:397
void printSelf(std::ostream &) const
Prints a string representation of itself.
Definition: Quat.cpp:609
Quat & operator*=(const Quat &)
Quaternion self-multiplication operator.
Definition: Quat.cpp:298
std::string toString() const
Definition: Quat.cpp:657
void rotateBB(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) const
Taking two points defining a cuboid bounding box (xmin,ymin,zmin) and.
Definition: Quat.cpp:670
std::vector< double > getEulerAngles(const std::string &convention) const
Calculate the Euler angles that are equivalent to this Quaternion.
Definition: Quat.cpp:729
bool isNull(const double tolerance=0.001) const
Is the quaternion representing a null rotation.
Definition: Quat.cpp:124
std::vector< double > getRotation(bool check_normalisation=false, bool throw_on_errors=false) const
returns the rotation matrix defined by this quaternion as an 9-point
Definition: Quat.cpp:453
void setAngleAxis(const double _deg, const V3D &_axis)
Constructor from an angle and axis.
Definition: Quat.cpp:114
void setRotation(const double deg)
Set the rotation (both don't change rotation axis)
Definition: Quat.cpp:158
void conjugate()
Take the complex conjugate.
Definition: Quat.cpp:357
double a
Internal value.
Definition: Quat.h:135
double operator[](int) const
Bracket operator overload returns the internal representation values based on an index.
Definition: Quat.cpp:571
void operator()(const Quat &)
Sets the quat values from another Quat.
Definition: Quat.cpp:181
Class for 3D vectors.
Definition: V3D.h:34
constexpr double scalar_prod(const V3D &v) const noexcept
Calculates the cross product.
Definition: V3D.h:274
constexpr V3D cross_prod(const V3D &v) const noexcept
Cross product (this * argument)
Definition: V3D.h:278
double angle(const V3D &) const
Angle between this and another vector.
Definition: V3D.cpp:165
bool nullVector(const double tolerance=1e-3) const noexcept
Determine if the point is null.
Definition: V3D.cpp:241
constexpr double rad2deg
constexpr double deg2rad
Defines units/enum for Crystal work.
Definition: AngleUnits.h:20
MANTID_KERNEL_DLL std::ostream & operator<<(std::ostream &, CPUTimer &)
Convenience function to provide for easier debug printing.
Definition: CPUTimer.cpp:86
MANTID_KERNEL_DLL std::istream & operator>>(std::istream &, Interpolation &)
Reads in parameter value.
constexpr double Tolerance
Standard tolerance value.
Definition: Tolerance.h:12
MANTID_KERNEL_DLL V3D normalize(V3D v)
Normalizes a V3D.
Definition: V3D.h:341
Mantid::Kernel::Matrix< double > DblMatrix
Definition: Matrix.h:206
STL namespace.