# How to use bounding method in synthetixio-synpress

Best JavaScript code snippet using synthetixio-synpress

BoundingSphere.js

Source:BoundingSphere.js

`1import Cartesian3 from "./Cartesian3.js";2import Cartographic from "./Cartographic.js";3import Check from "./Check.js";4import defaultValue from "./defaultValue.js";5import defined from "./defined.js";6import Ellipsoid from "./Ellipsoid.js";7import GeographicProjection from "./GeographicProjection.js";8import Intersect from "./Intersect.js";9import Interval from "./Interval.js";10import CesiumMath from "./Math.js";11import Matrix3 from "./Matrix3.js";12import Matrix4 from "./Matrix4.js";13import Rectangle from "./Rectangle.js";14/**15 * A bounding sphere with a center and a radius.16 * @alias BoundingSphere17 * @constructor18 *19 * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the bounding sphere.20 * @param {Number} [radius=0.0] The radius of the bounding sphere.21 *22 * @see AxisAlignedBoundingBox23 * @see BoundingRectangle24 * @see Packable25 */26function BoundingSphere(center, radius) {27 /**28 * The center point of the sphere.29 * @type {Cartesian3}30 * @default {@link Cartesian3.ZERO}31 */32 this.center = Cartesian3.clone(defaultValue(center, Cartesian3.ZERO));33 /**34 * The radius of the sphere.35 * @type {Number}36 * @default 0.037 */38 this.radius = defaultValue(radius, 0.0);39}40var fromPointsXMin = new Cartesian3();41var fromPointsYMin = new Cartesian3();42var fromPointsZMin = new Cartesian3();43var fromPointsXMax = new Cartesian3();44var fromPointsYMax = new Cartesian3();45var fromPointsZMax = new Cartesian3();46var fromPointsCurrentPos = new Cartesian3();47var fromPointsScratch = new Cartesian3();48var fromPointsRitterCenter = new Cartesian3();49var fromPointsMinBoxPt = new Cartesian3();50var fromPointsMaxBoxPt = new Cartesian3();51var fromPointsNaiveCenterScratch = new Cartesian3();52var volumeConstant = (4.0 / 3.0) * CesiumMath.PI;53/**54 * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points.55 * The bounding sphere is computed by running two algorithms, a naive algorithm and56 * Ritter's algorithm. The smaller of the two spheres is used to ensure a tight fit.57 *58 * @param {Cartesian3[]} [positions] An array of points that the bounding sphere will enclose. Each point must have <code>x</code>, <code>y</code>, and <code>z</code> properties.59 * @param {BoundingSphere} [result] The object onto which to store the result.60 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided.61 *62 * @see {@link http://help.agi.com/AGIComponents/html/BlogBoundingSphere.htm|Bounding Sphere computation article}63 */64BoundingSphere.fromPoints = function (positions, result) {65 if (!defined(result)) {66 result = new BoundingSphere();67 }68 if (!defined(positions) || positions.length === 0) {69 result.center = Cartesian3.clone(Cartesian3.ZERO, result.center);70 result.radius = 0.0;71 return result;72 }73 var currentPos = Cartesian3.clone(positions[0], fromPointsCurrentPos);74 var xMin = Cartesian3.clone(currentPos, fromPointsXMin);75 var yMin = Cartesian3.clone(currentPos, fromPointsYMin);76 var zMin = Cartesian3.clone(currentPos, fromPointsZMin);77 var xMax = Cartesian3.clone(currentPos, fromPointsXMax);78 var yMax = Cartesian3.clone(currentPos, fromPointsYMax);79 var zMax = Cartesian3.clone(currentPos, fromPointsZMax);80 var numPositions = positions.length;81 var i;82 for (i = 1; i < numPositions; i++) {83 Cartesian3.clone(positions[i], currentPos);84 var x = currentPos.x;85 var y = currentPos.y;86 var z = currentPos.z;87 // Store points containing the the smallest and largest components88 if (x < xMin.x) {89 Cartesian3.clone(currentPos, xMin);90 }91 if (x > xMax.x) {92 Cartesian3.clone(currentPos, xMax);93 }94 if (y < yMin.y) {95 Cartesian3.clone(currentPos, yMin);96 }97 if (y > yMax.y) {98 Cartesian3.clone(currentPos, yMax);99 }100 if (z < zMin.z) {101 Cartesian3.clone(currentPos, zMin);102 }103 if (z > zMax.z) {104 Cartesian3.clone(currentPos, zMax);105 }106 }107 // Compute x-, y-, and z-spans (Squared distances b/n each component's min. and max.).108 var xSpan = Cartesian3.magnitudeSquared(109 Cartesian3.subtract(xMax, xMin, fromPointsScratch)110 );111 var ySpan = Cartesian3.magnitudeSquared(112 Cartesian3.subtract(yMax, yMin, fromPointsScratch)113 );114 var zSpan = Cartesian3.magnitudeSquared(115 Cartesian3.subtract(zMax, zMin, fromPointsScratch)116 );117 // Set the diameter endpoints to the largest span.118 var diameter1 = xMin;119 var diameter2 = xMax;120 var maxSpan = xSpan;121 if (ySpan > maxSpan) {122 maxSpan = ySpan;123 diameter1 = yMin;124 diameter2 = yMax;125 }126 if (zSpan > maxSpan) {127 maxSpan = zSpan;128 diameter1 = zMin;129 diameter2 = zMax;130 }131 // Calculate the center of the initial sphere found by Ritter's algorithm132 var ritterCenter = fromPointsRitterCenter;133 ritterCenter.x = (diameter1.x + diameter2.x) * 0.5;134 ritterCenter.y = (diameter1.y + diameter2.y) * 0.5;135 ritterCenter.z = (diameter1.z + diameter2.z) * 0.5;136 // Calculate the radius of the initial sphere found by Ritter's algorithm137 var radiusSquared = Cartesian3.magnitudeSquared(138 Cartesian3.subtract(diameter2, ritterCenter, fromPointsScratch)139 );140 var ritterRadius = Math.sqrt(radiusSquared);141 // Find the center of the sphere found using the Naive method.142 var minBoxPt = fromPointsMinBoxPt;143 minBoxPt.x = xMin.x;144 minBoxPt.y = yMin.y;145 minBoxPt.z = zMin.z;146 var maxBoxPt = fromPointsMaxBoxPt;147 maxBoxPt.x = xMax.x;148 maxBoxPt.y = yMax.y;149 maxBoxPt.z = zMax.z;150 var naiveCenter = Cartesian3.midpoint(151 minBoxPt,152 maxBoxPt,153 fromPointsNaiveCenterScratch154 );155 // Begin 2nd pass to find naive radius and modify the ritter sphere.156 var naiveRadius = 0;157 for (i = 0; i < numPositions; i++) {158 Cartesian3.clone(positions[i], currentPos);159 // Find the furthest point from the naive center to calculate the naive radius.160 var r = Cartesian3.magnitude(161 Cartesian3.subtract(currentPos, naiveCenter, fromPointsScratch)162 );163 if (r > naiveRadius) {164 naiveRadius = r;165 }166 // Make adjustments to the Ritter Sphere to include all points.167 var oldCenterToPointSquared = Cartesian3.magnitudeSquared(168 Cartesian3.subtract(currentPos, ritterCenter, fromPointsScratch)169 );170 if (oldCenterToPointSquared > radiusSquared) {171 var oldCenterToPoint = Math.sqrt(oldCenterToPointSquared);172 // Calculate new radius to include the point that lies outside173 ritterRadius = (ritterRadius + oldCenterToPoint) * 0.5;174 radiusSquared = ritterRadius * ritterRadius;175 // Calculate center of new Ritter sphere176 var oldToNew = oldCenterToPoint - ritterRadius;177 ritterCenter.x =178 (ritterRadius * ritterCenter.x + oldToNew * currentPos.x) /179 oldCenterToPoint;180 ritterCenter.y =181 (ritterRadius * ritterCenter.y + oldToNew * currentPos.y) /182 oldCenterToPoint;183 ritterCenter.z =184 (ritterRadius * ritterCenter.z + oldToNew * currentPos.z) /185 oldCenterToPoint;186 }187 }188 if (ritterRadius < naiveRadius) {189 Cartesian3.clone(ritterCenter, result.center);190 result.radius = ritterRadius;191 } else {192 Cartesian3.clone(naiveCenter, result.center);193 result.radius = naiveRadius;194 }195 return result;196};197var defaultProjection = new GeographicProjection();198var fromRectangle2DLowerLeft = new Cartesian3();199var fromRectangle2DUpperRight = new Cartesian3();200var fromRectangle2DSouthwest = new Cartographic();201var fromRectangle2DNortheast = new Cartographic();202/**203 * Computes a bounding sphere from a rectangle projected in 2D.204 *205 * @param {Rectangle} [rectangle] The rectangle around which to create a bounding sphere.206 * @param {Object} [projection=GeographicProjection] The projection used to project the rectangle into 2D.207 * @param {BoundingSphere} [result] The object onto which to store the result.208 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided.209 */210BoundingSphere.fromRectangle2D = function (rectangle, projection, result) {211 return BoundingSphere.fromRectangleWithHeights2D(212 rectangle,213 projection,214 0.0,215 0.0,216 result217 );218};219/**220 * Computes a bounding sphere from a rectangle projected in 2D. The bounding sphere accounts for the221 * object's minimum and maximum heights over the rectangle.222 *223 * @param {Rectangle} [rectangle] The rectangle around which to create a bounding sphere.224 * @param {Object} [projection=GeographicProjection] The projection used to project the rectangle into 2D.225 * @param {Number} [minimumHeight=0.0] The minimum height over the rectangle.226 * @param {Number} [maximumHeight=0.0] The maximum height over the rectangle.227 * @param {BoundingSphere} [result] The object onto which to store the result.228 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided.229 */230BoundingSphere.fromRectangleWithHeights2D = function (231 rectangle,232 projection,233 minimumHeight,234 maximumHeight,235 result236) {237 if (!defined(result)) {238 result = new BoundingSphere();239 }240 if (!defined(rectangle)) {241 result.center = Cartesian3.clone(Cartesian3.ZERO, result.center);242 result.radius = 0.0;243 return result;244 }245 projection = defaultValue(projection, defaultProjection);246 Rectangle.southwest(rectangle, fromRectangle2DSouthwest);247 fromRectangle2DSouthwest.height = minimumHeight;248 Rectangle.northeast(rectangle, fromRectangle2DNortheast);249 fromRectangle2DNortheast.height = maximumHeight;250 var lowerLeft = projection.project(251 fromRectangle2DSouthwest,252 fromRectangle2DLowerLeft253 );254 var upperRight = projection.project(255 fromRectangle2DNortheast,256 fromRectangle2DUpperRight257 );258 var width = upperRight.x - lowerLeft.x;259 var height = upperRight.y - lowerLeft.y;260 var elevation = upperRight.z - lowerLeft.z;261 result.radius =262 Math.sqrt(width * width + height * height + elevation * elevation) * 0.5;263 var center = result.center;264 center.x = lowerLeft.x + width * 0.5;265 center.y = lowerLeft.y + height * 0.5;266 center.z = lowerLeft.z + elevation * 0.5;267 return result;268};269var fromRectangle3DScratch = [];270/**271 * Computes a bounding sphere from a rectangle in 3D. The bounding sphere is created using a subsample of points272 * on the ellipsoid and contained in the rectangle. It may not be accurate for all rectangles on all types of ellipsoids.273 *274 * @param {Rectangle} [rectangle] The valid rectangle used to create a bounding sphere.275 * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid used to determine positions of the rectangle.276 * @param {Number} [surfaceHeight=0.0] The height above the surface of the ellipsoid.277 * @param {BoundingSphere} [result] The object onto which to store the result.278 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided.279 */280BoundingSphere.fromRectangle3D = function (281 rectangle,282 ellipsoid,283 surfaceHeight,284 result285) {286 ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84);287 surfaceHeight = defaultValue(surfaceHeight, 0.0);288 if (!defined(result)) {289 result = new BoundingSphere();290 }291 if (!defined(rectangle)) {292 result.center = Cartesian3.clone(Cartesian3.ZERO, result.center);293 result.radius = 0.0;294 return result;295 }296 var positions = Rectangle.subsample(297 rectangle,298 ellipsoid,299 surfaceHeight,300 fromRectangle3DScratch301 );302 return BoundingSphere.fromPoints(positions, result);303};304/**305 * Computes a tight-fitting bounding sphere enclosing a list of 3D points, where the points are306 * stored in a flat array in X, Y, Z, order. The bounding sphere is computed by running two307 * algorithms, a naive algorithm and Ritter's algorithm. The smaller of the two spheres is used to308 * ensure a tight fit.309 *310 * @param {Number[]} [positions] An array of points that the bounding sphere will enclose. Each point311 * is formed from three elements in the array in the order X, Y, Z.312 * @param {Cartesian3} [center=Cartesian3.ZERO] The position to which the positions are relative, which need not be the313 * origin of the coordinate system. This is useful when the positions are to be used for314 * relative-to-center (RTC) rendering.315 * @param {Number} [stride=3] The number of array elements per vertex. It must be at least 3, but it may316 * be higher. Regardless of the value of this parameter, the X coordinate of the first position317 * is at array index 0, the Y coordinate is at array index 1, and the Z coordinate is at array index318 * 2. When stride is 3, the X coordinate of the next position then begins at array index 3. If319 * the stride is 5, however, two array elements are skipped and the next position begins at array320 * index 5.321 * @param {BoundingSphere} [result] The object onto which to store the result.322 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided.323 *324 * @example325 * // Compute the bounding sphere from 3 positions, each specified relative to a center.326 * // In addition to the X, Y, and Z coordinates, the points array contains two additional327 * // elements per point which are ignored for the purpose of computing the bounding sphere.328 * var center = new Cesium.Cartesian3(1.0, 2.0, 3.0);329 * var points = [1.0, 2.0, 3.0, 0.1, 0.2,330 * 4.0, 5.0, 6.0, 0.1, 0.2,331 * 7.0, 8.0, 9.0, 0.1, 0.2];332 * var sphere = Cesium.BoundingSphere.fromVertices(points, center, 5);333 *334 * @see {@link http://blogs.agi.com/insight3d/index.php/2008/02/04/a-bounding/|Bounding Sphere computation article}335 */336BoundingSphere.fromVertices = function (positions, center, stride, result) {337 if (!defined(result)) {338 result = new BoundingSphere();339 }340 if (!defined(positions) || positions.length === 0) {341 result.center = Cartesian3.clone(Cartesian3.ZERO, result.center);342 result.radius = 0.0;343 return result;344 }345 center = defaultValue(center, Cartesian3.ZERO);346 stride = defaultValue(stride, 3);347 //>>includeStart('debug', pragmas.debug);348 Check.typeOf.number.greaterThanOrEquals("stride", stride, 3);349 //>>includeEnd('debug');350 var currentPos = fromPointsCurrentPos;351 currentPos.x = positions[0] + center.x;352 currentPos.y = positions[1] + center.y;353 currentPos.z = positions[2] + center.z;354 var xMin = Cartesian3.clone(currentPos, fromPointsXMin);355 var yMin = Cartesian3.clone(currentPos, fromPointsYMin);356 var zMin = Cartesian3.clone(currentPos, fromPointsZMin);357 var xMax = Cartesian3.clone(currentPos, fromPointsXMax);358 var yMax = Cartesian3.clone(currentPos, fromPointsYMax);359 var zMax = Cartesian3.clone(currentPos, fromPointsZMax);360 var numElements = positions.length;361 var i;362 for (i = 0; i < numElements; i += stride) {363 var x = positions[i] + center.x;364 var y = positions[i + 1] + center.y;365 var z = positions[i + 2] + center.z;366 currentPos.x = x;367 currentPos.y = y;368 currentPos.z = z;369 // Store points containing the the smallest and largest components370 if (x < xMin.x) {371 Cartesian3.clone(currentPos, xMin);372 }373 if (x > xMax.x) {374 Cartesian3.clone(currentPos, xMax);375 }376 if (y < yMin.y) {377 Cartesian3.clone(currentPos, yMin);378 }379 if (y > yMax.y) {380 Cartesian3.clone(currentPos, yMax);381 }382 if (z < zMin.z) {383 Cartesian3.clone(currentPos, zMin);384 }385 if (z > zMax.z) {386 Cartesian3.clone(currentPos, zMax);387 }388 }389 // Compute x-, y-, and z-spans (Squared distances b/n each component's min. and max.).390 var xSpan = Cartesian3.magnitudeSquared(391 Cartesian3.subtract(xMax, xMin, fromPointsScratch)392 );393 var ySpan = Cartesian3.magnitudeSquared(394 Cartesian3.subtract(yMax, yMin, fromPointsScratch)395 );396 var zSpan = Cartesian3.magnitudeSquared(397 Cartesian3.subtract(zMax, zMin, fromPointsScratch)398 );399 // Set the diameter endpoints to the largest span.400 var diameter1 = xMin;401 var diameter2 = xMax;402 var maxSpan = xSpan;403 if (ySpan > maxSpan) {404 maxSpan = ySpan;405 diameter1 = yMin;406 diameter2 = yMax;407 }408 if (zSpan > maxSpan) {409 maxSpan = zSpan;410 diameter1 = zMin;411 diameter2 = zMax;412 }413 // Calculate the center of the initial sphere found by Ritter's algorithm414 var ritterCenter = fromPointsRitterCenter;415 ritterCenter.x = (diameter1.x + diameter2.x) * 0.5;416 ritterCenter.y = (diameter1.y + diameter2.y) * 0.5;417 ritterCenter.z = (diameter1.z + diameter2.z) * 0.5;418 // Calculate the radius of the initial sphere found by Ritter's algorithm419 var radiusSquared = Cartesian3.magnitudeSquared(420 Cartesian3.subtract(diameter2, ritterCenter, fromPointsScratch)421 );422 var ritterRadius = Math.sqrt(radiusSquared);423 // Find the center of the sphere found using the Naive method.424 var minBoxPt = fromPointsMinBoxPt;425 minBoxPt.x = xMin.x;426 minBoxPt.y = yMin.y;427 minBoxPt.z = zMin.z;428 var maxBoxPt = fromPointsMaxBoxPt;429 maxBoxPt.x = xMax.x;430 maxBoxPt.y = yMax.y;431 maxBoxPt.z = zMax.z;432 var naiveCenter = Cartesian3.midpoint(433 minBoxPt,434 maxBoxPt,435 fromPointsNaiveCenterScratch436 );437 // Begin 2nd pass to find naive radius and modify the ritter sphere.438 var naiveRadius = 0;439 for (i = 0; i < numElements; i += stride) {440 currentPos.x = positions[i] + center.x;441 currentPos.y = positions[i + 1] + center.y;442 currentPos.z = positions[i + 2] + center.z;443 // Find the furthest point from the naive center to calculate the naive radius.444 var r = Cartesian3.magnitude(445 Cartesian3.subtract(currentPos, naiveCenter, fromPointsScratch)446 );447 if (r > naiveRadius) {448 naiveRadius = r;449 }450 // Make adjustments to the Ritter Sphere to include all points.451 var oldCenterToPointSquared = Cartesian3.magnitudeSquared(452 Cartesian3.subtract(currentPos, ritterCenter, fromPointsScratch)453 );454 if (oldCenterToPointSquared > radiusSquared) {455 var oldCenterToPoint = Math.sqrt(oldCenterToPointSquared);456 // Calculate new radius to include the point that lies outside457 ritterRadius = (ritterRadius + oldCenterToPoint) * 0.5;458 radiusSquared = ritterRadius * ritterRadius;459 // Calculate center of new Ritter sphere460 var oldToNew = oldCenterToPoint - ritterRadius;461 ritterCenter.x =462 (ritterRadius * ritterCenter.x + oldToNew * currentPos.x) /463 oldCenterToPoint;464 ritterCenter.y =465 (ritterRadius * ritterCenter.y + oldToNew * currentPos.y) /466 oldCenterToPoint;467 ritterCenter.z =468 (ritterRadius * ritterCenter.z + oldToNew * currentPos.z) /469 oldCenterToPoint;470 }471 }472 if (ritterRadius < naiveRadius) {473 Cartesian3.clone(ritterCenter, result.center);474 result.radius = ritterRadius;475 } else {476 Cartesian3.clone(naiveCenter, result.center);477 result.radius = naiveRadius;478 }479 return result;480};481/**482 * Computes a tight-fitting bounding sphere enclosing a list of EncodedCartesian3s, where the points are483 * stored in parallel flat arrays in X, Y, Z, order. The bounding sphere is computed by running two484 * algorithms, a naive algorithm and Ritter's algorithm. The smaller of the two spheres is used to485 * ensure a tight fit.486 *487 * @param {Number[]} [positionsHigh] An array of high bits of the encoded cartesians that the bounding sphere will enclose. Each point488 * is formed from three elements in the array in the order X, Y, Z.489 * @param {Number[]} [positionsLow] An array of low bits of the encoded cartesians that the bounding sphere will enclose. Each point490 * is formed from three elements in the array in the order X, Y, Z.491 * @param {BoundingSphere} [result] The object onto which to store the result.492 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided.493 *494 * @see {@link http://blogs.agi.com/insight3d/index.php/2008/02/04/a-bounding/|Bounding Sphere computation article}495 */496BoundingSphere.fromEncodedCartesianVertices = function (497 positionsHigh,498 positionsLow,499 result500) {501 if (!defined(result)) {502 result = new BoundingSphere();503 }504 if (505 !defined(positionsHigh) ||506 !defined(positionsLow) ||507 positionsHigh.length !== positionsLow.length ||508 positionsHigh.length === 0509 ) {510 result.center = Cartesian3.clone(Cartesian3.ZERO, result.center);511 result.radius = 0.0;512 return result;513 }514 var currentPos = fromPointsCurrentPos;515 currentPos.x = positionsHigh[0] + positionsLow[0];516 currentPos.y = positionsHigh[1] + positionsLow[1];517 currentPos.z = positionsHigh[2] + positionsLow[2];518 var xMin = Cartesian3.clone(currentPos, fromPointsXMin);519 var yMin = Cartesian3.clone(currentPos, fromPointsYMin);520 var zMin = Cartesian3.clone(currentPos, fromPointsZMin);521 var xMax = Cartesian3.clone(currentPos, fromPointsXMax);522 var yMax = Cartesian3.clone(currentPos, fromPointsYMax);523 var zMax = Cartesian3.clone(currentPos, fromPointsZMax);524 var numElements = positionsHigh.length;525 var i;526 for (i = 0; i < numElements; i += 3) {527 var x = positionsHigh[i] + positionsLow[i];528 var y = positionsHigh[i + 1] + positionsLow[i + 1];529 var z = positionsHigh[i + 2] + positionsLow[i + 2];530 currentPos.x = x;531 currentPos.y = y;532 currentPos.z = z;533 // Store points containing the the smallest and largest components534 if (x < xMin.x) {535 Cartesian3.clone(currentPos, xMin);536 }537 if (x > xMax.x) {538 Cartesian3.clone(currentPos, xMax);539 }540 if (y < yMin.y) {541 Cartesian3.clone(currentPos, yMin);542 }543 if (y > yMax.y) {544 Cartesian3.clone(currentPos, yMax);545 }546 if (z < zMin.z) {547 Cartesian3.clone(currentPos, zMin);548 }549 if (z > zMax.z) {550 Cartesian3.clone(currentPos, zMax);551 }552 }553 // Compute x-, y-, and z-spans (Squared distances b/n each component's min. and max.).554 var xSpan = Cartesian3.magnitudeSquared(555 Cartesian3.subtract(xMax, xMin, fromPointsScratch)556 );557 var ySpan = Cartesian3.magnitudeSquared(558 Cartesian3.subtract(yMax, yMin, fromPointsScratch)559 );560 var zSpan = Cartesian3.magnitudeSquared(561 Cartesian3.subtract(zMax, zMin, fromPointsScratch)562 );563 // Set the diameter endpoints to the largest span.564 var diameter1 = xMin;565 var diameter2 = xMax;566 var maxSpan = xSpan;567 if (ySpan > maxSpan) {568 maxSpan = ySpan;569 diameter1 = yMin;570 diameter2 = yMax;571 }572 if (zSpan > maxSpan) {573 maxSpan = zSpan;574 diameter1 = zMin;575 diameter2 = zMax;576 }577 // Calculate the center of the initial sphere found by Ritter's algorithm578 var ritterCenter = fromPointsRitterCenter;579 ritterCenter.x = (diameter1.x + diameter2.x) * 0.5;580 ritterCenter.y = (diameter1.y + diameter2.y) * 0.5;581 ritterCenter.z = (diameter1.z + diameter2.z) * 0.5;582 // Calculate the radius of the initial sphere found by Ritter's algorithm583 var radiusSquared = Cartesian3.magnitudeSquared(584 Cartesian3.subtract(diameter2, ritterCenter, fromPointsScratch)585 );586 var ritterRadius = Math.sqrt(radiusSquared);587 // Find the center of the sphere found using the Naive method.588 var minBoxPt = fromPointsMinBoxPt;589 minBoxPt.x = xMin.x;590 minBoxPt.y = yMin.y;591 minBoxPt.z = zMin.z;592 var maxBoxPt = fromPointsMaxBoxPt;593 maxBoxPt.x = xMax.x;594 maxBoxPt.y = yMax.y;595 maxBoxPt.z = zMax.z;596 var naiveCenter = Cartesian3.midpoint(597 minBoxPt,598 maxBoxPt,599 fromPointsNaiveCenterScratch600 );601 // Begin 2nd pass to find naive radius and modify the ritter sphere.602 var naiveRadius = 0;603 for (i = 0; i < numElements; i += 3) {604 currentPos.x = positionsHigh[i] + positionsLow[i];605 currentPos.y = positionsHigh[i + 1] + positionsLow[i + 1];606 currentPos.z = positionsHigh[i + 2] + positionsLow[i + 2];607 // Find the furthest point from the naive center to calculate the naive radius.608 var r = Cartesian3.magnitude(609 Cartesian3.subtract(currentPos, naiveCenter, fromPointsScratch)610 );611 if (r > naiveRadius) {612 naiveRadius = r;613 }614 // Make adjustments to the Ritter Sphere to include all points.615 var oldCenterToPointSquared = Cartesian3.magnitudeSquared(616 Cartesian3.subtract(currentPos, ritterCenter, fromPointsScratch)617 );618 if (oldCenterToPointSquared > radiusSquared) {619 var oldCenterToPoint = Math.sqrt(oldCenterToPointSquared);620 // Calculate new radius to include the point that lies outside621 ritterRadius = (ritterRadius + oldCenterToPoint) * 0.5;622 radiusSquared = ritterRadius * ritterRadius;623 // Calculate center of new Ritter sphere624 var oldToNew = oldCenterToPoint - ritterRadius;625 ritterCenter.x =626 (ritterRadius * ritterCenter.x + oldToNew * currentPos.x) /627 oldCenterToPoint;628 ritterCenter.y =629 (ritterRadius * ritterCenter.y + oldToNew * currentPos.y) /630 oldCenterToPoint;631 ritterCenter.z =632 (ritterRadius * ritterCenter.z + oldToNew * currentPos.z) /633 oldCenterToPoint;634 }635 }636 if (ritterRadius < naiveRadius) {637 Cartesian3.clone(ritterCenter, result.center);638 result.radius = ritterRadius;639 } else {640 Cartesian3.clone(naiveCenter, result.center);641 result.radius = naiveRadius;642 }643 return result;644};645/**646 * Computes a bounding sphere from the corner points of an axis-aligned bounding box. The sphere647 * tighly and fully encompases the box.648 *649 * @param {Cartesian3} [corner] The minimum height over the rectangle.650 * @param {Cartesian3} [oppositeCorner] The maximum height over the rectangle.651 * @param {BoundingSphere} [result] The object onto which to store the result.652 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided.653 *654 * @example655 * // Create a bounding sphere around the unit cube656 * var sphere = Cesium.BoundingSphere.fromCornerPoints(new Cesium.Cartesian3(-0.5, -0.5, -0.5), new Cesium.Cartesian3(0.5, 0.5, 0.5));657 */658BoundingSphere.fromCornerPoints = function (corner, oppositeCorner, result) {659 //>>includeStart('debug', pragmas.debug);660 Check.typeOf.object("corner", corner);661 Check.typeOf.object("oppositeCorner", oppositeCorner);662 //>>includeEnd('debug');663 if (!defined(result)) {664 result = new BoundingSphere();665 }666 var center = Cartesian3.midpoint(corner, oppositeCorner, result.center);667 result.radius = Cartesian3.distance(center, oppositeCorner);668 return result;669};670/**671 * Creates a bounding sphere encompassing an ellipsoid.672 *673 * @param {Ellipsoid} ellipsoid The ellipsoid around which to create a bounding sphere.674 * @param {BoundingSphere} [result] The object onto which to store the result.675 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided.676 *677 * @example678 * var boundingSphere = Cesium.BoundingSphere.fromEllipsoid(ellipsoid);679 */680BoundingSphere.fromEllipsoid = function (ellipsoid, result) {681 //>>includeStart('debug', pragmas.debug);682 Check.typeOf.object("ellipsoid", ellipsoid);683 //>>includeEnd('debug');684 if (!defined(result)) {685 result = new BoundingSphere();686 }687 Cartesian3.clone(Cartesian3.ZERO, result.center);688 result.radius = ellipsoid.maximumRadius;689 return result;690};691var fromBoundingSpheresScratch = new Cartesian3();692/**693 * Computes a tight-fitting bounding sphere enclosing the provided array of bounding spheres.694 *695 * @param {BoundingSphere[]} [boundingSpheres] The array of bounding spheres.696 * @param {BoundingSphere} [result] The object onto which to store the result.697 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided.698 */699BoundingSphere.fromBoundingSpheres = function (boundingSpheres, result) {700 if (!defined(result)) {701 result = new BoundingSphere();702 }703 if (!defined(boundingSpheres) || boundingSpheres.length === 0) {704 result.center = Cartesian3.clone(Cartesian3.ZERO, result.center);705 result.radius = 0.0;706 return result;707 }708 var length = boundingSpheres.length;709 if (length === 1) {710 return BoundingSphere.clone(boundingSpheres[0], result);711 }712 if (length === 2) {713 return BoundingSphere.union(boundingSpheres[0], boundingSpheres[1], result);714 }715 var positions = [];716 var i;717 for (i = 0; i < length; i++) {718 positions.push(boundingSpheres[i].center);719 }720 result = BoundingSphere.fromPoints(positions, result);721 var center = result.center;722 var radius = result.radius;723 for (i = 0; i < length; i++) {724 var tmp = boundingSpheres[i];725 radius = Math.max(726 radius,727 Cartesian3.distance(center, tmp.center, fromBoundingSpheresScratch) +728 tmp.radius729 );730 }731 result.radius = radius;732 return result;733};734var fromOrientedBoundingBoxScratchU = new Cartesian3();735var fromOrientedBoundingBoxScratchV = new Cartesian3();736var fromOrientedBoundingBoxScratchW = new Cartesian3();737/**738 * Computes a tight-fitting bounding sphere enclosing the provided oriented bounding box.739 *740 * @param {OrientedBoundingBox} orientedBoundingBox The oriented bounding box.741 * @param {BoundingSphere} [result] The object onto which to store the result.742 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided.743 */744BoundingSphere.fromOrientedBoundingBox = function (745 orientedBoundingBox,746 result747) {748 //>>includeStart('debug', pragmas.debug);749 Check.defined("orientedBoundingBox", orientedBoundingBox);750 //>>includeEnd('debug');751 if (!defined(result)) {752 result = new BoundingSphere();753 }754 var halfAxes = orientedBoundingBox.halfAxes;755 var u = Matrix3.getColumn(halfAxes, 0, fromOrientedBoundingBoxScratchU);756 var v = Matrix3.getColumn(halfAxes, 1, fromOrientedBoundingBoxScratchV);757 var w = Matrix3.getColumn(halfAxes, 2, fromOrientedBoundingBoxScratchW);758 Cartesian3.add(u, v, u);759 Cartesian3.add(u, w, u);760 result.center = Cartesian3.clone(orientedBoundingBox.center, result.center);761 result.radius = Cartesian3.magnitude(u);762 return result;763};764/**765 * Duplicates a BoundingSphere instance.766 *767 * @param {BoundingSphere} sphere The bounding sphere to duplicate.768 * @param {BoundingSphere} [result] The object onto which to store the result.769 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. (Returns undefined if sphere is undefined)770 */771BoundingSphere.clone = function (sphere, result) {772 if (!defined(sphere)) {773 return undefined;774 }775 if (!defined(result)) {776 return new BoundingSphere(sphere.center, sphere.radius);777 }778 result.center = Cartesian3.clone(sphere.center, result.center);779 result.radius = sphere.radius;780 return result;781};782/**783 * The number of elements used to pack the object into an array.784 * @type {Number}785 */786BoundingSphere.packedLength = 4;787/**788 * Stores the provided instance into the provided array.789 *790 * @param {BoundingSphere} value The value to pack.791 * @param {Number[]} array The array to pack into.792 * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.793 *794 * @returns {Number[]} The array that was packed into795 */796BoundingSphere.pack = function (value, array, startingIndex) {797 //>>includeStart('debug', pragmas.debug);798 Check.typeOf.object("value", value);799 Check.defined("array", array);800 //>>includeEnd('debug');801 startingIndex = defaultValue(startingIndex, 0);802 var center = value.center;803 array[startingIndex++] = center.x;804 array[startingIndex++] = center.y;805 array[startingIndex++] = center.z;806 array[startingIndex] = value.radius;807 return array;808};809/**810 * Retrieves an instance from a packed array.811 *812 * @param {Number[]} array The packed array.813 * @param {Number} [startingIndex=0] The starting index of the element to be unpacked.814 * @param {BoundingSphere} [result] The object into which to store the result.815 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided.816 */817BoundingSphere.unpack = function (array, startingIndex, result) {818 //>>includeStart('debug', pragmas.debug);819 Check.defined("array", array);820 //>>includeEnd('debug');821 startingIndex = defaultValue(startingIndex, 0);822 if (!defined(result)) {823 result = new BoundingSphere();824 }825 var center = result.center;826 center.x = array[startingIndex++];827 center.y = array[startingIndex++];828 center.z = array[startingIndex++];829 result.radius = array[startingIndex];830 return result;831};832var unionScratch = new Cartesian3();833var unionScratchCenter = new Cartesian3();834/**835 * Computes a bounding sphere that contains both the left and right bounding spheres.836 *837 * @param {BoundingSphere} left A sphere to enclose in a bounding sphere.838 * @param {BoundingSphere} right A sphere to enclose in a bounding sphere.839 * @param {BoundingSphere} [result] The object onto which to store the result.840 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided.841 */842BoundingSphere.union = function (left, right, result) {843 //>>includeStart('debug', pragmas.debug);844 Check.typeOf.object("left", left);845 Check.typeOf.object("right", right);846 //>>includeEnd('debug');847 if (!defined(result)) {848 result = new BoundingSphere();849 }850 var leftCenter = left.center;851 var leftRadius = left.radius;852 var rightCenter = right.center;853 var rightRadius = right.radius;854 var toRightCenter = Cartesian3.subtract(855 rightCenter,856 leftCenter,857 unionScratch858 );859 var centerSeparation = Cartesian3.magnitude(toRightCenter);860 if (leftRadius >= centerSeparation + rightRadius) {861 // Left sphere wins.862 left.clone(result);863 return result;864 }865 if (rightRadius >= centerSeparation + leftRadius) {866 // Right sphere wins.867 right.clone(result);868 return result;869 }870 // There are two tangent points, one on far side of each sphere.871 var halfDistanceBetweenTangentPoints =872 (leftRadius + centerSeparation + rightRadius) * 0.5;873 // Compute the center point halfway between the two tangent points.874 var center = Cartesian3.multiplyByScalar(875 toRightCenter,876 (-leftRadius + halfDistanceBetweenTangentPoints) / centerSeparation,877 unionScratchCenter878 );879 Cartesian3.add(center, leftCenter, center);880 Cartesian3.clone(center, result.center);881 result.radius = halfDistanceBetweenTangentPoints;882 return result;883};884var expandScratch = new Cartesian3();885/**886 * Computes a bounding sphere by enlarging the provided sphere to contain the provided point.887 *888 * @param {BoundingSphere} sphere A sphere to expand.889 * @param {Cartesian3} point A point to enclose in a bounding sphere.890 * @param {BoundingSphere} [result] The object onto which to store the result.891 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided.892 */893BoundingSphere.expand = function (sphere, point, result) {894 //>>includeStart('debug', pragmas.debug);895 Check.typeOf.object("sphere", sphere);896 Check.typeOf.object("point", point);897 //>>includeEnd('debug');898 result = BoundingSphere.clone(sphere, result);899 var radius = Cartesian3.magnitude(900 Cartesian3.subtract(point, result.center, expandScratch)901 );902 if (radius > result.radius) {903 result.radius = radius;904 }905 return result;906};907/**908 * Determines which side of a plane a sphere is located.909 *910 * @param {BoundingSphere} sphere The bounding sphere to test.911 * @param {Plane} plane The plane to test against.912 * @returns {Intersect} {@link Intersect.INSIDE} if the entire sphere is on the side of the plane913 * the normal is pointing, {@link Intersect.OUTSIDE} if the entire sphere is914 * on the opposite side, and {@link Intersect.INTERSECTING} if the sphere915 * intersects the plane.916 */917BoundingSphere.intersectPlane = function (sphere, plane) {918 //>>includeStart('debug', pragmas.debug);919 Check.typeOf.object("sphere", sphere);920 Check.typeOf.object("plane", plane);921 //>>includeEnd('debug');922 var center = sphere.center;923 var radius = sphere.radius;924 var normal = plane.normal;925 var distanceToPlane = Cartesian3.dot(normal, center) + plane.distance;926 if (distanceToPlane < -radius) {927 // The center point is negative side of the plane normal928 return Intersect.OUTSIDE;929 } else if (distanceToPlane < radius) {930 // The center point is positive side of the plane, but radius extends beyond it; partial overlap931 return Intersect.INTERSECTING;932 }933 return Intersect.INSIDE;934};935/**936 * Applies a 4x4 affine transformation matrix to a bounding sphere.937 *938 * @param {BoundingSphere} sphere The bounding sphere to apply the transformation to.939 * @param {Matrix4} transform The transformation matrix to apply to the bounding sphere.940 * @param {BoundingSphere} [result] The object onto which to store the result.941 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided.942 */943BoundingSphere.transform = function (sphere, transform, result) {944 //>>includeStart('debug', pragmas.debug);945 Check.typeOf.object("sphere", sphere);946 Check.typeOf.object("transform", transform);947 //>>includeEnd('debug');948 if (!defined(result)) {949 result = new BoundingSphere();950 }951 result.center = Matrix4.multiplyByPoint(952 transform,953 sphere.center,954 result.center955 );956 result.radius = Matrix4.getMaximumScale(transform) * sphere.radius;957 return result;958};959var distanceSquaredToScratch = new Cartesian3();960/**961 * Computes the estimated distance squared from the closest point on a bounding sphere to a point.962 *963 * @param {BoundingSphere} sphere The sphere.964 * @param {Cartesian3} cartesian The point965 * @returns {Number} The estimated distance squared from the bounding sphere to the point.966 *967 * @example968 * // Sort bounding spheres from back to front969 * spheres.sort(function(a, b) {970 * return Cesium.BoundingSphere.distanceSquaredTo(b, camera.positionWC) - Cesium.BoundingSphere.distanceSquaredTo(a, camera.positionWC);971 * });972 */973BoundingSphere.distanceSquaredTo = function (sphere, cartesian) {974 //>>includeStart('debug', pragmas.debug);975 Check.typeOf.object("sphere", sphere);976 Check.typeOf.object("cartesian", cartesian);977 //>>includeEnd('debug');978 var diff = Cartesian3.subtract(979 sphere.center,980 cartesian,981 distanceSquaredToScratch982 );983 return Cartesian3.magnitudeSquared(diff) - sphere.radius * sphere.radius;984};985/**986 * Applies a 4x4 affine transformation matrix to a bounding sphere where there is no scale987 * The transformation matrix is not verified to have a uniform scale of 1.988 * This method is faster than computing the general bounding sphere transform using {@link BoundingSphere.transform}.989 *990 * @param {BoundingSphere} sphere The bounding sphere to apply the transformation to.991 * @param {Matrix4} transform The transformation matrix to apply to the bounding sphere.992 * @param {BoundingSphere} [result] The object onto which to store the result.993 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided.994 *995 * @example996 * var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(positionOnEllipsoid);997 * var boundingSphere = new Cesium.BoundingSphere();998 * var newBoundingSphere = Cesium.BoundingSphere.transformWithoutScale(boundingSphere, modelMatrix);999 */1000BoundingSphere.transformWithoutScale = function (sphere, transform, result) {1001 //>>includeStart('debug', pragmas.debug);1002 Check.typeOf.object("sphere", sphere);1003 Check.typeOf.object("transform", transform);1004 //>>includeEnd('debug');1005 if (!defined(result)) {1006 result = new BoundingSphere();1007 }1008 result.center = Matrix4.multiplyByPoint(1009 transform,1010 sphere.center,1011 result.center1012 );1013 result.radius = sphere.radius;1014 return result;1015};1016var scratchCartesian3 = new Cartesian3();1017/**1018 * The distances calculated by the vector from the center of the bounding sphere to position projected onto direction1019 * plus/minus the radius of the bounding sphere.1020 * <br>1021 * If you imagine the infinite number of planes with normal direction, this computes the smallest distance to the1022 * closest and farthest planes from position that intersect the bounding sphere.1023 *1024 * @param {BoundingSphere} sphere The bounding sphere to calculate the distance to.1025 * @param {Cartesian3} position The position to calculate the distance from.1026 * @param {Cartesian3} direction The direction from position.1027 * @param {Interval} [result] A Interval to store the nearest and farthest distances.1028 * @returns {Interval} The nearest and farthest distances on the bounding sphere from position in direction.1029 */1030BoundingSphere.computePlaneDistances = function (1031 sphere,1032 position,1033 direction,1034 result1035) {1036 //>>includeStart('debug', pragmas.debug);1037 Check.typeOf.object("sphere", sphere);1038 Check.typeOf.object("position", position);1039 Check.typeOf.object("direction", direction);1040 //>>includeEnd('debug');1041 if (!defined(result)) {1042 result = new Interval();1043 }1044 var toCenter = Cartesian3.subtract(1045 sphere.center,1046 position,1047 scratchCartesian31048 );1049 var mag = Cartesian3.dot(direction, toCenter);1050 result.start = mag - sphere.radius;1051 result.stop = mag + sphere.radius;1052 return result;1053};1054var projectTo2DNormalScratch = new Cartesian3();1055var projectTo2DEastScratch = new Cartesian3();1056var projectTo2DNorthScratch = new Cartesian3();1057var projectTo2DWestScratch = new Cartesian3();1058var projectTo2DSouthScratch = new Cartesian3();1059var projectTo2DCartographicScratch = new Cartographic();1060var projectTo2DPositionsScratch = new Array(8);1061for (var n = 0; n < 8; ++n) {1062 projectTo2DPositionsScratch[n] = new Cartesian3();1063}1064var projectTo2DProjection = new GeographicProjection();1065/**1066 * Creates a bounding sphere in 2D from a bounding sphere in 3D world coordinates.1067 *1068 * @param {BoundingSphere} sphere The bounding sphere to transform to 2D.1069 * @param {Object} [projection=GeographicProjection] The projection to 2D.1070 * @param {BoundingSphere} [result] The object onto which to store the result.1071 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided.1072 */1073BoundingSphere.projectTo2D = function (sphere, projection, result) {1074 //>>includeStart('debug', pragmas.debug);1075 Check.typeOf.object("sphere", sphere);1076 //>>includeEnd('debug');1077 projection = defaultValue(projection, projectTo2DProjection);1078 var ellipsoid = projection.ellipsoid;1079 var center = sphere.center;1080 var radius = sphere.radius;1081 var normal;1082 if (Cartesian3.equals(center, Cartesian3.ZERO)) {1083 // Bounding sphere is at the center. The geodetic surface normal is not1084 // defined here so pick the x-axis as a fallback.1085 normal = Cartesian3.clone(Cartesian3.UNIT_X, projectTo2DNormalScratch);1086 } else {1087 normal = ellipsoid.geodeticSurfaceNormal(center, projectTo2DNormalScratch);1088 }1089 var east = Cartesian3.cross(1090 Cartesian3.UNIT_Z,1091 normal,1092 projectTo2DEastScratch1093 );1094 Cartesian3.normalize(east, east);1095 var north = Cartesian3.cross(normal, east, projectTo2DNorthScratch);1096 Cartesian3.normalize(north, north);1097 Cartesian3.multiplyByScalar(normal, radius, normal);1098 Cartesian3.multiplyByScalar(north, radius, north);1099 Cartesian3.multiplyByScalar(east, radius, east);1100 var south = Cartesian3.negate(north, projectTo2DSouthScratch);1101 var west = Cartesian3.negate(east, projectTo2DWestScratch);1102 var positions = projectTo2DPositionsScratch;1103 // top NE corner1104 var corner = positions[0];1105 Cartesian3.add(normal, north, corner);1106 Cartesian3.add(corner, east, corner);1107 // top NW corner1108 corner = positions[1];1109 Cartesian3.add(normal, north, corner);1110 Cartesian3.add(corner, west, corner);1111 // top SW corner1112 corner = positions[2];1113 Cartesian3.add(normal, south, corner);1114 Cartesian3.add(corner, west, corner);1115 // top SE corner1116 corner = positions[3];1117 Cartesian3.add(normal, south, corner);1118 Cartesian3.add(corner, east, corner);1119 Cartesian3.negate(normal, normal);1120 // bottom NE corner1121 corner = positions[4];1122 Cartesian3.add(normal, north, corner);1123 Cartesian3.add(corner, east, corner);1124 // bottom NW corner1125 corner = positions[5];1126 Cartesian3.add(normal, north, corner);1127 Cartesian3.add(corner, west, corner);1128 // bottom SW corner1129 corner = positions[6];1130 Cartesian3.add(normal, south, corner);1131 Cartesian3.add(corner, west, corner);1132 // bottom SE corner1133 corner = positions[7];1134 Cartesian3.add(normal, south, corner);1135 Cartesian3.add(corner, east, corner);1136 var length = positions.length;1137 for (var i = 0; i < length; ++i) {1138 var position = positions[i];1139 Cartesian3.add(center, position, position);1140 var cartographic = ellipsoid.cartesianToCartographic(1141 position,1142 projectTo2DCartographicScratch1143 );1144 projection.project(cartographic, position);1145 }1146 result = BoundingSphere.fromPoints(positions, result);1147 // swizzle center components1148 center = result.center;1149 var x = center.x;1150 var y = center.y;1151 var z = center.z;1152 center.x = z;1153 center.y = x;1154 center.z = y;1155 return result;1156};1157/**1158 * Determines whether or not a sphere is hidden from view by the occluder.1159 *1160 * @param {BoundingSphere} sphere The bounding sphere surrounding the occludee object.1161 * @param {Occluder} occluder The occluder.1162 * @returns {Boolean} <code>true</code> if the sphere is not visible; otherwise <code>false</code>.1163 */1164BoundingSphere.isOccluded = function (sphere, occluder) {1165 //>>includeStart('debug', pragmas.debug);1166 Check.typeOf.object("sphere", sphere);1167 Check.typeOf.object("occluder", occluder);1168 //>>includeEnd('debug');1169 return !occluder.isBoundingSphereVisible(sphere);1170};1171/**1172 * Compares the provided BoundingSphere componentwise and returns1173 * <code>true</code> if they are equal, <code>false</code> otherwise.1174 *1175 * @param {BoundingSphere} [left] The first BoundingSphere.1176 * @param {BoundingSphere} [right] The second BoundingSphere.1177 * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise.1178 */1179BoundingSphere.equals = function (left, right) {1180 return (1181 left === right ||1182 (defined(left) &&1183 defined(right) &&1184 Cartesian3.equals(left.center, right.center) &&1185 left.radius === right.radius)1186 );1187};1188/**1189 * Determines which side of a plane the sphere is located.1190 *1191 * @param {Plane} plane The plane to test against.1192 * @returns {Intersect} {@link Intersect.INSIDE} if the entire sphere is on the side of the plane1193 * the normal is pointing, {@link Intersect.OUTSIDE} if the entire sphere is1194 * on the opposite side, and {@link Intersect.INTERSECTING} if the sphere1195 * intersects the plane.1196 */1197BoundingSphere.prototype.intersectPlane = function (plane) {1198 return BoundingSphere.intersectPlane(this, plane);1199};1200/**1201 * Computes the estimated distance squared from the closest point on a bounding sphere to a point.1202 *1203 * @param {Cartesian3} cartesian The point1204 * @returns {Number} The estimated distance squared from the bounding sphere to the point.1205 *1206 * @example1207 * // Sort bounding spheres from back to front1208 * spheres.sort(function(a, b) {1209 * return b.distanceSquaredTo(camera.positionWC) - a.distanceSquaredTo(camera.positionWC);1210 * });1211 */1212BoundingSphere.prototype.distanceSquaredTo = function (cartesian) {1213 return BoundingSphere.distanceSquaredTo(this, cartesian);1214};1215/**1216 * The distances calculated by the vector from the center of the bounding sphere to position projected onto direction1217 * plus/minus the radius of the bounding sphere.1218 * <br>1219 * If you imagine the infinite number of planes with normal direction, this computes the smallest distance to the1220 * closest and farthest planes from position that intersect the bounding sphere.1221 *1222 * @param {Cartesian3} position The position to calculate the distance from.1223 * @param {Cartesian3} direction The direction from position.1224 * @param {Interval} [result] A Interval to store the nearest and farthest distances.1225 * @returns {Interval} The nearest and farthest distances on the bounding sphere from position in direction.1226 */1227BoundingSphere.prototype.computePlaneDistances = function (1228 position,1229 direction,1230 result1231) {1232 return BoundingSphere.computePlaneDistances(1233 this,1234 position,1235 direction,1236 result1237 );1238};1239/**1240 * Determines whether or not a sphere is hidden from view by the occluder.1241 *1242 * @param {Occluder} occluder The occluder.1243 * @returns {Boolean} <code>true</code> if the sphere is not visible; otherwise <code>false</code>.1244 */1245BoundingSphere.prototype.isOccluded = function (occluder) {1246 return BoundingSphere.isOccluded(this, occluder);1247};1248/**1249 * Compares this BoundingSphere against the provided BoundingSphere componentwise and returns1250 * <code>true</code> if they are equal, <code>false</code> otherwise.1251 *1252 * @param {BoundingSphere} [right] The right hand side BoundingSphere.1253 * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise.1254 */1255BoundingSphere.prototype.equals = function (right) {1256 return BoundingSphere.equals(this, right);1257};1258/**1259 * Duplicates this BoundingSphere instance.1260 *1261 * @param {BoundingSphere} [result] The object onto which to store the result.1262 * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided.1263 */1264BoundingSphere.prototype.clone = function (result) {1265 return BoundingSphere.clone(this, result);1266};1267/**1268 * Computes the radius of the BoundingSphere.1269 * @returns {Number} The radius of the BoundingSphere.1270 */1271BoundingSphere.prototype.volume = function () {1272 var radius = this.radius;1273 return volumeConstant * radius * radius * radius;1274};...`

