HeadingPitchRoll.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import defaultValue from './defaultValue.js';
  2. import defined from './defined.js';
  3. import DeveloperError from './DeveloperError.js';
  4. import CesiumMath from './Math.js';
  5. /**
  6. * A rotation expressed as a heading, pitch, and roll. Heading is the rotation about the
  7. * negative z axis. Pitch is the rotation about the negative y axis. Roll is the rotation about
  8. * the positive x axis.
  9. * @alias HeadingPitchRoll
  10. * @constructor
  11. *
  12. * @param {Number} [heading=0.0] The heading component in radians.
  13. * @param {Number} [pitch=0.0] The pitch component in radians.
  14. * @param {Number} [roll=0.0] The roll component in radians.
  15. */
  16. function HeadingPitchRoll(heading, pitch, roll) {
  17. this.heading = defaultValue(heading, 0.0);
  18. this.pitch = defaultValue(pitch, 0.0);
  19. this.roll = defaultValue(roll, 0.0);
  20. }
  21. /**
  22. * Computes the heading, pitch and roll from a quaternion (see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles )
  23. *
  24. * @param {Quaternion} quaternion The quaternion from which to retrieve heading, pitch, and roll, all expressed in radians.
  25. * @param {HeadingPitchRoll} [result] The object in which to store the result. If not provided, a new instance is created and returned.
  26. * @returns {HeadingPitchRoll} The modified result parameter or a new HeadingPitchRoll instance if one was not provided.
  27. */
  28. HeadingPitchRoll.fromQuaternion = function(quaternion, result) {
  29. //>>includeStart('debug', pragmas.debug);
  30. if (!defined(quaternion)) {
  31. throw new DeveloperError('quaternion is required');
  32. }
  33. //>>includeEnd('debug');
  34. if (!defined(result)) {
  35. result = new HeadingPitchRoll();
  36. }
  37. var test = 2 * (quaternion.w * quaternion.y - quaternion.z * quaternion.x);
  38. var denominatorRoll = 1 - 2 * (quaternion.x * quaternion.x + quaternion.y * quaternion.y);
  39. var numeratorRoll = 2 * (quaternion.w * quaternion.x + quaternion.y * quaternion.z);
  40. var denominatorHeading = 1 - 2 * (quaternion.y * quaternion.y + quaternion.z * quaternion.z);
  41. var numeratorHeading = 2 * (quaternion.w * quaternion.z + quaternion.x * quaternion.y);
  42. result.heading = -Math.atan2(numeratorHeading, denominatorHeading);
  43. result.roll = Math.atan2(numeratorRoll, denominatorRoll);
  44. result.pitch = -CesiumMath.asinClamped(test);
  45. return result;
  46. };
  47. /**
  48. * Returns a new HeadingPitchRoll instance from angles given in degrees.
  49. *
  50. * @param {Number} heading the heading in degrees
  51. * @param {Number} pitch the pitch in degrees
  52. * @param {Number} roll the heading in degrees
  53. * @param {HeadingPitchRoll} [result] The object in which to store the result. If not provided, a new instance is created and returned.
  54. * @returns {HeadingPitchRoll} A new HeadingPitchRoll instance
  55. */
  56. HeadingPitchRoll.fromDegrees = function(heading, pitch, roll, result) {
  57. //>>includeStart('debug', pragmas.debug);
  58. if (!defined(heading)) {
  59. throw new DeveloperError('heading is required');
  60. }
  61. if (!defined(pitch)) {
  62. throw new DeveloperError('pitch is required');
  63. }
  64. if (!defined(roll)) {
  65. throw new DeveloperError('roll is required');
  66. }
  67. //>>includeEnd('debug');
  68. if (!defined(result)) {
  69. result = new HeadingPitchRoll();
  70. }
  71. result.heading = heading * CesiumMath.RADIANS_PER_DEGREE;
  72. result.pitch = pitch * CesiumMath.RADIANS_PER_DEGREE;
  73. result.roll = roll * CesiumMath.RADIANS_PER_DEGREE;
  74. return result;
  75. };
  76. /**
  77. * Duplicates a HeadingPitchRoll instance.
  78. *
  79. * @param {HeadingPitchRoll} headingPitchRoll The HeadingPitchRoll to duplicate.
  80. * @param {HeadingPitchRoll} [result] The object onto which to store the result.
  81. * @returns {HeadingPitchRoll} The modified result parameter or a new HeadingPitchRoll instance if one was not provided. (Returns undefined if headingPitchRoll is undefined)
  82. */
  83. HeadingPitchRoll.clone = function(headingPitchRoll, result) {
  84. if (!defined(headingPitchRoll)) {
  85. return undefined;
  86. }
  87. if (!defined(result)) {
  88. return new HeadingPitchRoll(headingPitchRoll.heading, headingPitchRoll.pitch, headingPitchRoll.roll);
  89. }
  90. result.heading = headingPitchRoll.heading;
  91. result.pitch = headingPitchRoll.pitch;
  92. result.roll = headingPitchRoll.roll;
  93. return result;
  94. };
  95. /**
  96. * Compares the provided HeadingPitchRolls componentwise and returns
  97. * <code>true</code> if they are equal, <code>false</code> otherwise.
  98. *
  99. * @param {HeadingPitchRoll} [left] The first HeadingPitchRoll.
  100. * @param {HeadingPitchRoll} [right] The second HeadingPitchRoll.
  101. * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise.
  102. */
  103. HeadingPitchRoll.equals = function(left, right) {
  104. return (left === right) ||
  105. ((defined(left)) &&
  106. (defined(right)) &&
  107. (left.heading === right.heading) &&
  108. (left.pitch === right.pitch) &&
  109. (left.roll === right.roll));
  110. };
  111. /**
  112. * Compares the provided HeadingPitchRolls componentwise and returns
  113. * <code>true</code> if they pass an absolute or relative tolerance test,
  114. * <code>false</code> otherwise.
  115. *
  116. * @param {HeadingPitchRoll} [left] The first HeadingPitchRoll.
  117. * @param {HeadingPitchRoll} [right] The second HeadingPitchRoll.
  118. * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing.
  119. * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing.
  120. * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise.
  121. */
  122. HeadingPitchRoll.equalsEpsilon = function(left, right, relativeEpsilon, absoluteEpsilon) {
  123. return (left === right) ||
  124. (defined(left) &&
  125. defined(right) &&
  126. CesiumMath.equalsEpsilon(left.heading, right.heading, relativeEpsilon, absoluteEpsilon) &&
  127. CesiumMath.equalsEpsilon(left.pitch, right.pitch, relativeEpsilon, absoluteEpsilon) &&
  128. CesiumMath.equalsEpsilon(left.roll, right.roll, relativeEpsilon, absoluteEpsilon));
  129. };
  130. /**
  131. * Duplicates this HeadingPitchRoll instance.
  132. *
  133. * @param {HeadingPitchRoll} [result] The object onto which to store the result.
  134. * @returns {HeadingPitchRoll} The modified result parameter or a new HeadingPitchRoll instance if one was not provided.
  135. */
  136. HeadingPitchRoll.prototype.clone = function(result) {
  137. return HeadingPitchRoll.clone(this, result);
  138. };
  139. /**
  140. * Compares this HeadingPitchRoll against the provided HeadingPitchRoll componentwise and returns
  141. * <code>true</code> if they are equal, <code>false</code> otherwise.
  142. *
  143. * @param {HeadingPitchRoll} [right] The right hand side HeadingPitchRoll.
  144. * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise.
  145. */
  146. HeadingPitchRoll.prototype.equals = function(right) {
  147. return HeadingPitchRoll.equals(this, right);
  148. };
  149. /**
  150. * Compares this HeadingPitchRoll against the provided HeadingPitchRoll componentwise and returns
  151. * <code>true</code> if they pass an absolute or relative tolerance test,
  152. * <code>false</code> otherwise.
  153. *
  154. * @param {HeadingPitchRoll} [right] The right hand side HeadingPitchRoll.
  155. * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing.
  156. * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing.
  157. * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise.
  158. */
  159. HeadingPitchRoll.prototype.equalsEpsilon = function(right, relativeEpsilon, absoluteEpsilon) {
  160. return HeadingPitchRoll.equalsEpsilon(this, right, relativeEpsilon, absoluteEpsilon);
  161. };
  162. /**
  163. * Creates a string representing this HeadingPitchRoll in the format '(heading, pitch, roll)' in radians.
  164. *
  165. * @returns {String} A string representing the provided HeadingPitchRoll in the format '(heading, pitch, roll)'.
  166. */
  167. HeadingPitchRoll.prototype.toString = function() {
  168. return '(' + this.heading + ', ' + this.pitch + ', ' + this.roll + ')';
  169. };
  170. export default HeadingPitchRoll;