42 double phi = std::sqrt(vx * vx + vy * vy + vz * vz);
45 double factor = std::sin(phi / 2.0) / phi;
46 double S0 = std::cos(phi / 2.0);
47 double S1 = factor * vx;
48 double S2 = factor * vy;
49 double S3 = factor * vz;
51 R(0, 0) = 2.0 * (S1 * S1 + S0 * S0) - 1.0;
52 R(0, 1) = 2.0 * (S1 * S2 - S0 * S3);
53 R(0, 2) = 2.0 * (S1 * S3 + S0 * S2);
55 R(1, 0) = 2.0 * (S2 * S1 + S0 * S3);
56 R(1, 1) = 2.0 * (S2 * S2 + S0 * S0) - 1.0;
57 R(1, 2) = 2.0 * (S2 * S3 - S0 * S1);
59 R(2, 0) = 2.0 * (S3 * S1 - S0 * S2);
60 R(2, 1) = 2.0 * (S3 * S2 + S0 * S1);
61 R(2, 2) = 2.0 * (S3 * S3 + S0 * S0) - 1.0;
66 vx = (
R(2, 1) -
R(1, 2)) / 2.0;
67 vy = (
R(0, 2) -
R(2, 0)) / 2.0;
68 vz = (
R(1, 0) -
R(0, 1)) / 2.0;
69 double c = (
R(0, 0) +
R(1, 1) +
R(2, 2) - 1.0) / 2.0;
70 double s = std::sqrt(vx * vx + vy * vy + vz * vz);
71 double phi = std::atan2(s, c);
76 vx = (vx > 0.0 ? phi : (-phi)) * std::sqrt(std::max(
R(0, 0) - c, 0.0) / (1.0 - c));
77 vy = (vy > 0.0 ? phi : (-phi)) * std::sqrt(std::max(
R(1, 1) - c, 0.0) / (1.0 - c));
78 vz = (vz > 0.0 ? phi : (-phi)) * std::sqrt(std::max(
R(2, 2) - c, 0.0) / (1.0 - c));
79 }
else if (std::abs(s) > 1.0e-10) {
80 double factor = phi / s;