Cesium3DTileSpec.js

Source:Cesium3DTileSpec.js

```1defineSuite([2 'Scene/Cesium3DTile',3 'Core/Cartesian3',4 'Core/clone',5 'Core/defined',6 'Core/HeadingPitchRoll',7 'Core/loadWithXhr',8 'Core/Math',9 'Core/Matrix3',10 'Core/Matrix4',11 'Core/Rectangle',12 'Core/SphereOutlineGeometry',13 'Core/Transforms',14 'Scene/Cesium3DTileRefine',15 'Scene/TileBoundingRegion',16 'Scene/TileOrientedBoundingBox',17 'Specs/createScene'18 ], function(19 Cesium3DTile,20 Cartesian3,21 clone,22 defined,23 HeadingPitchRoll,24 loadWithXhr,25 CesiumMath,26 Matrix3,27 Matrix4,28 Rectangle,29 SphereOutlineGeometry,30 Transforms,31 Cesium3DTileRefine,32 TileBoundingRegion,33 TileOrientedBoundingBox,34 createScene) {35 'use strict';3637 var tileWithBoundingSphere = {38 geometricError : 1,39 refine : 'REPLACE',40 children : [],41 boundingVolume : {42 sphere: [0.0, 0.0, 0.0, 5.0]43 }44 };4546 var tileWithContentBoundingSphere = {47 geometricError : 1,48 refine : 'REPLACE',49 content : {50 url : '0/0.b3dm',51 boundingVolume : {52 sphere: [0.0, 0.0, 1.0, 5.0]53 }54 },55 children : [],56 boundingVolume : {57 sphere: [0.0, 0.0, 1.0, 5.0]58 }59 };6061 var tileWithBoundingRegion = {62 geometricError : 1,63 refine : 'REPLACE',64 children : [],65 boundingVolume: {66 region : [-1.2, -1.2, 0.0, 0.0, -30, -34]67 }68 };6970 var tileWithContentBoundingRegion = {71 geometricError : 1,72 refine : 'REPLACE',73 children : [],74 content : {75 url : '0/0.b3dm',76 boundingVolume : {77 region : [-1.2, -1.2, 0, 0, -30, -34]78 }79 },80 boundingVolume: {81 region : [-1.2, -1.2, 0, 0, -30, -34]82 }83 };8485 var tileWithBoundingBox = {86 geometricError : 1,87 refine : 'REPLACE',88 children : [],89 boundingVolume: {90 box : [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]91 }92 };9394 var tileWithContentBoundingBox = {95 geometricError : 1,96 refine : 'REPLACE',97 children : [],98 content : {99 url : '0/0.b3dm',100 boundingVolume : {101 box : [0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 2.0]102 }103 },104 boundingVolume: {105 box : [0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 2.0]106 }107 };108109 var tileWithViewerRequestVolume = {110 geometricError : 1,111 refine : 'REPLACE',112 children : [],113 boundingVolume: {114 box : [0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 2.0]115 },116 viewerRequestVolume : {117 box : [0.0, 0.0, 1.0, 2.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 2.0]118 }119 };120121 var mockTileset = {122 debugShowBoundingVolume : true,123 debugShowViewerRequestVolume : true,124 modelMatrix : Matrix4.IDENTITY,125 _geometricError : 2126 };127128 var centerLongitude = -1.31968;129 var centerLatitude = 0.698874;130131 function getTileTransform(longitude, latitude) {132 var transformCenter = Cartesian3.fromRadians(longitude, latitude, 0.0);133 var hpr = new HeadingPitchRoll();134 var transformMatrix = Transforms.headingPitchRollToFixedFrame(transformCenter, hpr);135 return Matrix4.pack(transformMatrix, new Array(16));136 }137138 it('destroys', function() {139 var tile = new Cesium3DTile(mockTileset, '/some_url', tileWithBoundingSphere, undefined);140 expect(tile.isDestroyed()).toEqual(false);141 tile.destroy();142 expect(tile.isDestroyed()).toEqual(true);143 });144145 it('throws if boundingVolume is undefined', function() {146 var tileWithoutBoundingVolume = clone(tileWithBoundingSphere, true);147 delete tileWithoutBoundingVolume.boundingVolume;148 expect(function() {149 return new Cesium3DTile(mockTileset, '/some_url', tileWithoutBoundingVolume, undefined);150 }).toThrowRuntimeError();151 });152153 it('throws if boundingVolume does not contain a sphere, region, or box', function() {154 var tileWithoutBoundingVolume = clone(tileWithBoundingSphere, true);155 delete tileWithoutBoundingVolume.boundingVolume.sphere;156 expect(function() {157 return new Cesium3DTile(mockTileset, '/some_url', tileWithoutBoundingVolume, undefined);158 }).toThrowRuntimeError();159 });160161 it('logs deprecation warning if refine is lowercase', function() {162 spyOn(Cesium3DTile, '_deprecationWarning');163 var header = clone(tileWithBoundingSphere, true);164 header.refine = 'replace';165 var tile = new Cesium3DTile(mockTileset, '/some_url', header, undefined);166 expect(tile.refine).toBe(Cesium3DTileRefine.REPLACE);167 expect(Cesium3DTile._deprecationWarning).toHaveBeenCalled();168 });169170 it('logs deprecation warning if geometric error is undefined', function() {171 spyOn(Cesium3DTile, '_deprecationWarning');172173 var geometricErrorMissing = clone(tileWithBoundingSphere, true);174 delete geometricErrorMissing.geometricError;175176 var parent = new Cesium3DTile(mockTileset, '/some_url', tileWithBoundingSphere, undefined);177 var child = new Cesium3DTile(mockTileset, '/some_url', geometricErrorMissing, parent);178 expect(child.geometricError).toBe(parent.geometricError);179 expect(child.geometricError).toBe(1);180181 var tile = new Cesium3DTile(mockTileset, '/some_url', geometricErrorMissing, undefined);182 expect(tile.geometricError).toBe(mockTileset._geometricError);183 expect(tile.geometricError).toBe(2);184185 expect(Cesium3DTile._deprecationWarning.calls.count()).toBe(2);186 });187188 describe('bounding volumes', function() {189 it('can have a bounding sphere', function() {190 var tile = new Cesium3DTile(mockTileset, '/some_url', tileWithBoundingSphere, undefined);191 var radius = tileWithBoundingSphere.boundingVolume.sphere[3];192 expect(tile.contentBoundingVolume).toBeDefined();193 expect(tile.contentBoundingVolume.boundingVolume.radius).toEqual(radius);194 expect(tile.contentBoundingVolume.boundingVolume.center).toEqual(Cartesian3.ZERO);195 });196197 it('can have a content bounding sphere', function() {198 var tile = new Cesium3DTile(mockTileset, '/some_url', tileWithContentBoundingSphere, undefined);199 var radius = tileWithContentBoundingSphere.content.boundingVolume.sphere[3];200 expect(tile.contentBoundingVolume).toBeDefined();201 expect(tile.contentBoundingVolume.boundingVolume.radius).toEqual(radius);202 expect(tile.contentBoundingVolume.boundingVolume.center).toEqual(new Cartesian3(0.0, 0.0, 1.0));203 });204205 it('can have a bounding region', function() {206 var box = tileWithBoundingRegion.boundingVolume.region;207 var rectangle = new Rectangle(box[0], box[1], box[2], box[3]);208 var minimumHeight = tileWithBoundingRegion.boundingVolume.region[4];209 var maximumHeight = tileWithBoundingRegion.boundingVolume.region[5];210 var tile = new Cesium3DTile(mockTileset, '/some_url', tileWithBoundingRegion, undefined);211 var tbr = new TileBoundingRegion({rectangle: rectangle, minimumHeight: minimumHeight, maximumHeight: maximumHeight});212 expect(tile.contentBoundingVolume).toBeDefined();213 expect(tile.contentBoundingVolume).toEqual(tbr);214 });215216 it('can have a content bounding region', function() {217 var region = tileWithContentBoundingRegion.content.boundingVolume.region;218 var tile = new Cesium3DTile(mockTileset, '/some_url', tileWithContentBoundingRegion, undefined);219 expect(tile._contentBoundingVolume).toBeDefined();220 var tbb = new TileBoundingRegion({221 rectangle: new Rectangle(region[0], region[1], region[2], region[3]),222 minimumHeight: region[4],223 maximumHeight: region[5]224 });225 expect(tile._contentBoundingVolume).toEqual(tbb);226 });227228 it('can have an oriented bounding box', function() {229 var box = tileWithBoundingBox.boundingVolume.box;230 var tile = new Cesium3DTile(mockTileset, '/some_url', tileWithBoundingBox, undefined);231 expect(tile.contentBoundingVolume).toBeDefined();232 var center = new Cartesian3(box[0], box[1], box[2]);233 var halfAxes = Matrix3.fromArray(box, 3);234 var obb = new TileOrientedBoundingBox(center, halfAxes);235 expect(tile.contentBoundingVolume).toEqual(obb);236 });237238 it('can have a content oriented bounding box', function() {239 var box = tileWithContentBoundingBox.boundingVolume.box;240 var tile = new Cesium3DTile(mockTileset, '/some_url', tileWithContentBoundingBox, undefined);241 expect(tile.contentBoundingVolume).toBeDefined();242 var center = new Cartesian3(box[0], box[1], box[2]);243 var halfAxes = Matrix3.fromArray(box, 3);244 var obb = new TileOrientedBoundingBox(center, halfAxes);245 expect(tile.contentBoundingVolume).toEqual(obb);246 });247248 it('tile transform affects bounding sphere', function() {249 var header = clone(tileWithContentBoundingSphere, true);250 header.transform = getTileTransform(centerLongitude, centerLatitude);251 var tile = new Cesium3DTile(mockTileset, '/some_url', header, undefined);252 var boundingSphere = tile._boundingVolume.boundingVolume;253 var contentBoundingSphere = tile._contentBoundingVolume.boundingVolume;254255 var boundingVolumeCenter = Cartesian3.fromRadians(centerLongitude, centerLatitude, 1.0);256 expect(boundingSphere.center).toEqualEpsilon(boundingVolumeCenter, CesiumMath.EPSILON4);257 expect(boundingSphere.radius).toEqual(5.0); // No change258259 expect(contentBoundingSphere.center).toEqualEpsilon(boundingVolumeCenter, CesiumMath.EPSILON4);260 expect(contentBoundingSphere.radius).toEqual(5.0); // No change261 });262263 it('tile transform affects oriented bounding box', function() {264 var header = clone(tileWithContentBoundingBox, true);265 header.transform = getTileTransform(centerLongitude, centerLatitude);266 var tile = new Cesium3DTile(mockTileset, '/some_url', header, undefined);267 var boundingBox = tile._boundingVolume.boundingVolume;268 var contentBoundingBox = tile._contentBoundingVolume.boundingVolume;269270 var boundingVolumeCenter = Cartesian3.fromRadians(centerLongitude, centerLatitude, 1.0);271 expect(boundingBox.center).toEqualEpsilon(boundingVolumeCenter, CesiumMath.EPSILON7);272 expect(contentBoundingBox.center).toEqualEpsilon(boundingVolumeCenter, CesiumMath.EPSILON7);273 });274275 it('tile transform does not affect bounding region', function() {276 var header = clone(tileWithContentBoundingRegion, true);277 header.transform = getTileTransform(centerLongitude, centerLatitude);278 var tile = new Cesium3DTile(mockTileset, '/some_url', header, undefined);279 var boundingRegion = tile._boundingVolume;280 var contentBoundingRegion = tile._contentBoundingVolume;281282 var region = header.boundingVolume.region;283 var rectangle = Rectangle.unpack(region);284 expect(boundingRegion.rectangle).toEqual(rectangle);285 expect(contentBoundingRegion.rectangle).toEqual(rectangle);286 });287288 it('tile transform affects viewer request volume', function() {289 var header = clone(tileWithViewerRequestVolume, true);290 header.transform = getTileTransform(centerLongitude, centerLatitude);291 var tile = new Cesium3DTile(mockTileset, '/some_url', header, undefined);292 var requestVolume = tile._viewerRequestVolume.boundingVolume;293 var requestVolumeCenter = Cartesian3.fromRadians(centerLongitude, centerLatitude, 1.0);294 expect(requestVolume.center).toEqualEpsilon(requestVolumeCenter, CesiumMath.EPSILON7);295 });296297 it('tile transform changes', function() {298 var mockTileset = {299 modelMatrix : Matrix4.IDENTITY300 };301 var header = clone(tileWithBoundingSphere, true);302 header.transform = getTileTransform(centerLongitude, centerLatitude);303 var tile = new Cesium3DTile(mockTileset, '/some_url', header, undefined);304 var boundingSphere = tile._boundingVolume.boundingVolume;305306 // Check the original transform307 var boundingVolumeCenter = Cartesian3.fromRadians(centerLongitude, centerLatitude);308 expect(boundingSphere.center).toEqualEpsilon(boundingVolumeCenter, CesiumMath.EPSILON7);309310 // Change the transform311 var newLongitude = -1.012;312 var newLatitude = 0.698874;313 tile.transform = getTileTransform(newLongitude, newLatitude);314 tile.updateTransform();315316 // Check the new transform317 var newCenter = Cartesian3.fromRadians(newLongitude, newLatitude);318 expect(boundingSphere.center).toEqualEpsilon(newCenter, CesiumMath.EPSILON7);319 });320 });321322 describe('debug bounding volumes', function() {323 it('can be a bounding region', function() {324 var scene = createScene();325 var tile = new Cesium3DTile(mockTileset, '/some_url', tileWithBoundingRegion, undefined);326 tile.update(mockTileset, scene.frameState);327 expect(tile._debugBoundingVolume).toBeDefined();328 });329330 it('can be an oriented bounding box', function() {331 var scene = createScene();332 var tile = new Cesium3DTile(mockTileset, '/some_url', tileWithBoundingBox, undefined);333 tile.update(mockTileset, scene.frameState);334 expect(tile._debugBoundingVolume).toBeDefined();335 });336337 it('can be a bounding sphere', function() {338 var scene = createScene();339 var tile = new Cesium3DTile(mockTileset, '/some_url', tileWithBoundingSphere, undefined);340 tile.update(mockTileset, scene.frameState);341 expect(tile._debugBoundingVolume).toBeDefined();342 });343344 it('creates debug bounding volume for viewer request volume', function() {345 var scene = createScene();346 var tile = new Cesium3DTile(mockTileset, '/some_url', tileWithViewerRequestVolume, undefined);347 tile.update(mockTileset, scene.frameState);348 expect(tile._debugViewerRequestVolume).toBeDefined();349 });350 }); ...```

