text: /*global defineSuite*/
  defineSuite([
          'Core/OrientedBoundingBox',
          'Core/BoundingRectangle',
          'Core/BoundingSphere',
          'Core/Cartesian3',
          'Core/Cartesian4',
          'Core/Ellipsoid',
          'Core/EllipsoidTangentPlane',
          'Core/Intersect',
          'Core/Math',
          'Core/Matrix3',
          'Core/Occluder',
          'Core/Plane',
          'Core/Quaternion',
          'Core/Rectangle'
      ], function(
          OrientedBoundingBox,
          BoundingRectangle,
          BoundingSphere,
          Cartesian3,
          Cartesian4,
          Ellipsoid,
          EllipsoidTangentPlane,
          Intersect,
          CesiumMath,
          Matrix3,
          Occluder,
          Plane,
          Quaternion,
          Rectangle) {
      "use strict";
      /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn*/
  
      var positions = [
          new Cartesian3(2.0, 0.0, 0.0),
          new Cartesian3(0.0, 3.0, 0.0),
          new Cartesian3(0.0, 0.0, 4.0),
          new Cartesian3(-2.0, 0.0, 0.0),
          new Cartesian3(0.0, -3.0, 0.0),
          new Cartesian3(0.0, 0.0, -4.0)
      ];
  
      var positions2 = [
          new Cartesian3(4.0, 0.0, 0.0),
          new Cartesian3(0.0, 3.0, 0.0),
          new Cartesian3(0.0, 0.0, 2.0),
          new Cartesian3(-4.0, 0.0, 0.0),
          new Cartesian3(0.0, -3.0, 0.0),
          new Cartesian3(0.0, 0.0, -2.0)
      ];
  
      function rotatePositions(positions, axis, angle) {
          var points = [];
  
          var quaternion = Quaternion.fromAxisAngle(axis, angle);
          var rotation = Matrix3.fromQuaternion(quaternion);
  
          for (var i = 0; i < positions.length; ++i) {
              points.push(Matrix3.multiplyByVector(rotation, positions[i], new Cartesian3()));
          }
  
          return {
              points : points,
              rotation : rotation
          };
      }
  
      function translatePositions(positions, translation) {
          var points = [];
          for (var i = 0; i < positions.length; ++i) {
              points.push(Cartesian3.add(translation, positions[i], new Cartesian3()));
          }
  
          return points;
      }
  
      it('constructor sets expected default values', function() {
          var box = new OrientedBoundingBox();
          expect(box.center).toEqual(Cartesian3.ZERO);
          expect(box.halfAxes).toEqual(Matrix3.ZERO);
      });
  
      it('fromPoints constructs empty box with undefined positions', function() {
          var box = OrientedBoundingBox.fromPoints(undefined);
          expect(box.halfAxes).toEqual(Matrix3.ZERO);
          expect(box.center).toEqual(Cartesian3.ZERO);
      });
  
      it('fromPoints constructs empty box with empty positions', function() {
          var box = OrientedBoundingBox.fromPoints([]);
          expect(box.halfAxes).toEqual(Matrix3.ZERO);
          expect(box.center).toEqual(Cartesian3.ZERO);
      });
  
      it('fromPoints correct scale', function() {
          var box = OrientedBoundingBox.fromPoints(positions);
          expect(box.halfAxes).toEqual(Matrix3.fromScale(new Cartesian3(2.0, 3.0, 4.0)));
          expect(box.center).toEqual(Cartesian3.ZERO);
      });
  
      it('fromPoints correct translation', function() {
          var translation = new Cartesian3(10.0, -20.0, 30.0);
          var points = translatePositions(positions, translation);
          var box = OrientedBoundingBox.fromPoints(points);
          expect(box.halfAxes).toEqual(Matrix3.fromScale(new Cartesian3(2.0, 3.0, 4.0)));
          expect(box.center).toEqual(translation);
      });
  
      it('fromPoints rotation about z', function() {
          var result = rotatePositions(positions, Cartesian3.UNIT_Z, CesiumMath.PI_OVER_FOUR);
          var points = result.points;
          var rotation = result.rotation;
  
          var box = OrientedBoundingBox.fromPoints(points);
          expect(box.halfAxes).toEqualEpsilon(Matrix3.multiplyByScale(rotation, new Cartesian3(3.0, 2.0, 4.0), new Matrix3()), CesiumMath.EPSILON15);
          expect(box.center).toEqualEpsilon(Cartesian3.ZERO, CesiumMath.EPSILON15);
      });
  
      it('fromPoints rotation about y', function() {
          var result = rotatePositions(positions, Cartesian3.UNIT_Y, CesiumMath.PI_OVER_FOUR);
          var points = result.points;
          var rotation = result.rotation;
  
          var box = OrientedBoundingBox.fromPoints(points);
          expect(box.halfAxes).toEqualEpsilon(Matrix3.multiplyByScale(rotation, new Cartesian3(4.0, 3.0, 2.0), new Matrix3()), CesiumMath.EPSILON15);
          expect(box.center).toEqualEpsilon(Cartesian3.ZERO, CesiumMath.EPSILON15);
      });
  
      it('fromPoints rotation about x', function() {
          var result = rotatePositions(positions, Cartesian3.UNIT_X, CesiumMath.PI_OVER_FOUR);
          var points = result.points;
          var rotation = result.rotation;
  
          var box = OrientedBoundingBox.fromPoints(points);
          expect(box.halfAxes).toEqualEpsilon(Matrix3.multiplyByScale(rotation, new Cartesian3(2.0, 4.0, 3.0), new Matrix3()), CesiumMath.EPSILON15);
          expect(box.center).toEqualEpsilon(Cartesian3.ZERO, CesiumMath.EPSILON15);
      });
  
      it('fromPoints rotation and translation', function() {
          var result = rotatePositions(positions, Cartesian3.UNIT_Z, CesiumMath.PI_OVER_FOUR);
          var points = result.points;
          var rotation = result.rotation;
  
          var translation = new Cartesian3(-40.0, 20.0, -30.0);
          points = translatePositions(points, translation);
  
          var box = OrientedBoundingBox.fromPoints(points);
          expect(box.halfAxes).toEqualEpsilon(Matrix3.multiplyByScale(rotation, new Cartesian3(3.0, 2.0, 4.0), new Matrix3()), CesiumMath.EPSILON14);
          expect(box.center).toEqualEpsilon(translation, CesiumMath.EPSILON15);
      });
  
      it('fromRectangle sets correct default ellipsoid', function() {
          var rectangle = new Rectangle(-0.9, -1.2, 0.5, 0.7);
          var box1 = OrientedBoundingBox.fromRectangle(rectangle, 0.0, 0.0);
          var box2 = OrientedBoundingBox.fromRectangle(rectangle, 0.0, 0.0, Ellipsoid.WGS84);
  
          expect(box1.center).toEqualEpsilon(box2.center, CesiumMath.EPSILON15);
  
          var rotScale = Matrix3.ZERO;
          expect(box1.halfAxes).toEqualEpsilon(box2.halfAxes, CesiumMath.EPSILON15);
      });
  
      it('fromRectangle sets correct default heights', function() {
          var rectangle = new Rectangle(0.0, 0.0, 0.0, 0.0);
          var box = OrientedBoundingBox.fromRectangle(rectangle, undefined, undefined, Ellipsoid.UNIT_SPHERE);
  
          expect(box.center).toEqualEpsilon(new Cartesian3(1.0, 0.0, 0.0), CesiumMath.EPSILON15);
  
          var rotScale = Matrix3.ZERO;
          expect(box.halfAxes).toEqualEpsilon(rotScale, CesiumMath.EPSILON15);
      });
  
      it('fromRectangle throws without rectangle', function() {
          var ellipsoid = Ellipsoid.UNIT_SPHERE;
          expect(function() {
              OrientedBoundingBox.fromRectangle(undefined, 0.0, 0.0, ellipsoid);
          }).toThrowDeveloperError();
      });
  
      it('fromRectangle throws with invalid rectangles', function() {
          var ellipsoid = Ellipsoid.UNIT_SPHERE;
          expect(function() { return OrientedBoundingBox.fromRectangle(new Rectangle(1.0, -1.0, -1.0, 1.0), 0.0, 0.0, ellipsoid); }).toThrowDeveloperError();
          expect(function() { return OrientedBoundingBox.fromRectangle(new Rectangle(-1.0, 1.0, 1.0, -1.0), 0.0, 0.0, ellipsoid); }).toThrowDeveloperError();
          expect(function() { return OrientedBoundingBox.fromRectangle(new Rectangle(-1.0, 1.0, -2.0, 2.0), 0.0, 0.0, ellipsoid); }).toThrowDeveloperError();
          expect(function() { return OrientedBoundingBox.fromRectangle(new Rectangle(-2.0, 2.0, -1.0, 1.0), 0.0, 0.0, ellipsoid); }).toThrowDeveloperError();
          expect(function() { return OrientedBoundingBox.fromRectangle(new Rectangle(-2.0, -2.0, 2.0, 1.0), 0.0, 0.0, ellipsoid); }).toThrowDeveloperError();
          expect(function() { return OrientedBoundingBox.fromRectangle(new Rectangle(-2.0, -2.0, 1.0, 2.0), 0.0, 0.0, ellipsoid); }).toThrowDeveloperError();
          expect(function() { return OrientedBoundingBox.fromRectangle(new Rectangle(-1.0, -2.0, 2.0, 2.0), 0.0, 0.0, ellipsoid); }).toThrowDeveloperError();
          expect(function() { return OrientedBoundingBox.fromRectangle(new Rectangle(-2.0, -1.0, 2.0, 2.0), 0.0, 0.0, ellipsoid); }).toThrowDeveloperError();
      });
  
      it('fromRectangle throws with non-revolution ellipsoids', function() {
          var rectangle = new Rectangle(0.0, 0.0, 0.0, 0.0);
          expect(function() { return OrientedBoundingBox.fromRectangle(rectangle, 0.0, 0.0, new Ellipsoid(1.01, 1.00, 1.01)); }).toThrowDeveloperError();
          expect(function() { return OrientedBoundingBox.fromRectangle(rectangle, 0.0, 0.0, new Ellipsoid(1.00, 1.01, 1.01)); }).toThrowDeveloperError();
      });
  
      it('fromRectangle creates an OrientedBoundingBox without a result parameter', function() {
          var ellipsoid = Ellipsoid.UNIT_SPHERE;
          var rectangle = new Rectangle(0.0, 0.0, 0.0, 0.0);
          var box = OrientedBoundingBox.fromRectangle(rectangle, 0.0, 0.0, ellipsoid);
  
          expect(box.center).toEqualEpsilon(new Cartesian3(1.0, 0.0, 0.0), CesiumMath.EPSILON15);
  
          var rotScale = Matrix3.ZERO;
          expect(box.halfAxes).toEqualEpsilon(rotScale, CesiumMath.EPSILON15);
      });
  
      it('fromRectangle creates an OrientedBoundingBox with a result parameter', function() {
          var ellipsoid = Ellipsoid.UNIT_SPHERE;
          var rectangle = new Rectangle(0.0, 0.0, 0.0, 0.0);
          var result = new OrientedBoundingBox();
          var box = OrientedBoundingBox.fromRectangle(rectangle, 0.0, 0.0, ellipsoid, result);
          expect(box).toBe(result);
  
          expect(box.center).toEqualEpsilon(new Cartesian3(1.0, 0.0, 0.0), CesiumMath.EPSILON15);
  
          var rotScale = Matrix3.ZERO;
          expect(box.halfAxes).toEqualEpsilon(rotScale, CesiumMath.EPSILON15);
      });
  
      it('fromRectangle for rectangles with heights', function() {
          var d90 = CesiumMath.PI_OVER_TWO;
  
          var box;
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(0.0, 0.0, 0.0, 0.0), 1.0, 1.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(2.0, 0.0, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(Matrix3.ZERO, CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(0.0, 0.0, 0.0, 0.0), -1.0, -1.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(0.0, 0.0, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(Matrix3.ZERO, CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(0.0, 0.0, 0.0, 0.0), -1.0, 1.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(1.0, 0.0, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(new Matrix3(0, 0, 1, 0, 0, 0, 0, 0, 0), CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(-d90, -d90, d90, d90), 0.0, 1.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(1.0, 0.0, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(new Matrix3(0, 0, 1, 2, 0, 0, 0, 2, 0), CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(-d90, -d90, d90, d90), -1.0, -1.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(0.0, 0.0, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(Matrix3.ZERO, CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(-d90, -d90, d90, d90), -1.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(0.5, 0.0, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(new Matrix3(0, 0, 0.5, 1, 0, 0, 0, 1, 0), CesiumMath.EPSILON15);
      });
  
      it('fromRectangle for interesting, degenerate, and edge-case rectangles', function() {
          var d45 = CesiumMath.PI_OVER_FOUR;
          var d30 = CesiumMath.PI_OVER_SIX;
          var d90 = CesiumMath.PI_OVER_TWO;
          var d135 = 3 * CesiumMath.PI_OVER_FOUR;
          var d180 = CesiumMath.PI;
          var sqrt3 = Math.sqrt(3.0);
  
          var box;
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(0.0, 0.0, 0.0, 0.0), 0.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(1.0, 0.0, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(Matrix3.ZERO, CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(d180, 0.0, -d180, 0.0), 0.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(-1.0, 0.0, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(Matrix3.ZERO, CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(d180, 0.0, d180, 0.0), 0.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(-1.0, 0.0, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(Matrix3.ZERO, CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(0.0, d90, 0.0, d90), 0.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(0.0, 0.0, 1.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(Matrix3.ZERO, CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(0.0, 0.0, d180, 0.0), 0.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(0.0, 0.5, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(new Matrix3(-1.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0), CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(-d90, -d90, d90, d90), 0.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(0.5, 0.0, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(new Matrix3(0.0, 0.0, 0.5, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0), CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(-d90, -d30, d90, d90), 0.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(0.1875 * sqrt3, 0.0, 0.1875), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(new Matrix3(0, -sqrt3/4, 5*sqrt3/16, 1, 0, 0, 0, 3/4, 5/16), CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(-d90, -d90, d90, d30), 0.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(0.1875 * sqrt3, 0.0, -0.1875), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(new Matrix3(0, sqrt3/4, 5*sqrt3/16, 1, 0, 0, 0, 3/4, -5/16), CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(0.0, -d30, d180, d90), 0.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(0.0, 0.1875 * sqrt3, 0.1875), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(new Matrix3(-1, 0, 0, 0, -sqrt3/4, 5*sqrt3/16, 0, 3/4, 5/16), CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(0.0, -d90, d180, d30), 0.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(0.0, 0.1875 * sqrt3, -0.1875), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(new Matrix3(-1, 0, 0, 0, sqrt3/4, 5*sqrt3/16, 0, 3/4, -5/16), CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(-d45, 0.0, d45, 0.0), 0.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3((1.0 + Math.SQRT1_2) / 2.0, 0.0, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(new Matrix3(0.0, 0.0, 0.5 * (1.0 - Math.SQRT1_2), Math.SQRT1_2, 0.0, 0.0, 0.0, 0.0, 0.0), CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(d135, 0.0, -d135, 0.0), 0.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(-(1.0 + Math.SQRT1_2) / 2.0, 0.0, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(new Matrix3(0.0, 0.0, -0.5 * (1.0 - Math.SQRT1_2), -Math.SQRT1_2, 0.0, 0.0, 0.0, 0.0, 0.0), CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(0.0, -d45, 0.0, d45), 0.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3((1.0 + Math.SQRT1_2) / 2.0, 0.0, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(new Matrix3(0.0, 0.0, 0.5 * (1.0 - Math.SQRT1_2), 0.0, 0.0, 0.0, 0.0, Math.SQRT1_2, 0.0), CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(-d90, 0.0, d90, 0.0), 0.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(0.5, 0.0, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(new Matrix3(0.0, 0.0, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0), CesiumMath.EPSILON15);
  
          box = OrientedBoundingBox.fromRectangle(new Rectangle(0.0, -d90, 0.0, d90), 0.0, 0.0, Ellipsoid.UNIT_SPHERE);
          expect(box.center).toEqualEpsilon(new Cartesian3(0.5, 0.0, 0.0), CesiumMath.EPSILON15);
          expect(box.halfAxes).toEqualEpsilon(new Matrix3(0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0), CesiumMath.EPSILON15);
      });
  
      var intersectPlaneTestCornersEdgesFaces = function(center, axes) {
          var SQRT1_2 = Math.pow(1.0 / 2.0, 1 / 2.0);
          var SQRT3_4 = Math.pow(3.0 / 4.0, 1 / 2.0);
  
          var box = new OrientedBoundingBox(center, Matrix3.multiplyByScalar(axes, 0.5, new Matrix3()));
  
          var planeNormXform = function(nx, ny, nz, dist) {
              var n = new Cartesian3(nx, ny, nz);
              var arb = new Cartesian3(357, 924, 258);
              var p0 = Cartesian3.normalize(n, new Cartesian3());
              Cartesian3.multiplyByScalar(p0, -dist, p0);
              var tang = Cartesian3.cross(n, arb, new Cartesian3());
              Cartesian3.normalize(tang, tang);
              var binorm = Cartesian3.cross(n, tang, new Cartesian3());
              Cartesian3.normalize(binorm, binorm);
  
              Matrix3.multiplyByVector(axes, p0, p0);
              Matrix3.multiplyByVector(axes, tang, tang);
              Matrix3.multiplyByVector(axes, binorm, binorm);
              Cartesian3.cross(tang, binorm, n);
              Cartesian3.normalize(n, n);
  
              Cartesian3.add(p0, center, p0);
              var d = -Cartesian3.dot(p0, n);
              if (Math.abs(d) > 0.0001 && Cartesian3.magnitudeSquared(n) > 0.0001) {
                  return new Plane(n, d);
              } else {
                  return undefined;
              }
          };
  
          var pl;
  
          // Tests against faces
  
          pl = planeNormXform(+1.0, +0.0, +0.0,  0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(-1.0, +0.0, +0.0,  0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(+0.0, +1.0, +0.0,  0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(+0.0, -1.0, +0.0,  0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(+0.0, +0.0, +1.0,  0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(+0.0, +0.0, -1.0,  0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
  
          pl = planeNormXform(+1.0, +0.0, +0.0,  0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, +0.0, +0.0,  0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, +1.0, +0.0,  0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, -1.0, +0.0,  0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, +0.0, +1.0,  0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, +0.0, -1.0,  0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
  
          pl = planeNormXform(+1.0, +0.0, +0.0, -0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, +0.0, +0.0, -0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, +1.0, +0.0, -0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, -1.0, +0.0, -0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, +0.0, +1.0, -0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, +0.0, -1.0, -0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
  
          pl = planeNormXform(+1.0, +0.0, +0.0, -0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(-1.0, +0.0, +0.0, -0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(+0.0, +1.0, +0.0, -0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(+0.0, -1.0, +0.0, -0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(+0.0, +0.0, +1.0, -0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(+0.0, +0.0, -1.0, -0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
  
          // Tests against edges
  
          pl = planeNormXform(+1.0, +1.0, +0.0,  SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(+1.0, -1.0, +0.0,  SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(-1.0, +1.0, +0.0,  SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(-1.0, -1.0, +0.0,  SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(+1.0, +0.0, +1.0,  SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(+1.0, +0.0, -1.0,  SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(-1.0, +0.0, +1.0,  SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(-1.0, +0.0, -1.0,  SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(+0.0, +1.0, +1.0,  SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(+0.0, +1.0, -1.0,  SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(+0.0, -1.0, +1.0,  SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(+0.0, -1.0, -1.0,  SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
  
          pl = planeNormXform(+1.0, +1.0, +0.0,  SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+1.0, -1.0, +0.0,  SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, +1.0, +0.0,  SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, -1.0, +0.0,  SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+1.0, +0.0, +1.0,  SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+1.0, +0.0, -1.0,  SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, +0.0, +1.0,  SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, +0.0, -1.0,  SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, +1.0, +1.0,  SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, +1.0, -1.0,  SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, -1.0, +1.0,  SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, -1.0, -1.0,  SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
  
          pl = planeNormXform(+1.0, +1.0, +0.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+1.0, -1.0, +0.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, +1.0, +0.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, -1.0, +0.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+1.0, +0.0, +1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+1.0, +0.0, -1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, +0.0, +1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, +0.0, -1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, +1.0, +1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, +1.0, -1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, -1.0, +1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+0.0, -1.0, -1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
  
          pl = planeNormXform(+1.0, +1.0, +0.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(+1.0, -1.0, +0.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(-1.0, +1.0, +0.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(-1.0, -1.0, +0.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(+1.0, +0.0, +1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(+1.0, +0.0, -1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(-1.0, +0.0, +1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(-1.0, +0.0, -1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(+0.0, +1.0, +1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(+0.0, +1.0, -1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(+0.0, -1.0, +1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(+0.0, -1.0, -1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
  
          // Tests against corners
  
          pl = planeNormXform(+1.0, +1.0, +1.0,  SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(+1.0, +1.0, -1.0,  SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(+1.0, -1.0, +1.0,  SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(+1.0, -1.0, -1.0,  SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(-1.0, +1.0, +1.0,  SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(-1.0, +1.0, -1.0,  SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(-1.0, -1.0, +1.0,  SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
          pl = planeNormXform(-1.0, -1.0, -1.0,  SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); }
  
          pl = planeNormXform(+1.0, +1.0, +1.0,  SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+1.0, +1.0, -1.0,  SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+1.0, -1.0, +1.0,  SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+1.0, -1.0, -1.0,  SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, +1.0, +1.0,  SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, +1.0, -1.0,  SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, -1.0, +1.0,  SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, -1.0, -1.0,  SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
  
          pl = planeNormXform(+1.0, +1.0, +1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+1.0, +1.0, -1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+1.0, -1.0, +1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(+1.0, -1.0, -1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, +1.0, +1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, +1.0, -1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, -1.0, +1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
          pl = planeNormXform(-1.0, -1.0, -1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); }
  
          pl = planeNormXform(+1.0, +1.0, +1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(+1.0, +1.0, -1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(+1.0, -1.0, +1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(+1.0, -1.0, -1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(-1.0, +1.0, +1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(-1.0, +1.0, -1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(-1.0, -1.0, +1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
          pl = planeNormXform(-1.0, -1.0, -1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); }
  
      };
  
      it('intersectPlane works with untransformed box', function() {
          intersectPlaneTestCornersEdgesFaces(Cartesian3.ZERO, Matrix3.IDENTITY);
      });
  
      it('intersectPlane works with off-center box', function() {
          intersectPlaneTestCornersEdgesFaces(new Cartesian3(1.0, 0.0, 0.0), Matrix3.IDENTITY);
          intersectPlaneTestCornersEdgesFaces(new Cartesian3(0.7, -1.8, 12.0), Matrix3.IDENTITY);
      });
  
      it('intersectPlane works with rotated box', function() {
          intersectPlaneTestCornersEdgesFaces(Cartesian3.ZERO,
                  Matrix3.fromQuaternion(Quaternion.fromAxisAngle(new Cartesian3(0.5, 1.5, -1.2), 1.2), new Matrix3()));
      });
  
      it('intersectPlane works with scaled box', function() {
          var m = new Matrix3();
          intersectPlaneTestCornersEdgesFaces(Cartesian3.ZERO, Matrix3.fromScale(new Cartesian3(1.5, 0.4, 20.6), m));
          intersectPlaneTestCornersEdgesFaces(Cartesian3.ZERO, Matrix3.fromScale(new Cartesian3(0.0, 0.4, 20.6), m));
          intersectPlaneTestCornersEdgesFaces(Cartesian3.ZERO, Matrix3.fromScale(new Cartesian3(1.5, 0.0, 20.6), m));
          intersectPlaneTestCornersEdgesFaces(Cartesian3.ZERO, Matrix3.fromScale(new Cartesian3(1.5, 0.4, 0.0), m));
          intersectPlaneTestCornersEdgesFaces(Cartesian3.ZERO, Matrix3.fromScale(new Cartesian3(0.0, 0.0, 0.0), m));
      });
  
      it('intersectPlane works with this arbitrary box', function() {
          var m = Matrix3.fromScale(new Cartesian3(1.5, 80.4, 2.6), new Matrix3());
          var n = Matrix3.fromQuaternion(Quaternion.fromAxisAngle(new Cartesian3(0.5, 1.5, -1.2), 1.2), new Matrix3());
          Matrix3.multiply(m, n, n);
          intersectPlaneTestCornersEdgesFaces(new Cartesian3(-5.1, 0.0, 0.1), n);
      });
  
      it('intersectPlane fails without box parameter', function() {
          var plane = new Cartesian4(1.0, 0.0, 0.0, 0.0);
          expect(function() {
              OrientedBoundingBox.intersectPlane(undefined, plane);
          }).toThrowDeveloperError();
      });
  
      it('intersectPlane fails without plane parameter', function() {
          var box = new OrientedBoundingBox(Cartesian3.IDENTITY, Matrix3.ZERO);
          expect(function() {
              OrientedBoundingBox.intersectPlane(box, undefined);
          }).toThrowDeveloperError();
      });
  
      it('distanceSquaredTo', function() {
          var r0 = Matrix3.fromRotationZ(CesiumMath.toRadians(-45.0));
          var r1 = Matrix3.fromRotationY(CesiumMath.toRadians(45.0));
  
          var rotation = Matrix3.multiply(r1, r0, r0);
          var scale = new Cartesian3(2.0, 3.0, 4.0);
          var rotationScale = Matrix3.multiplyByScale(rotation, scale, rotation);
  
          var center = new Cartesian3(4.0, 3.0, 2.0);
  
          var obb = new OrientedBoundingBox(center, rotationScale);
  
          var halfAxes = obb.halfAxes;
          var xAxis = Matrix3.getColumn(halfAxes, 0, new Cartesian3());
          var yAxis = Matrix3.getColumn(halfAxes, 1, new Cartesian3());
          var zAxis = Matrix3.getColumn(halfAxes, 2, new Cartesian3());
  
          // from positive x direction
          var cartesian = Cartesian3.multiplyByScalar(xAxis, 2.0, new Cartesian3());
          Cartesian3.add(cartesian, center, cartesian);
  
          var d = Cartesian3.distance(cartesian, center) - scale.x;
          var expected = d * d;
          expect(obb.distanceSquaredTo(cartesian)).toEqualEpsilon(expected, CesiumMath.EPSILON14);
  
          // from negative x direction
          Cartesian3.multiplyByScalar(xAxis, -2.0, cartesian);
          Cartesian3.add(cartesian, center, cartesian);
  
          d = Cartesian3.distance(cartesian, center) - scale.x;
          expected = d * d;
          expect(obb.distanceSquaredTo(cartesian)).toEqualEpsilon(expected, CesiumMath.EPSILON14);
  
          // from positive y direction
          Cartesian3.multiplyByScalar(yAxis, 2.0, cartesian);
          Cartesian3.add(cartesian, center, cartesian);
  
          d = Cartesian3.distance(cartesian, center) - scale.y;
          expected = d * d;
          expect(obb.distanceSquaredTo(cartesian)).toEqualEpsilon(expected, CesiumMath.EPSILON14);
  
          // from negative y direction
          Cartesian3.multiplyByScalar(yAxis, -2.0, cartesian);
          Cartesian3.add(cartesian, center, cartesian);
  
          d = Cartesian3.distance(cartesian, center) - scale.y;
          expected = d * d;
          expect(obb.distanceSquaredTo(cartesian)).toEqualEpsilon(expected, CesiumMath.EPSILON14);
  
          // from positive z direction
          Cartesian3.multiplyByScalar(zAxis, 2.0, cartesian);
          Cartesian3.add(cartesian, center, cartesian);
  
          d = Cartesian3.distance(cartesian, center) - scale.z;
          expected = d * d;
          expect(obb.distanceSquaredTo(cartesian)).toEqualEpsilon(expected, CesiumMath.EPSILON14);
  
          // from negative z direction
          Cartesian3.multiplyByScalar(zAxis, -2.0, cartesian);
          Cartesian3.add(cartesian, center, cartesian);
  
          d = Cartesian3.distance(cartesian, center) - scale.z;
          expected = d * d;
          expect(obb.distanceSquaredTo(cartesian)).toEqualEpsilon(expected, CesiumMath.EPSILON14);
  
          // from corner point
          Cartesian3.add(xAxis, yAxis, cartesian);
          Cartesian3.add(zAxis, cartesian, cartesian);
  
          var cornerDistance = Cartesian3.magnitude(cartesian);
          Cartesian3.add(cartesian, center, cartesian);
  
          d = Cartesian3.distance(cartesian, center) - cornerDistance;
          expected = d * d;
          expect(obb.distanceSquaredTo(cartesian)).toEqualEpsilon(expected, CesiumMath.EPSILON14);
      });
  
      it('distanceSquaredTo throws without box', function() {
          expect(function() {
              OrientedBoundingBox.distanceSquaredTo(undefined, new Cartesian3());
          }).toThrowDeveloperError();
      });
  
      it('distanceSquaredTo throws without cartesian', function() {
          expect(function() {
              OrientedBoundingBox.distanceSquaredTo(new OrientedBoundingBox(), undefined);
          }).toThrowDeveloperError();
      });
  
      it('computePlaneDistances', function() {
          var r0 = Matrix3.fromRotationZ(CesiumMath.toRadians(-45.0));
          var r1 = Matrix3.fromRotationY(CesiumMath.toRadians(45.0));
  
          var rotation = Matrix3.multiply(r1, r0, r0);
          var scale = new Cartesian3(2.0, 3.0, 4.0);
          var rotationScale = Matrix3.multiplyByScale(rotation, scale, rotation);
  
          var center = new Cartesian3(4.0, 3.0, 2.0);
  
          var obb = new OrientedBoundingBox(center, rotationScale);
  
          var halfAxes = obb.halfAxes;
          var xAxis = Matrix3.getColumn(halfAxes, 0, new Cartesian3());
          var yAxis = Matrix3.getColumn(halfAxes, 1, new Cartesian3());
          var zAxis = Matrix3.getColumn(halfAxes, 2, new Cartesian3());
  
          // from x direction
          var position = Cartesian3.multiplyByScalar(xAxis, 2.0, new Cartesian3());
          Cartesian3.add(position, center, position);
  
          var direction = Cartesian3.negate(xAxis, new Cartesian3());
          Cartesian3.normalize(direction, direction);
  
          var d = Cartesian3.distance(position, center);
          var expectedNear = d - scale.x;
          var expectedFar = d + scale.x;
  
          var distances = obb.computePlaneDistances(position, direction);
          expect(distances.start).toEqualEpsilon(expectedNear, CesiumMath.EPSILON14);
          expect(distances.stop).toEqualEpsilon(expectedFar, CesiumMath.EPSILON14);
  
          // from y direction
          Cartesian3.multiplyByScalar(yAxis, 2.0, position);
          Cartesian3.add(position, center, position);
  
          Cartesian3.negate(yAxis, direction);
          Cartesian3.normalize(direction, direction);
  
          d = Cartesian3.distance(position, center);
          expectedNear = d - scale.y;
          expectedFar = d + scale.y;
  
          obb.computePlaneDistances(position, direction, distances);
          expect(distances.start).toEqualEpsilon(expectedNear, CesiumMath.EPSILON14);
          expect(distances.stop).toEqualEpsilon(expectedFar, CesiumMath.EPSILON14);
  
          // from z direction
          Cartesian3.multiplyByScalar(zAxis, 2.0, position);
          Cartesian3.add(position, center, position);
  
          Cartesian3.negate(zAxis, direction);
          Cartesian3.normalize(direction, direction);
  
          d = Cartesian3.distance(position, center);
          expectedNear = d - scale.z;
          expectedFar = d + scale.z;
  
          obb.computePlaneDistances(position, direction, distances);
          expect(distances.start).toEqualEpsilon(expectedNear, CesiumMath.EPSILON14);
          expect(distances.stop).toEqualEpsilon(expectedFar, CesiumMath.EPSILON14);
  
          // from corner point
          Cartesian3.add(xAxis, yAxis, position);
          Cartesian3.add(zAxis, position, position);
  
          Cartesian3.negate(position, direction);
          Cartesian3.normalize(direction, direction);
  
          var cornerDistance = Cartesian3.magnitude(position);
          Cartesian3.add(position, center, position);
  
          d = Cartesian3.distance(position, center);
          expectedNear = d - cornerDistance;
          expectedFar = d + cornerDistance;
  
          obb.computePlaneDistances(position, direction, distances);
          expect(distances.start).toEqualEpsilon(expectedNear, CesiumMath.EPSILON14);
          expect(distances.stop).toEqualEpsilon(expectedFar, CesiumMath.EPSILON14);
      });
  
      it('computePlaneDistances throws without a box', function() {
          expect(function() {
              OrientedBoundingBox.computePlaneDistances(undefined, new Cartesian3(), new Cartesian3());
          }).toThrowDeveloperError();
      });
  
      it('computePlaneDistances throws without a position', function() {
          expect(function() {
              OrientedBoundingBox.computePlaneDistances(new OrientedBoundingBox(), undefined, new Cartesian3());
          }).toThrowDeveloperError();
      });
  
      it('computePlaneDistances throws without a direction', function() {
          expect(function() {
              OrientedBoundingBox.computePlaneDistances(new OrientedBoundingBox(), new Cartesian3(), undefined);
          }).toThrowDeveloperError();
      });
  
      it('isOccluded', function() {
          var occluderSphere = new BoundingSphere(new Cartesian3(0, 0, -1.5), 0.5);
          var occluder = new Occluder(occluderSphere, Cartesian3.ZERO);
  
          var radius = 0.25 / Math.sqrt(2.0);
          var halfAxes = Matrix3.multiplyByScale(Matrix3.IDENTITY, new Cartesian3(radius, radius, radius), new Matrix3());
          var obb = new OrientedBoundingBox(new Cartesian3(0, 0, -2.75), halfAxes);
          expect(obb.isOccluded(occluder)).toEqual(true);
  
          occluderSphere = new BoundingSphere(new Cartesian3(0, 0, -2.75), 0.25);
          occluder = new Occluder(occluderSphere, Cartesian3.ZERO);
  
          radius = 0.5 / Math.sqrt(2.0);
          halfAxes = Matrix3.multiplyByScale(Matrix3.IDENTITY, new Cartesian3(radius, radius, radius), new Matrix3());
          obb = new OrientedBoundingBox(new Cartesian3(0, 0, -1.5), halfAxes);
          expect(obb.isOccluded(occluder)).toEqual(false);
      });
  
      it('isOccluded throws without a box', function() {
          expect(function() {
              OrientedBoundingBox.isOccluded(undefined, new Occluder(new BoundingSphere(), new Cartesian3()));
          }).toThrowDeveloperError();
      });
  
      it('isOccluded throws without a occluder', function() {
          expect(function() {
              OrientedBoundingBox.isOccluded(new OrientedBoundingBox(), undefined);
          }).toThrowDeveloperError();
      });
  
      it('clone without a result parameter', function() {
          var box = new OrientedBoundingBox();
          var result = OrientedBoundingBox.clone(box);
          expect(box).not.toBe(result);
          expect(box).toEqual(result);
          expect(box.clone()).toEqual(box);
      });
  
      it('clone with a result parameter', function() {
          var box = new OrientedBoundingBox();
          var box2 = new OrientedBoundingBox();
          var result = new OrientedBoundingBox();
          var returnedResult = OrientedBoundingBox.clone(box, result);
          expect(result).toBe(returnedResult);
          expect(box).not.toBe(result);
          expect(box).toEqual(result);
          expect(box.clone(box2)).toBe(box2);
          expect(box.clone(box2)).toEqual(box2);
      });
  
      it('clone undefined OBB with a result parameter', function() {
          var box = new OrientedBoundingBox();
          var box2 = new OrientedBoundingBox();
          expect(OrientedBoundingBox.clone(undefined, box)).toBe(undefined);
      });
  
      it('clone undefined OBB without a result parameter', function() {
          expect(OrientedBoundingBox.clone(undefined)).toBe(undefined);
      });
  
      it('equals works in all cases', function() {
          var box = new OrientedBoundingBox();
          expect(box.equals(new OrientedBoundingBox())).toEqual(true);
          expect(box.equals(undefined)).toEqual(false);
      });
  });
  