import { BoundingSphere } from "../../Source/Cesium.js"; import { Cartesian3 } from "../../Source/Cesium.js"; import { Cartographic } from "../../Source/Cesium.js"; import { Ellipsoid } from "../../Source/Cesium.js"; import { EncodedCartesian3 } from "../../Source/Cesium.js"; import { GeographicProjection } from "../../Source/Cesium.js"; import { Intersect } from "../../Source/Cesium.js"; import { Interval } from "../../Source/Cesium.js"; import { Math as CesiumMath } from "../../Source/Cesium.js"; import { Matrix4 } from "../../Source/Cesium.js"; import { OrientedBoundingBox } from "../../Source/Cesium.js"; import { Plane } from "../../Source/Cesium.js"; import { Rectangle } from "../../Source/Cesium.js"; import createPackableSpecs from "../createPackableSpecs.js"; describe("Core/BoundingSphere", function () { var positionsRadius = 1.0; var positionsCenter = new Cartesian3(10000001.0, 0.0, 0.0); var center = new Cartesian3(10000000.0, 0.0, 0.0); function getPositions() { return [ Cartesian3.add(center, new Cartesian3(1, 0, 0), new Cartesian3()), Cartesian3.add(center, new Cartesian3(2, 0, 0), new Cartesian3()), Cartesian3.add(center, new Cartesian3(0, 0, 0), new Cartesian3()), Cartesian3.add(center, new Cartesian3(1, 1, 0), new Cartesian3()), Cartesian3.add(center, new Cartesian3(1, -1, 0), new Cartesian3()), Cartesian3.add(center, new Cartesian3(1, 0, 1), new Cartesian3()), Cartesian3.add(center, new Cartesian3(1, 0, -1), new Cartesian3()), ]; } function getPositionsAsFlatArray() { var positions = getPositions(); var result = []; for (var i = 0; i < positions.length; ++i) { result.push(positions[i].x); result.push(positions[i].y); result.push(positions[i].z); } return result; } function getPositionsAsFlatArrayWithStride5() { var positions = getPositions(); var result = []; for (var i = 0; i < positions.length; ++i) { result.push(positions[i].x); result.push(positions[i].y); result.push(positions[i].z); result.push(1.23); result.push(4.56); } return result; } function getPositionsAsEncodedFlatArray() { var positions = getPositions(); var high = []; var low = []; for (var i = 0; i < positions.length; ++i) { var encoded = EncodedCartesian3.fromCartesian(positions[i]); high.push(encoded.high.x); high.push(encoded.high.y); high.push(encoded.high.z); low.push(encoded.low.x); low.push(encoded.low.y); low.push(encoded.low.z); } return { high: high, low: low, }; } it("default constructing produces expected values", function () { var sphere = new BoundingSphere(); expect(sphere.center).toEqual(Cartesian3.ZERO); expect(sphere.radius).toEqual(0.0); }); it("constructor sets expected values", function () { var expectedCenter = new Cartesian3(1.0, 2.0, 3.0); var expectedRadius = 1.0; var sphere = new BoundingSphere(expectedCenter, expectedRadius); expect(sphere.center).toEqual(expectedCenter); expect(sphere.radius).toEqual(expectedRadius); }); it("clone without a result parameter", function () { var sphere = new BoundingSphere(new Cartesian3(1.0, 2.0, 3.0), 4.0); var result = sphere.clone(); expect(sphere).not.toBe(result); expect(sphere).toEqual(result); }); it("clone with a result parameter", function () { var sphere = new BoundingSphere(new Cartesian3(1.0, 2.0, 3.0), 4.0); var result = new BoundingSphere(); var returnedResult = sphere.clone(result); expect(result).not.toBe(sphere); expect(result).toBe(returnedResult); expect(result).toEqual(sphere); }); it('clone works with "this" result parameter', function () { var expectedCenter = new Cartesian3(1.0, 2.0, 3.0); var expectedRadius = 1.0; var sphere = new BoundingSphere(expectedCenter, expectedRadius); var returnedResult = sphere.clone(sphere); expect(sphere).toBe(returnedResult); expect(sphere.center).toEqual(expectedCenter); expect(sphere.radius).toEqual(expectedRadius); }); it("clone clones undefined", function () { expect(BoundingSphere.clone(undefined)).toBe(undefined); }); it("equals", function () { var sphere = new BoundingSphere(new Cartesian3(1.0, 2.0, 3.0), 4.0); expect( sphere.equals(new BoundingSphere(new Cartesian3(1.0, 2.0, 3.0), 4.0)) ).toEqual(true); expect( sphere.equals(new BoundingSphere(new Cartesian3(5.0, 2.0, 3.0), 4.0)) ).toEqual(false); expect( sphere.equals(new BoundingSphere(new Cartesian3(1.0, 6.0, 3.0), 4.0)) ).toEqual(false); expect( sphere.equals(new BoundingSphere(new Cartesian3(1.0, 2.0, 7.0), 4.0)) ).toEqual(false); expect( sphere.equals(new BoundingSphere(new Cartesian3(1.0, 2.0, 3.0), 8.0)) ).toEqual(false); expect(sphere.equals(undefined)).toEqual(false); }); it("fromPoints without positions returns an empty sphere", function () { var sphere = BoundingSphere.fromPoints(); expect(sphere.center).toEqual(Cartesian3.ZERO); expect(sphere.radius).toEqual(0.0); }); it("fromPoints works with one point", function () { var expectedCenter = new Cartesian3(1.0, 2.0, 3.0); var sphere = BoundingSphere.fromPoints([expectedCenter]); expect(sphere.center).toEqual(expectedCenter); expect(sphere.radius).toEqual(0.0); }); it("fromPoints computes a center from points", function () { var sphere = BoundingSphere.fromPoints(getPositions()); expect(sphere.center).toEqual(positionsCenter); expect(sphere.radius).toEqual(positionsRadius); }); it("fromPoints contains all points (naive)", function () { var sphere = BoundingSphere.fromPoints(getPositions()); var radius = sphere.radius; var center = sphere.center; var r = new Cartesian3(radius, radius, radius); var max = Cartesian3.add(r, center, new Cartesian3()); var min = Cartesian3.subtract(center, r, new Cartesian3()); var positions = getPositions(); var numPositions = positions.length; for (var i = 0; i < numPositions; i++) { var currentPos = positions[i]; expect(currentPos.x <= max.x && currentPos.x >= min.x).toEqual(true); expect(currentPos.y <= max.y && currentPos.y >= min.y).toEqual(true); expect(currentPos.z <= max.z && currentPos.z >= min.z).toEqual(true); } }); it("fromPoints contains all points (ritter)", function () { var positions = getPositions(); positions.push( new Cartesian3(1, 1, 1), new Cartesian3(2, 2, 2), new Cartesian3(3, 3, 3) ); var sphere = BoundingSphere.fromPoints(positions); var radius = sphere.radius; var center = sphere.center; var r = new Cartesian3(radius, radius, radius); var max = Cartesian3.add(r, center, new Cartesian3()); var min = Cartesian3.subtract(center, r, new Cartesian3()); var numPositions = positions.length; for (var i = 0; i < numPositions; i++) { var currentPos = positions[i]; expect(currentPos.x <= max.x && currentPos.x >= min.x).toEqual(true); expect(currentPos.y <= max.y && currentPos.y >= min.y).toEqual(true); expect(currentPos.z <= max.z && currentPos.z >= min.z).toEqual(true); } }); it("fromVertices without positions returns an empty sphere", function () { var sphere = BoundingSphere.fromVertices(); expect(sphere.center).toEqual(Cartesian3.ZERO); expect(sphere.radius).toEqual(0.0); }); it("fromVertices works with one point", function () { var expectedCenter = new Cartesian3(1.0, 2.0, 3.0); var sphere = BoundingSphere.fromVertices([ expectedCenter.x, expectedCenter.y, expectedCenter.z, ]); expect(sphere.center).toEqual(expectedCenter); expect(sphere.radius).toEqual(0.0); }); it("fromVertices computes a center from points", function () { var sphere = BoundingSphere.fromVertices(getPositionsAsFlatArray()); expect(sphere.center).toEqual(positionsCenter); expect(sphere.radius).toEqual(positionsRadius); }); it("fromVertices contains all points (naive)", function () { var sphere = BoundingSphere.fromVertices(getPositionsAsFlatArray()); var radius = sphere.radius; var center = sphere.center; var r = new Cartesian3(radius, radius, radius); var max = Cartesian3.add(r, center, new Cartesian3()); var min = Cartesian3.subtract(center, r, new Cartesian3()); var positions = getPositions(); var numPositions = positions.length; for (var i = 0; i < numPositions; i++) { var currentPos = positions[i]; expect(currentPos.x <= max.x && currentPos.x >= min.x).toEqual(true); expect(currentPos.y <= max.y && currentPos.y >= min.y).toEqual(true); expect(currentPos.z <= max.z && currentPos.z >= min.z).toEqual(true); } }); it("fromVertices contains all points (ritter)", function () { var positions = getPositionsAsFlatArray(); positions.push(1, 1, 1, 2, 2, 2, 3, 3, 3); var sphere = BoundingSphere.fromVertices(positions); var radius = sphere.radius; var center = sphere.center; var r = new Cartesian3(radius, radius, radius); var max = Cartesian3.add(r, center, new Cartesian3()); var min = Cartesian3.subtract(center, r, new Cartesian3()); var numElements = positions.length; for (var i = 0; i < numElements; i += 3) { expect(positions[i] <= max.x && positions[i] >= min.x).toEqual(true); expect(positions[i + 1] <= max.y && positions[i + 1] >= min.y).toEqual( true ); expect(positions[i + 2] <= max.z && positions[i + 2] >= min.z).toEqual( true ); } }); it("fromVertices works with a stride of 5", function () { var sphere = BoundingSphere.fromVertices( getPositionsAsFlatArrayWithStride5(), undefined, 5 ); expect(sphere.center).toEqual(positionsCenter); expect(sphere.radius).toEqual(positionsRadius); }); it("fromVertices works with defined center", function () { var center = new Cartesian3(1.0, 2.0, 3.0); var sphere = BoundingSphere.fromVertices( getPositionsAsFlatArrayWithStride5(), center, 5 ); expect(sphere.center).toEqual( Cartesian3.add(positionsCenter, center, new Cartesian3()) ); expect(sphere.radius).toEqual(positionsRadius); }); it("fromVertices requires a stride of at least 3", function () { function callWithStrideOf2() { BoundingSphere.fromVertices(getPositionsAsFlatArray(), undefined, 2); } expect(callWithStrideOf2).toThrowDeveloperError(); }); it("fromVertices fills result parameter if specified", function () { var center = new Cartesian3(1.0, 2.0, 3.0); var result = new BoundingSphere(); var sphere = BoundingSphere.fromVertices( getPositionsAsFlatArrayWithStride5(), center, 5, result ); expect(sphere).toEqual(result); expect(result.center).toEqual( Cartesian3.add(positionsCenter, center, new Cartesian3()) ); expect(result.radius).toEqual(positionsRadius); }); it("fromEncodedCartesianVertices without positions returns an empty sphere", function () { var sphere = BoundingSphere.fromEncodedCartesianVertices(); expect(sphere.center).toEqual(Cartesian3.ZERO); expect(sphere.radius).toEqual(0.0); }); it("fromEncodedCartesianVertices without positions of different lengths returns an empty sphere", function () { var positions = getPositionsAsEncodedFlatArray(); positions.low.length = positions.low.length - 1; var sphere = BoundingSphere.fromEncodedCartesianVertices( positions.high, positions.low ); expect(sphere.center).toEqual(Cartesian3.ZERO); expect(sphere.radius).toEqual(0.0); }); it("fromEncodedCartesianVertices computes a center from points", function () { var positions = getPositionsAsEncodedFlatArray(); var sphere = BoundingSphere.fromEncodedCartesianVertices( positions.high, positions.low ); expect(sphere.center).toEqual(positionsCenter); expect(sphere.radius).toEqual(positionsRadius); }); it("fromEncodedCartesianVertices contains all points (naive)", function () { var positions = getPositionsAsEncodedFlatArray(); var sphere = BoundingSphere.fromEncodedCartesianVertices( positions.high, positions.low ); var radius = sphere.radius; var center = sphere.center; var r = new Cartesian3(radius, radius, radius); var max = Cartesian3.add(r, center, new Cartesian3()); var min = Cartesian3.subtract(center, r, new Cartesian3()); positions = getPositions(); var numPositions = positions.length; for (var i = 0; i < numPositions; i++) { var currentPos = positions[i]; expect(currentPos.x <= max.x && currentPos.x >= min.x).toEqual(true); expect(currentPos.y <= max.y && currentPos.y >= min.y).toEqual(true); expect(currentPos.z <= max.z && currentPos.z >= min.z).toEqual(true); } }); it("fromEncodedCartesianVertices contains all points (ritter)", function () { var positions = getPositionsAsEncodedFlatArray(); var appendedPositions = [ new Cartesian3(1, 1, 1), new Cartesian3(2, 2, 2), new Cartesian3(3, 3, 3), ]; for (var j = 0; j < appendedPositions.length; ++j) { var encoded = EncodedCartesian3.fromCartesian( Cartesian3.add(appendedPositions[j], center, new Cartesian3()) ); positions.high.push(encoded.high.x); positions.high.push(encoded.high.y); positions.high.push(encoded.high.z); positions.low.push(encoded.low.x); positions.low.push(encoded.low.y); positions.low.push(encoded.low.z); } var sphere = BoundingSphere.fromEncodedCartesianVertices( positions.high, positions.low ); var radius = sphere.radius; var sphereCenter = sphere.center; var r = new Cartesian3(radius, radius, radius); var max = Cartesian3.add(r, sphereCenter, new Cartesian3()); var min = Cartesian3.subtract(sphereCenter, r, new Cartesian3()); var numElements = positions.length; for (var i = 0; i < numElements; i += 3) { expect(positions[i] <= max.x && positions[i] >= min.x).toEqual(true); expect(positions[i + 1] <= max.y && positions[i + 1] >= min.y).toEqual( true ); expect(positions[i + 2] <= max.z && positions[i + 2] >= min.z).toEqual( true ); } }); it("fromEncodedCartesianVertices fills result parameter if specified", function () { var positions = getPositionsAsEncodedFlatArray(); var result = new BoundingSphere(); var sphere = BoundingSphere.fromEncodedCartesianVertices( positions.high, positions.low, result ); expect(sphere).toEqual(result); expect(result.center).toEqual(positionsCenter); expect(result.radius).toEqual(positionsRadius); }); it("fromRectangle2D creates an empty sphere if no rectangle provided", function () { var sphere = BoundingSphere.fromRectangle2D(); expect(sphere.center).toEqual(Cartesian3.ZERO); expect(sphere.radius).toEqual(0.0); }); it("fromRectangle2D", function () { var rectangle = Rectangle.MAX_VALUE; var projection = new GeographicProjection(Ellipsoid.UNIT_SPHERE); var expected = new BoundingSphere( Cartesian3.ZERO, Math.sqrt( rectangle.east * rectangle.east + rectangle.north * rectangle.north ) ); expect(BoundingSphere.fromRectangle2D(rectangle, projection)).toEqual( expected ); }); it("fromRectangle3D creates an empty sphere if no rectangle provided", function () { var sphere = BoundingSphere.fromRectangle3D(); expect(sphere.center).toEqual(Cartesian3.ZERO); expect(sphere.radius).toEqual(0.0); }); it("fromRectangle3D", function () { var rectangle = Rectangle.MAX_VALUE; var ellipsoid = Ellipsoid.WGS84; var expected = new BoundingSphere(Cartesian3.ZERO, ellipsoid.maximumRadius); expect(BoundingSphere.fromRectangle3D(rectangle, ellipsoid)).toEqual( expected ); }); it("fromRectangle3D with height", function () { var rectangle = new Rectangle(0.1, -0.3, 0.2, -0.4); var height = 100000.0; var ellipsoid = Ellipsoid.WGS84; var points = Rectangle.subsample(rectangle, ellipsoid, height); var expected = BoundingSphere.fromPoints(points); expect( BoundingSphere.fromRectangle3D(rectangle, ellipsoid, height) ).toEqual(expected); }); it("fromCornerPoints", function () { var sphere = BoundingSphere.fromCornerPoints( new Cartesian3(-1.0, -0.0, 0.0), new Cartesian3(1.0, 0.0, 0.0) ); expect(sphere).toEqual(new BoundingSphere(Cartesian3.ZERO, 1.0)); }); it("fromCornerPoints with a result parameter", function () { var sphere = new BoundingSphere(); var result = BoundingSphere.fromCornerPoints( new Cartesian3(0.0, -1.0, 0.0), new Cartesian3(0.0, 1.0, 0.0), sphere ); expect(result).toBe(sphere); expect(result).toEqual(new BoundingSphere(Cartesian3.ZERO, 1.0)); }); it("fromCornerPoints throws without corner", function () { expect(function () { BoundingSphere.fromCornerPoints(); }).toThrowDeveloperError(); }); it("fromCornerPoints throws without oppositeCorner", function () { expect(function () { BoundingSphere.fromCornerPoints(Cartesian3.UNIT_X); }).toThrowDeveloperError(); }); it("fromEllipsoid", function () { var ellipsoid = Ellipsoid.WGS84; var sphere = BoundingSphere.fromEllipsoid(ellipsoid); expect(sphere.center).toEqual(Cartesian3.ZERO); expect(sphere.radius).toEqual(ellipsoid.maximumRadius); }); it("fromEllipsoid with a result parameter", function () { var ellipsoid = Ellipsoid.WGS84; var sphere = new BoundingSphere(new Cartesian3(1.0, 2.0, 3.0), 4.0); var result = BoundingSphere.fromEllipsoid(ellipsoid, sphere); expect(result).toBe(sphere); expect(result).toEqual( new BoundingSphere(Cartesian3.ZERO, ellipsoid.maximumRadius) ); }); it("fromEllipsoid throws without ellipsoid", function () { expect(function () { BoundingSphere.fromEllipsoid(); }).toThrowDeveloperError(); }); it("fromBoundingSpheres with undefined returns an empty sphere", function () { var sphere = BoundingSphere.fromBoundingSpheres(); expect(sphere.center).toEqual(Cartesian3.ZERO); expect(sphere.radius).toEqual(0.0); }); it("fromBoundingSpheres with empty array returns an empty sphere", function () { var sphere = BoundingSphere.fromBoundingSpheres([]); expect(sphere.center).toEqual(Cartesian3.ZERO); expect(sphere.radius).toEqual(0.0); }); it("fromBoundingSpheres works with 1 sphere", function () { var one = new BoundingSphere(new Cartesian3(1, 2, 3), 4); var sphere = BoundingSphere.fromBoundingSpheres([one]); expect(sphere).toEqual(one); }); it("fromBoundingSpheres works with 2 spheres", function () { var one = new BoundingSphere(new Cartesian3(1, 2, 3), 4); var two = new BoundingSphere(new Cartesian3(5, 6, 7), 8); var sphere = BoundingSphere.fromBoundingSpheres([one, two]); expect(sphere).toEqual( BoundingSphere.union(one, two, new BoundingSphere()) ); }); it("fromBoundingSpheres works with 3 spheres", function () { var one = new BoundingSphere(new Cartesian3(0, 0, 0), 1); var two = new BoundingSphere(new Cartesian3(0, 3, 0), 1); var three = new BoundingSphere(new Cartesian3(0, 0, 4), 1); var expected = new BoundingSphere(new Cartesian3(0.0, 1.5, 2.0), 3.5); var sphere = BoundingSphere.fromBoundingSpheres([one, two, three]); expect(sphere).toEqual(expected); }); it("fromOrientedBoundingBox works with a result", function () { var box = OrientedBoundingBox.fromPoints(getPositions()); var sphere = new BoundingSphere(); BoundingSphere.fromOrientedBoundingBox(box, sphere); expect(sphere.center).toEqual(positionsCenter); expect(sphere.radius).toBeGreaterThan(1.5); expect(sphere.radius).toBeLessThan(2.0); }); it("fromOrientedBoundingBox works without a result parameter", function () { var box = OrientedBoundingBox.fromPoints(getPositions()); var sphere = BoundingSphere.fromOrientedBoundingBox(box); expect(sphere.center).toEqual(positionsCenter); expect(sphere.radius).toBeGreaterThan(1.5); expect(sphere.radius).toBeLessThan(2.0); }); it("throws from fromOrientedBoundingBox with undefined orientedBoundingBox parameter", function () { expect(function () { BoundingSphere.fromOrientedBoundingBox(undefined); }).toThrowDeveloperError(); }); it("intersectPlane with sphere on the positive side of a plane", function () { var sphere = new BoundingSphere(Cartesian3.ZERO, 0.5); var normal = Cartesian3.negate(Cartesian3.UNIT_X, new Cartesian3()); var position = Cartesian3.UNIT_X; var plane = new Plane(normal, -Cartesian3.dot(normal, position)); expect(sphere.intersectPlane(plane)).toEqual(Intersect.INSIDE); }); it("intersectPlane with sphere on the negative side of a plane", function () { var sphere = new BoundingSphere(Cartesian3.ZERO, 0.5); var normal = Cartesian3.UNIT_X; var position = Cartesian3.UNIT_X; var plane = new Plane(normal, -Cartesian3.dot(normal, position)); expect(sphere.intersectPlane(plane)).toEqual(Intersect.OUTSIDE); }); it("intersectPlane with sphere intersecting a plane", function () { var sphere = new BoundingSphere(Cartesian3.UNIT_X, 0.5); var normal = Cartesian3.UNIT_X; var position = Cartesian3.UNIT_X; var plane = new Plane(normal, -Cartesian3.dot(normal, position)); expect(sphere.intersectPlane(plane)).toEqual(Intersect.INTERSECTING); }); it("expands to contain another sphere", function () { var bs1 = new BoundingSphere( Cartesian3.negate(Cartesian3.UNIT_X, new Cartesian3()), 1.0 ); var bs2 = new BoundingSphere(Cartesian3.UNIT_X, 1.0); var expected = new BoundingSphere(Cartesian3.ZERO, 2.0); expect(BoundingSphere.union(bs1, bs2)).toEqual(expected); }); it("union left sphere encloses right", function () { var bs1 = new BoundingSphere(Cartesian3.ZERO, 3.0); var bs2 = new BoundingSphere(Cartesian3.UNIT_X, 1.0); var union = BoundingSphere.union(bs1, bs2); expect(union).toEqual(bs1); }); it("union of co-located spheres, right sphere encloses left", function () { var bs1 = new BoundingSphere(Cartesian3.UNIT_X, 1.0); var bs2 = new BoundingSphere(Cartesian3.UNIT_X, 2.0); var union = BoundingSphere.union(bs1, bs2); expect(union).toEqual(bs2); }); it("union result parameter is a tight fit", function () { var bs1 = new BoundingSphere( Cartesian3.multiplyByScalar( Cartesian3.negate(Cartesian3.UNIT_X, new Cartesian3()), 3.0, new Cartesian3() ), 3.0 ); var bs2 = new BoundingSphere(Cartesian3.UNIT_X, 1.0); var expected = new BoundingSphere( Cartesian3.multiplyByScalar( Cartesian3.negate(Cartesian3.UNIT_X, new Cartesian3()), 2.0, new Cartesian3() ), 4.0 ); BoundingSphere.union(bs1, bs2, bs1); expect(bs1).toEqual(expected); }); it("expands to contain another point", function () { var bs = new BoundingSphere( Cartesian3.negate(Cartesian3.UNIT_X, new Cartesian3()), 1.0 ); var point = Cartesian3.UNIT_X; var expected = new BoundingSphere( Cartesian3.negate(Cartesian3.UNIT_X, new Cartesian3()), 2.0 ); expect(BoundingSphere.expand(bs, point)).toEqual(expected); }); it("applies transform", function () { var bs = new BoundingSphere(Cartesian3.ZERO, 1.0); var transform = Matrix4.fromTranslation(new Cartesian3(1.0, 2.0, 3.0)); var expected = new BoundingSphere(new Cartesian3(1.0, 2.0, 3.0), 1.0); expect(BoundingSphere.transform(bs, transform)).toEqual(expected); }); it("applies scale transform", function () { var bs = new BoundingSphere(Cartesian3.ZERO, 1.0); var transform = Matrix4.fromScale(new Cartesian3(1.0, 2.0, 3.0)); var expected = new BoundingSphere(Cartesian3.ZERO, 3.0); expect(BoundingSphere.transform(bs, transform)).toEqual(expected); }); it("applies transform without scale", function () { var bs = new BoundingSphere(Cartesian3.ZERO, 1.0); var transform = Matrix4.fromTranslation(new Cartesian3(1.0, 2.0, 3.0)); var expected = new BoundingSphere(new Cartesian3(1.0, 2.0, 3.0), 1.0); expect(BoundingSphere.transformWithoutScale(bs, transform)).toEqual( expected ); }); it("transformWithoutScale ignores scale", function () { var bs = new BoundingSphere(Cartesian3.ZERO, 1.0); var transform = Matrix4.fromScale(new Cartesian3(1.0, 2.0, 3.0)); var expected = new BoundingSphere(Cartesian3.ZERO, 1.0); expect(BoundingSphere.transformWithoutScale(bs, transform)).toEqual( expected ); }); it("finds distances", function () { var bs = new BoundingSphere(Cartesian3.ZERO, 1.0); var position = new Cartesian3(-2.0, 1.0, 0.0); var direction = Cartesian3.UNIT_X; var expected = new Interval(1.0, 3.0); expect( BoundingSphere.computePlaneDistances(bs, position, direction) ).toEqual(expected); }); it("distance squared to point outside of sphere", function () { var bs = new BoundingSphere(Cartesian3.ZERO, 1.0); var position = new Cartesian3(-2.0, 1.0, 0.0); var expected = 1.52786405; expect(BoundingSphere.distanceSquaredTo(bs, position)).toEqualEpsilon( expected, CesiumMath.EPSILON6 ); }); it("distance squared to point inside sphere", function () { var bs = new BoundingSphere(Cartesian3.ZERO, 1.0); var position = new Cartesian3(-0.5, 0.5, 0.0); expect(BoundingSphere.distanceSquaredTo(bs, position)).toEqual(0.0); }); it("projectTo2D", function () { var positions = getPositions(); var projection = new GeographicProjection(); var positions2D = []; for (var i = 0; i < positions.length; ++i) { var position = positions[i]; var cartographic = projection.ellipsoid.cartesianToCartographic(position); positions2D.push(projection.project(cartographic)); } var boundingSphere3D = BoundingSphere.fromPoints(positions); var boundingSphere2D = BoundingSphere.projectTo2D( boundingSphere3D, projection ); var actualSphere = BoundingSphere.fromPoints(positions2D); actualSphere.center = new Cartesian3( actualSphere.center.z, actualSphere.center.x, actualSphere.center.y ); expect(boundingSphere2D.center).toEqualEpsilon( actualSphere.center, CesiumMath.EPSILON6 ); expect(boundingSphere2D.radius).toBeGreaterThan(actualSphere.radius); }); it("projectTo2D with result parameter", function () { var positions = getPositions(); var projection = new GeographicProjection(); var sphere = new BoundingSphere(); var positions2D = []; for (var i = 0; i < positions.length; ++i) { var position = positions[i]; var cartographic = projection.ellipsoid.cartesianToCartographic(position); positions2D.push(projection.project(cartographic)); } var boundingSphere3D = BoundingSphere.fromPoints(positions); var boundingSphere2D = BoundingSphere.projectTo2D( boundingSphere3D, projection, sphere ); var actualSphere = BoundingSphere.fromPoints(positions2D); actualSphere.center = new Cartesian3( actualSphere.center.z, actualSphere.center.x, actualSphere.center.y ); expect(boundingSphere2D).toBe(sphere); expect(boundingSphere2D.center).toEqualEpsilon( actualSphere.center, CesiumMath.EPSILON6 ); expect(boundingSphere2D.radius).toBeGreaterThan(actualSphere.radius); }); it("can pack and unpack", function () { var array = []; var boundingSphere = new BoundingSphere(); boundingSphere.center = new Cartesian3(1, 2, 3); boundingSphere.radius = 4; BoundingSphere.pack(boundingSphere, array); expect(array.length).toEqual(BoundingSphere.packedLength); expect(BoundingSphere.unpack(array)).toEqual(boundingSphere); }); it("can pack and unpack with offset", function () { var packed = new Array(3); var offset = 3; var boundingSphere = new BoundingSphere(); boundingSphere.center = new Cartesian3(1, 2, 3); boundingSphere.radius = 4; BoundingSphere.pack(boundingSphere, packed, offset); expect(packed.length).toEqual(offset + BoundingSphere.packedLength); var result = new BoundingSphere(); var returnedResult = BoundingSphere.unpack(packed, offset, result); expect(returnedResult).toBe(result); expect(result).toEqual(boundingSphere); }); it("pack throws with undefined boundingSphere", function () { var array = []; expect(function () { BoundingSphere.pack(undefined, array); }).toThrowDeveloperError(); }); it("pack throws with undefined array", function () { var boundingSphere = new BoundingSphere(); expect(function () { BoundingSphere.pack(boundingSphere, undefined); }).toThrowDeveloperError(); }); it("unpack throws with undefined array", function () { expect(function () { BoundingSphere.unpack(undefined); }).toThrowDeveloperError(); }); it("static projectTo2D throws without sphere", function () { expect(function () { BoundingSphere.projectTo2D(); }).toThrowDeveloperError(); }); it("clone returns undefined with no parameter", function () { expect(BoundingSphere.clone()).toBeUndefined(); }); it("union throws with no left parameter", function () { var right = new BoundingSphere(); expect(function () { BoundingSphere.union(undefined, right); }).toThrowDeveloperError(); }); it("union throws with no right parameter", function () { var left = new BoundingSphere(); expect(function () { BoundingSphere.union(left, undefined); }).toThrowDeveloperError(); }); it("expand throws without a sphere", function () { var plane = new Cartesian3(); expect(function () { BoundingSphere.expand(undefined, plane); }).toThrowDeveloperError(); }); it("expand throws without a point", function () { var sphere = new BoundingSphere(); expect(function () { BoundingSphere.expand(sphere, undefined); }).toThrowDeveloperError(); }); it("intersectPlane throws without a sphere", function () { var plane = new Plane(Cartesian3.UNIT_X, 0.0); expect(function () { BoundingSphere.intersectPlane(undefined, plane); }).toThrowDeveloperError(); }); it("intersectPlane throws without a plane", function () { var sphere = new BoundingSphere(); expect(function () { BoundingSphere.intersectPlane(sphere, undefined); }).toThrowDeveloperError(); }); it("transform throws without a sphere", function () { expect(function () { BoundingSphere.transform(); }).toThrowDeveloperError(); }); it("transform throws without a transform", function () { var sphere = new BoundingSphere(); expect(function () { BoundingSphere.transform(sphere); }).toThrowDeveloperError(); }); it("distanceSquaredTo throws without a sphere", function () { expect(function () { BoundingSphere.distanceSquaredTo(); }).toThrowDeveloperError(); }); it("distanceSquaredTo throws without a cartesian", function () { expect(function () { BoundingSphere.distanceSquaredTo(new BoundingSphere()); }).toThrowDeveloperError(); }); it("transformWithoutScale throws without a sphere", function () { expect(function () { BoundingSphere.transformWithoutScale(); }).toThrowDeveloperError(); }); it("transformWithoutScale throws without a transform", function () { var sphere = new BoundingSphere(); expect(function () { BoundingSphere.transformWithoutScale(sphere); }).toThrowDeveloperError(); }); it("computePlaneDistances throws without a sphere", function () { expect(function () { BoundingSphere.computePlaneDistances(); }).toThrowDeveloperError(); }); it("computePlaneDistances throws without a position", function () { expect(function () { BoundingSphere.computePlaneDistances(new BoundingSphere()); }).toThrowDeveloperError(); }); it("computePlaneDistances throws without a direction", function () { expect(function () { BoundingSphere.computePlaneDistances( new BoundingSphere(), new Cartesian3() ); }).toThrowDeveloperError(); }); it("isOccluded throws without a sphere", function () { expect(function () { BoundingSphere.isOccluded(); }).toThrowDeveloperError(); }); it("isOccluded throws without an occluder", function () { expect(function () { BoundingSphere.isOccluded(new BoundingSphere()); }).toThrowDeveloperError(); }); function expectBoundingSphereToContainPoint( boundingSphere, point, projection ) { var pointInCartesian = projection.project(point); var distanceFromCenter = Cartesian3.magnitude( Cartesian3.subtract( pointInCartesian, boundingSphere.center, new Cartesian3() ) ); // The distanceFromCenter for corner points at the height extreme should equal the // bounding sphere's radius. But due to rounding errors it can end up being // very slightly greater. Pull in the distanceFromCenter slightly to // account for this possibility. distanceFromCenter -= CesiumMath.EPSILON9; expect(distanceFromCenter).toBeLessThanOrEqualTo(boundingSphere.radius); } it("fromRectangleWithHeights2D includes specified min and max heights", function () { var rectangle = new Rectangle(0.1, 0.5, 0.2, 0.6); var projection = new GeographicProjection(); var minHeight = -327.0; var maxHeight = 2456.0; var boundingSphere = BoundingSphere.fromRectangleWithHeights2D( rectangle, projection, minHeight, maxHeight ); // Test that the corners are inside the bounding sphere. var point = Rectangle.southwest(rectangle).clone(); point.height = minHeight; expectBoundingSphereToContainPoint(boundingSphere, point, projection); point = Rectangle.southwest(rectangle).clone(); point.height = maxHeight; expectBoundingSphereToContainPoint(boundingSphere, point, projection); point = Rectangle.northeast(rectangle).clone(); point.height = minHeight; expectBoundingSphereToContainPoint(boundingSphere, point, projection); point = Rectangle.northeast(rectangle).clone(); point.height = maxHeight; expectBoundingSphereToContainPoint(boundingSphere, point, projection); point = Rectangle.southeast(rectangle).clone(); point.height = minHeight; expectBoundingSphereToContainPoint(boundingSphere, point, projection); point = Rectangle.southeast(rectangle).clone(); point.height = maxHeight; expectBoundingSphereToContainPoint(boundingSphere, point, projection); point = Rectangle.northwest(rectangle).clone(); point.height = minHeight; expectBoundingSphereToContainPoint(boundingSphere, point, projection); point = Rectangle.northwest(rectangle).clone(); point.height = maxHeight; expectBoundingSphereToContainPoint(boundingSphere, point, projection); // Test that the center is inside the bounding sphere point = Rectangle.center(rectangle).clone(); point.height = minHeight; expectBoundingSphereToContainPoint(boundingSphere, point, projection); point = Rectangle.center(rectangle).clone(); point.height = maxHeight; expectBoundingSphereToContainPoint(boundingSphere, point, projection); // Test that the edge midpoints are inside the bounding sphere. point = new Cartographic( Rectangle.center(rectangle).longitude, rectangle.south, minHeight ); expectBoundingSphereToContainPoint(boundingSphere, point, projection); point = new Cartographic( Rectangle.center(rectangle).longitude, rectangle.south, maxHeight ); expectBoundingSphereToContainPoint(boundingSphere, point, projection); point = new Cartographic( Rectangle.center(rectangle).longitude, rectangle.north, minHeight ); expectBoundingSphereToContainPoint(boundingSphere, point, projection); point = new Cartographic( Rectangle.center(rectangle).longitude, rectangle.north, maxHeight ); expectBoundingSphereToContainPoint(boundingSphere, point, projection); point = new Cartographic( rectangle.west, Rectangle.center(rectangle).latitude, minHeight ); expectBoundingSphereToContainPoint(boundingSphere, point, projection); point = new Cartographic( rectangle.west, Rectangle.center(rectangle).latitude, maxHeight ); expectBoundingSphereToContainPoint(boundingSphere, point, projection); point = new Cartographic( rectangle.east, Rectangle.center(rectangle).latitude, minHeight ); expectBoundingSphereToContainPoint(boundingSphere, point, projection); point = new Cartographic( rectangle.east, Rectangle.center(rectangle).latitude, maxHeight ); expectBoundingSphereToContainPoint(boundingSphere, point, projection); }); it("computes the volume of a BoundingSphere", function () { var sphere = new BoundingSphere(new Cartesian3(), 1.0); var computedVolume = sphere.volume(); var expectedVolume = (4.0 / 3.0) * CesiumMath.PI; expect(computedVolume).toEqualEpsilon(expectedVolume, CesiumMath.EPSILON6); }); createPackableSpecs( BoundingSphere, new BoundingSphere(new Cartesian3(1.0, 2.0, 3.0), 4.0), [1.0, 2.0, 3.0, 4.0] ); });