BoundingRectangle.js

Source:BoundingRectangle.js

`1import Cartesian2 from "./Cartesian2.js";2import Cartographic from "./Cartographic.js";3import Check from "./Check.js";4import defaultValue from "./defaultValue.js";5import defined from "./defined.js";6import GeographicProjection from "./GeographicProjection.js";7import Intersect from "./Intersect.js";8import Rectangle from "./Rectangle.js";9/**10 * A bounding rectangle given by a corner, width and height.11 * @alias BoundingRectangle12 * @constructor13 *14 * @param {Number} [x=0.0] The x coordinate of the rectangle.15 * @param {Number} [y=0.0] The y coordinate of the rectangle.16 * @param {Number} [width=0.0] The width of the rectangle.17 * @param {Number} [height=0.0] The height of the rectangle.18 *19 * @see BoundingSphere20 * @see Packable21 */22function BoundingRectangle(x, y, width, height) {23 /**24 * The x coordinate of the rectangle.25 * @type {Number}26 * @default 0.027 */28 this.x = defaultValue(x, 0.0);29 /**30 * The y coordinate of the rectangle.31 * @type {Number}32 * @default 0.033 */34 this.y = defaultValue(y, 0.0);35 /**36 * The width of the rectangle.37 * @type {Number}38 * @default 0.039 */40 this.width = defaultValue(width, 0.0);41 /**42 * The height of the rectangle.43 * @type {Number}44 * @default 0.045 */46 this.height = defaultValue(height, 0.0);47}48/**49 * The number of elements used to pack the object into an array.50 * @type {Number}51 */52BoundingRectangle.packedLength = 4;53/**54 * Stores the provided instance into the provided array.55 *56 * @param {BoundingRectangle} value The value to pack.57 * @param {Number[]} array The array to pack into.58 * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.59 *60 * @returns {Number[]} The array that was packed into61 */62BoundingRectangle.pack = function (value, array, startingIndex) {63 //>>includeStart('debug', pragmas.debug);64 Check.typeOf.object("value", value);65 Check.defined("array", array);66 //>>includeEnd('debug');67 startingIndex = defaultValue(startingIndex, 0);68 array[startingIndex++] = value.x;69 array[startingIndex++] = value.y;70 array[startingIndex++] = value.width;71 array[startingIndex] = value.height;72 return array;73};74/**75 * Retrieves an instance from a packed array.76 *77 * @param {Number[]} array The packed array.78 * @param {Number} [startingIndex=0] The starting index of the element to be unpacked.79 * @param {BoundingRectangle} [result] The object into which to store the result.80 * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided.81 */82BoundingRectangle.unpack = function (array, startingIndex, result) {83 //>>includeStart('debug', pragmas.debug);84 Check.defined("array", array);85 //>>includeEnd('debug');86 startingIndex = defaultValue(startingIndex, 0);87 if (!defined(result)) {88 result = new BoundingRectangle();89 }90 result.x = array[startingIndex++];91 result.y = array[startingIndex++];92 result.width = array[startingIndex++];93 result.height = array[startingIndex];94 return result;95};96/**97 * Computes a bounding rectangle enclosing the list of 2D points.98 * The rectangle is oriented with the corner at the bottom left.99 *100 * @param {Cartesian2[]} positions List of points that the bounding rectangle will enclose. Each point must have <code>x</code> and <code>y</code> properties.101 * @param {BoundingRectangle} [result] The object onto which to store the result.102 * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided.103 */104BoundingRectangle.fromPoints = function (positions, result) {105 if (!defined(result)) {106 result = new BoundingRectangle();107 }108 if (!defined(positions) || positions.length === 0) {109 result.x = 0;110 result.y = 0;111 result.width = 0;112 result.height = 0;113 return result;114 }115 var length = positions.length;116 var minimumX = positions[0].x;117 var minimumY = positions[0].y;118 var maximumX = positions[0].x;119 var maximumY = positions[0].y;120 for (var i = 1; i < length; i++) {121 var p = positions[i];122 var x = p.x;123 var y = p.y;124 minimumX = Math.min(x, minimumX);125 maximumX = Math.max(x, maximumX);126 minimumY = Math.min(y, minimumY);127 maximumY = Math.max(y, maximumY);128 }129 result.x = minimumX;130 result.y = minimumY;131 result.width = maximumX - minimumX;132 result.height = maximumY - minimumY;133 return result;134};135var defaultProjection = new GeographicProjection();136var fromRectangleLowerLeft = new Cartographic();137var fromRectangleUpperRight = new Cartographic();138/**139 * Computes a bounding rectangle from a rectangle.140 *141 * @param {Rectangle} rectangle The valid rectangle used to create a bounding rectangle.142 * @param {Object} [projection=GeographicProjection] The projection used to project the rectangle into 2D.143 * @param {BoundingRectangle} [result] The object onto which to store the result.144 * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided.145 */146BoundingRectangle.fromRectangle = function (rectangle, projection, result) {147 if (!defined(result)) {148 result = new BoundingRectangle();149 }150 if (!defined(rectangle)) {151 result.x = 0;152 result.y = 0;153 result.width = 0;154 result.height = 0;155 return result;156 }157 projection = defaultValue(projection, defaultProjection);158 var lowerLeft = projection.project(159 Rectangle.southwest(rectangle, fromRectangleLowerLeft)160 );161 var upperRight = projection.project(162 Rectangle.northeast(rectangle, fromRectangleUpperRight)163 );164 Cartesian2.subtract(upperRight, lowerLeft, upperRight);165 result.x = lowerLeft.x;166 result.y = lowerLeft.y;167 result.width = upperRight.x;168 result.height = upperRight.y;169 return result;170};171/**172 * Duplicates a BoundingRectangle instance.173 *174 * @param {BoundingRectangle} rectangle The bounding rectangle to duplicate.175 * @param {BoundingRectangle} [result] The object onto which to store the result.176 * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. (Returns undefined if rectangle is undefined)177 */178BoundingRectangle.clone = function (rectangle, result) {179 if (!defined(rectangle)) {180 return undefined;181 }182 if (!defined(result)) {183 return new BoundingRectangle(184 rectangle.x,185 rectangle.y,186 rectangle.width,187 rectangle.height188 );189 }190 result.x = rectangle.x;191 result.y = rectangle.y;192 result.width = rectangle.width;193 result.height = rectangle.height;194 return result;195};196/**197 * Computes a bounding rectangle that is the union of the left and right bounding rectangles.198 *199 * @param {BoundingRectangle} left A rectangle to enclose in bounding rectangle.200 * @param {BoundingRectangle} right A rectangle to enclose in a bounding rectangle.201 * @param {BoundingRectangle} [result] The object onto which to store the result.202 * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided.203 */204BoundingRectangle.union = function (left, right, result) {205 //>>includeStart('debug', pragmas.debug);206 Check.typeOf.object("left", left);207 Check.typeOf.object("right", right);208 //>>includeEnd('debug');209 if (!defined(result)) {210 result = new BoundingRectangle();211 }212 var lowerLeftX = Math.min(left.x, right.x);213 var lowerLeftY = Math.min(left.y, right.y);214 var upperRightX = Math.max(left.x + left.width, right.x + right.width);215 var upperRightY = Math.max(left.y + left.height, right.y + right.height);216 result.x = lowerLeftX;217 result.y = lowerLeftY;218 result.width = upperRightX - lowerLeftX;219 result.height = upperRightY - lowerLeftY;220 return result;221};222/**223 * Computes a bounding rectangle by enlarging the provided rectangle until it contains the provided point.224 *225 * @param {BoundingRectangle} rectangle A rectangle to expand.226 * @param {Cartesian2} point A point to enclose in a bounding rectangle.227 * @param {BoundingRectangle} [result] The object onto which to store the result.228 * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided.229 */230BoundingRectangle.expand = function (rectangle, point, result) {231 //>>includeStart('debug', pragmas.debug);232 Check.typeOf.object("rectangle", rectangle);233 Check.typeOf.object("point", point);234 //>>includeEnd('debug');235 result = BoundingRectangle.clone(rectangle, result);236 var width = point.x - result.x;237 var height = point.y - result.y;238 if (width > result.width) {239 result.width = width;240 } else if (width < 0) {241 result.width -= width;242 result.x = point.x;243 }244 if (height > result.height) {245 result.height = height;246 } else if (height < 0) {247 result.height -= height;248 result.y = point.y;249 }250 return result;251};252/**253 * Determines if two rectangles intersect.254 *255 * @param {BoundingRectangle} left A rectangle to check for intersection.256 * @param {BoundingRectangle} right The other rectangle to check for intersection.257 * @returns {Intersect} <code>Intersect.INTESECTING</code> if the rectangles intersect, <code>Intersect.OUTSIDE</code> otherwise.258 */259BoundingRectangle.intersect = function (left, right) {260 //>>includeStart('debug', pragmas.debug);261 Check.typeOf.object("left", left);262 Check.typeOf.object("right", right);263 //>>includeEnd('debug');264 var leftX = left.x;265 var leftY = left.y;266 var rightX = right.x;267 var rightY = right.y;268 if (269 !(270 leftX > rightX + right.width ||271 leftX + left.width < rightX ||272 leftY + left.height < rightY ||273 leftY > rightY + right.height274 )275 ) {276 return Intersect.INTERSECTING;277 }278 return Intersect.OUTSIDE;279};280/**281 * Compares the provided BoundingRectangles componentwise and returns282 * <code>true</code> if they are equal, <code>false</code> otherwise.283 *284 * @param {BoundingRectangle} [left] The first BoundingRectangle.285 * @param {BoundingRectangle} [right] The second BoundingRectangle.286 * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise.287 */288BoundingRectangle.equals = function (left, right) {289 return (290 left === right ||291 (defined(left) &&292 defined(right) &&293 left.x === right.x &&294 left.y === right.y &&295 left.width === right.width &&296 left.height === right.height)297 );298};299/**300 * Duplicates this BoundingRectangle instance.301 *302 * @param {BoundingRectangle} [result] The object onto which to store the result.303 * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided.304 */305BoundingRectangle.prototype.clone = function (result) {306 return BoundingRectangle.clone(this, result);307};308/**309 * Determines if this rectangle intersects with another.310 *311 * @param {BoundingRectangle} right A rectangle to check for intersection.312 * @returns {Intersect} <code>Intersect.INTESECTING</code> if the rectangles intersect, <code>Intersect.OUTSIDE</code> otherwise.313 */314BoundingRectangle.prototype.intersect = function (right) {315 return BoundingRectangle.intersect(this, right);316};317/**318 * Compares this BoundingRectangle against the provided BoundingRectangle componentwise and returns319 * <code>true</code> if they are equal, <code>false</code> otherwise.320 *321 * @param {BoundingRectangle} [right] The right hand side BoundingRectangle.322 * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise.323 */324BoundingRectangle.prototype.equals = function (right) {325 return BoundingRectangle.equals(this, right);326};...`

