EllipseGeometryLibrary-ff991705.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /* This file is automatically rebuilt by the Cesium build process. */
  2. define(['exports', './Math-fa6e45cb', './Cartesian2-2a723276', './Transforms-65aba0a4'], function (exports, _Math, Cartesian2, Transforms) { 'use strict';
  3. var EllipseGeometryLibrary = {};
  4. var rotAxis = new Cartesian2.Cartesian3();
  5. var tempVec = new Cartesian2.Cartesian3();
  6. var unitQuat = new Transforms.Quaternion();
  7. var rotMtx = new Transforms.Matrix3();
  8. function pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, result) {
  9. var azimuth = theta + rotation;
  10. Cartesian2.Cartesian3.multiplyByScalar(eastVec, Math.cos(azimuth), rotAxis);
  11. Cartesian2.Cartesian3.multiplyByScalar(northVec, Math.sin(azimuth), tempVec);
  12. Cartesian2.Cartesian3.add(rotAxis, tempVec, rotAxis);
  13. var cosThetaSquared = Math.cos(theta);
  14. cosThetaSquared = cosThetaSquared * cosThetaSquared;
  15. var sinThetaSquared = Math.sin(theta);
  16. sinThetaSquared = sinThetaSquared * sinThetaSquared;
  17. var radius = ab / Math.sqrt(bSqr * cosThetaSquared + aSqr * sinThetaSquared);
  18. var angle = radius / mag;
  19. // Create the quaternion to rotate the position vector to the boundary of the ellipse.
  20. Transforms.Quaternion.fromAxisAngle(rotAxis, angle, unitQuat);
  21. Transforms.Matrix3.fromQuaternion(unitQuat, rotMtx);
  22. Transforms.Matrix3.multiplyByVector(rotMtx, unitPos, result);
  23. Cartesian2.Cartesian3.normalize(result, result);
  24. Cartesian2.Cartesian3.multiplyByScalar(result, mag, result);
  25. return result;
  26. }
  27. var scratchCartesian1 = new Cartesian2.Cartesian3();
  28. var scratchCartesian2 = new Cartesian2.Cartesian3();
  29. var scratchCartesian3 = new Cartesian2.Cartesian3();
  30. var scratchNormal = new Cartesian2.Cartesian3();
  31. /**
  32. * Returns the positions raised to the given heights
  33. * @private
  34. */
  35. EllipseGeometryLibrary.raisePositionsToHeight = function(positions, options, extrude) {
  36. var ellipsoid = options.ellipsoid;
  37. var height = options.height;
  38. var extrudedHeight = options.extrudedHeight;
  39. var size = (extrude) ? positions.length / 3 * 2 : positions.length / 3;
  40. var finalPositions = new Float64Array(size * 3);
  41. var length = positions.length;
  42. var bottomOffset = (extrude) ? length : 0;
  43. for (var i = 0; i < length; i += 3) {
  44. var i1 = i + 1;
  45. var i2 = i + 2;
  46. var position = Cartesian2.Cartesian3.fromArray(positions, i, scratchCartesian1);
  47. ellipsoid.scaleToGeodeticSurface(position, position);
  48. var extrudedPosition = Cartesian2.Cartesian3.clone(position, scratchCartesian2);
  49. var normal = ellipsoid.geodeticSurfaceNormal(position, scratchNormal);
  50. var scaledNormal = Cartesian2.Cartesian3.multiplyByScalar(normal, height, scratchCartesian3);
  51. Cartesian2.Cartesian3.add(position, scaledNormal, position);
  52. if (extrude) {
  53. Cartesian2.Cartesian3.multiplyByScalar(normal, extrudedHeight, scaledNormal);
  54. Cartesian2.Cartesian3.add(extrudedPosition, scaledNormal, extrudedPosition);
  55. finalPositions[i + bottomOffset] = extrudedPosition.x;
  56. finalPositions[i1 + bottomOffset] = extrudedPosition.y;
  57. finalPositions[i2 + bottomOffset] = extrudedPosition.z;
  58. }
  59. finalPositions[i] = position.x;
  60. finalPositions[i1] = position.y;
  61. finalPositions[i2] = position.z;
  62. }
  63. return finalPositions;
  64. };
  65. var unitPosScratch = new Cartesian2.Cartesian3();
  66. var eastVecScratch = new Cartesian2.Cartesian3();
  67. var northVecScratch = new Cartesian2.Cartesian3();
  68. /**
  69. * Returns an array of positions that make up the ellipse.
  70. * @private
  71. */
  72. EllipseGeometryLibrary.computeEllipsePositions = function(options, addFillPositions, addEdgePositions) {
  73. var semiMinorAxis = options.semiMinorAxis;
  74. var semiMajorAxis = options.semiMajorAxis;
  75. var rotation = options.rotation;
  76. var center = options.center;
  77. // Computing the arc-length of the ellipse is too expensive to be practical. Estimating it using the
  78. // arc length of the sphere is too inaccurate and creates sharp edges when either the semi-major or
  79. // semi-minor axis is much bigger than the other. Instead, scale the angle delta to make
  80. // the distance along the ellipse boundary more closely match the granularity.
  81. var granularity = options.granularity * 8.0;
  82. var aSqr = semiMinorAxis * semiMinorAxis;
  83. var bSqr = semiMajorAxis * semiMajorAxis;
  84. var ab = semiMajorAxis * semiMinorAxis;
  85. var mag = Cartesian2.Cartesian3.magnitude(center);
  86. var unitPos = Cartesian2.Cartesian3.normalize(center, unitPosScratch);
  87. var eastVec = Cartesian2.Cartesian3.cross(Cartesian2.Cartesian3.UNIT_Z, center, eastVecScratch);
  88. eastVec = Cartesian2.Cartesian3.normalize(eastVec, eastVec);
  89. var northVec = Cartesian2.Cartesian3.cross(unitPos, eastVec, northVecScratch);
  90. // The number of points in the first quadrant
  91. var numPts = 1 + Math.ceil(_Math.CesiumMath.PI_OVER_TWO / granularity);
  92. var deltaTheta = _Math.CesiumMath.PI_OVER_TWO / (numPts - 1);
  93. var theta = _Math.CesiumMath.PI_OVER_TWO - numPts * deltaTheta;
  94. if (theta < 0.0) {
  95. numPts -= Math.ceil(Math.abs(theta) / deltaTheta);
  96. }
  97. // If the number of points were three, the ellipse
  98. // would be tessellated like below:
  99. //
  100. // *---*
  101. // / | \ | \
  102. // *---*---*---*
  103. // / | \ | \ | \ | \
  104. // / .*---*---*---*. \
  105. // * ` | \ | \ | \ | `*
  106. // \`.*---*---*---*.`/
  107. // \ | \ | \ | \ | /
  108. // *---*---*---*
  109. // \ | \ | /
  110. // *---*
  111. // The first and last column have one position and fan to connect to the adjacent column.
  112. // Each other vertical column contains an even number of positions.
  113. var size = 2 * (numPts * (numPts + 2));
  114. var positions = (addFillPositions) ? new Array(size * 3) : undefined;
  115. var positionIndex = 0;
  116. var position = scratchCartesian1;
  117. var reflectedPosition = scratchCartesian2;
  118. var outerPositionsLength = (numPts * 4) * 3;
  119. var outerRightIndex = outerPositionsLength - 1;
  120. var outerLeftIndex = 0;
  121. var outerPositions = (addEdgePositions) ? new Array(outerPositionsLength) : undefined;
  122. var i;
  123. var j;
  124. var numInterior;
  125. var t;
  126. var interiorPosition;
  127. // Compute points in the 'eastern' half of the ellipse
  128. theta = _Math.CesiumMath.PI_OVER_TWO;
  129. position = pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);
  130. if (addFillPositions) {
  131. positions[positionIndex++] = position.x;
  132. positions[positionIndex++] = position.y;
  133. positions[positionIndex++] = position.z;
  134. }
  135. if (addEdgePositions) {
  136. outerPositions[outerRightIndex--] = position.z;
  137. outerPositions[outerRightIndex--] = position.y;
  138. outerPositions[outerRightIndex--] = position.x;
  139. }
  140. theta = _Math.CesiumMath.PI_OVER_TWO - deltaTheta;
  141. for (i = 1; i < numPts + 1; ++i) {
  142. position = pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);
  143. reflectedPosition = pointOnEllipsoid(Math.PI - theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, reflectedPosition);
  144. if (addFillPositions) {
  145. positions[positionIndex++] = position.x;
  146. positions[positionIndex++] = position.y;
  147. positions[positionIndex++] = position.z;
  148. numInterior = 2 * i + 2;
  149. for (j = 1; j < numInterior - 1; ++j) {
  150. t = j / (numInterior - 1);
  151. interiorPosition = Cartesian2.Cartesian3.lerp(position, reflectedPosition, t, scratchCartesian3);
  152. positions[positionIndex++] = interiorPosition.x;
  153. positions[positionIndex++] = interiorPosition.y;
  154. positions[positionIndex++] = interiorPosition.z;
  155. }
  156. positions[positionIndex++] = reflectedPosition.x;
  157. positions[positionIndex++] = reflectedPosition.y;
  158. positions[positionIndex++] = reflectedPosition.z;
  159. }
  160. if (addEdgePositions) {
  161. outerPositions[outerRightIndex--] = position.z;
  162. outerPositions[outerRightIndex--] = position.y;
  163. outerPositions[outerRightIndex--] = position.x;
  164. outerPositions[outerLeftIndex++] = reflectedPosition.x;
  165. outerPositions[outerLeftIndex++] = reflectedPosition.y;
  166. outerPositions[outerLeftIndex++] = reflectedPosition.z;
  167. }
  168. theta = _Math.CesiumMath.PI_OVER_TWO - (i + 1) * deltaTheta;
  169. }
  170. // Compute points in the 'western' half of the ellipse
  171. for (i = numPts; i > 1; --i) {
  172. theta = _Math.CesiumMath.PI_OVER_TWO - (i - 1) * deltaTheta;
  173. position = pointOnEllipsoid(-theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);
  174. reflectedPosition = pointOnEllipsoid(theta + Math.PI, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, reflectedPosition);
  175. if (addFillPositions) {
  176. positions[positionIndex++] = position.x;
  177. positions[positionIndex++] = position.y;
  178. positions[positionIndex++] = position.z;
  179. numInterior = 2 * (i - 1) + 2;
  180. for (j = 1; j < numInterior - 1; ++j) {
  181. t = j / (numInterior - 1);
  182. interiorPosition = Cartesian2.Cartesian3.lerp(position, reflectedPosition, t, scratchCartesian3);
  183. positions[positionIndex++] = interiorPosition.x;
  184. positions[positionIndex++] = interiorPosition.y;
  185. positions[positionIndex++] = interiorPosition.z;
  186. }
  187. positions[positionIndex++] = reflectedPosition.x;
  188. positions[positionIndex++] = reflectedPosition.y;
  189. positions[positionIndex++] = reflectedPosition.z;
  190. }
  191. if (addEdgePositions) {
  192. outerPositions[outerRightIndex--] = position.z;
  193. outerPositions[outerRightIndex--] = position.y;
  194. outerPositions[outerRightIndex--] = position.x;
  195. outerPositions[outerLeftIndex++] = reflectedPosition.x;
  196. outerPositions[outerLeftIndex++] = reflectedPosition.y;
  197. outerPositions[outerLeftIndex++] = reflectedPosition.z;
  198. }
  199. }
  200. theta = _Math.CesiumMath.PI_OVER_TWO;
  201. position = pointOnEllipsoid(-theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);
  202. var r = {};
  203. if (addFillPositions) {
  204. positions[positionIndex++] = position.x;
  205. positions[positionIndex++] = position.y;
  206. positions[positionIndex++] = position.z;
  207. r.positions = positions;
  208. r.numPts = numPts;
  209. }
  210. if (addEdgePositions) {
  211. outerPositions[outerRightIndex--] = position.z;
  212. outerPositions[outerRightIndex--] = position.y;
  213. outerPositions[outerRightIndex--] = position.x;
  214. r.outerPositions = outerPositions;
  215. }
  216. return r;
  217. };
  218. exports.EllipseGeometryLibrary = EllipseGeometryLibrary;
  219. });