Using AI Code Generation

`1const { synthetixio } = require('synthetixio-synpress');2const { SynthetixJs } = require('synthetix-js');3const { ethers } = require('ethers');4const { assert } = require('chai');5const { utils } = ethers;6const { toBytes32 } = SynthetixJs.utils;7const { toUnit } = SynthetixJs.utils;8const { connectContract } = synthetixio;9const { connectContracts } = synthetixio;10const { connectSigner } = synthetixio;11const { connectSigners } = synthetixio;12const { fastForward } = synthetixio;13const { fastForwardTo } = synthetixio;14const { getAccounts } = synthetixio;15const { getContract } = synthetixio;16const { getContracts } = synthetixio;17const { getSigner } = synthetixio;18const { getSigners } = synthetixio;19const { takeSnapshot } = synthetixio;20const { revertToSnapshot } = synthetixio;21const { toBN } = synthetixio;22const { toBytes32 } = synthetixio;23const { toUnit } = synthetixio;24const { web3 } = synthetixio;25const { writeSetting } = synthetixio;26const { writeSettingWithValue } = synthetixio;27const { toBytes32 } = SynthetixJs.utils;28const { toUnit } = SynthetixJs.utils;29const { connectContract } = synthetixio;30const { connectContracts } = synthetixio;31const { connectSigner } = synthetixio;32const { connectSigners } = synthetixio;33const { fastForward } = synthetixio;34const { fastForwardTo } = synthetixio;35const { getAccounts } = synthetixio;36const { getContract } = synthetixio;37const { getContracts } = synthetixio;38const { getSigner } = synthetixio;39const { getSigners } = synthetixio;40const { takeSnapshot } = synthetixio;41const { revertToSnapshot } = synthetixio;42const { toBN } = synthetixio;43const { toBytes32`

Using AI Code Generation

`1const synthetixioSynpress = require('synthetixio-synpress');2const { Synpress } = synthetixioSynpress;3const synpress = new Synpress();4(async () => {5 await synpress.init();6 const bounding = await synpress.bounding();7 console.log(bounding);8})();9{10 "bounding": {11 }12}13const synthetixioSynpress = require('synthetixio-synpress');14const { Synpress } = synthetixioSynpress;15const synpress = new Synpress();16(async () => {17 await synpress.init();18 const bounding = await synpress.bounding();19 console.log(bounding);20})();21{22 "bounding": {23 }24}25const synthetixioSynpress = require('synthetixio-synpress');26const { Synpress } = synthetixioSynpress;27const synpress = new Synpress();28(async () => {29 await synpress.init();30 const bounding = await synpress.bounding();31 console.log(bounding);32})();33{34 "bounding": {35 }36}37const synthetixioSynpress = require('synthetixio-synpress');38const { Synpress } = synthetixioSynpress;39const synpress = new Synpress();40(async () => {41 await synpress.init();42 const bounding = await synpress.bounding();43 console.log(bounding);44})();45{46 "bounding": {47 }48}`

Using AI Code Generation

`1const synthetixio = require('synthetixio-synpress');2const { toBN } = require('web3-utils');3const synthetix = synthetixio.contractSettings.requireContract('Synthetix');4const synthetixAddress = synthetix.options.address;5const synthetix2 = synthetixio.contractSettings.requireContract('Synthetix');6const synthetixAddress2 = synthetix2.options.address;7const synthetix3 = synthetixio.contractSettings.requireContract('Synthetix');8const synthetixAddress3 = synthetix3.options.address;9const synthetix4 = synthetixio.contractSettings.requireContract('Synthetix');10const synthetixAddress4 = synthetix4.options.address;11const synthetix5 = synthetixio.contractSettings.requireContract('Synthetix');12const synthetixAddress5 = synthetix5.options.address;13const synthetix6 = synthetixio.contractSettings.requireContract('Synthetix');14const synthetixAddress6 = synthetix6.options.address;15const synthetix7 = synthetixio.contractSettings.requireContract('Synthetix');16const synthetixAddress7 = synthetix7.options.address;17const synthetix8 = synthetixio.contractSettings.requireContract('Synthetix');18const synthetixAddress8 = synthetix8.options.address;19const synthetix9 = synthetixio.contractSettings.requireContract('Synthetix');20const synthetixAddress9 = synthetix9.options.address;21const synthetix10 = synthetixio.contractSettings.requireContract('Synthetix');22const synthetixAddress10 = synthetix10.options.address;23const synthetix11 = synthetixio.contractSettings.requireContract('Synthetix');`

Using AI Code Generation

`1const { bounding } = require('synthetixio-synpress');2const point = {x: 1, y: 2};3const bbox = bounding(point);4console.log(bbox);5const { bounding } = require('synthetixio-synpress');6const point = {x: 1, y: 2};7const bbox = bounding(point);8console.log(bbox);9const { bounding } = require('synthetixio-synpress');10const point = {x: 1, y: 2};11const bbox = bounding(point);12console.log(bbox);13const { bounding } = require('synthetixio-synpress');14const point = {x: 1, y: 2};15const bbox = bounding(point);16console.log(bbox);17const { bounding } = require('synthetixio-synpress');`

Using AI Code Generation

`1const synthetixioSynpress = require('synthetixio-synpress');2const bounding = synthetixioSynpress.bounding;3const testFunc = (x) => {4 return Math.pow(x, 2);5};6const result = bounding(testFunc, 0.5, 100, 1e-4);7console.log(result);`

Using AI Code Generation

`1var synthetixio-synpress = require('synthetixio-synpress');2var geojson = require('./points.geojson');3var bbox = synthetixio-synpress.bbox(geojson);4var fs = require('fs');5fs.writeFileSync('bbox.geojson', JSON.stringify(bbox));6console.log(bbox);7var geojson = require('./points.geojson');8var bbox = synthetixio-synpress.bbox(geojson);9console.log(bbox);10var geojson = require('./points.geojson');11var bbox = synthetixio-synpress.bbox(geojson);12console.log(bbox);13var geojson = require('./points.geojson');14var bbox = synthetixio-synpress.bbox(geojson);15console.log(bbox);16var geojson = require('./points.geojson');17var bbox = synthetixio-synpress.bbox(geojson);18console.log(bbox);19var geojson = require('./points.geojson');20var bbox = synthetixio-synpress.bbox(geojson);21console.log(bbox);22var geojson = require('./points.geojson');23var bbox = synthetixio-synpress.bbox(geojson);24console.log(bbox);25var geojson = require('./points.geojson');26var bbox = synthetixio-synpress.bbox(geojson);`

## Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.