From 7265e2012d34c21b3f7b6e1d55400388eda46180 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Fri, 29 May 2015 13:08:18 +1000 Subject: [PATCH 1/6] Improve position selected for camera in viewRectangle in 3D. --- Source/Scene/Camera.js | 10 ++++++++-- Specs/Scene/CameraSpec.js | 29 +++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js index fed7d13feaf6..be34c91e55cd 100644 --- a/Source/Scene/Camera.js +++ b/Source/Scene/Camera.js @@ -1662,6 +1662,7 @@ define([ var viewRectangle3DNorthWest = new Cartesian3(); var viewRectangle3DSouthEast = new Cartesian3(); var viewRectangle3DCenter = new Cartesian3(); + var viewRectangle3DCenter2 = new Cartesian3(); var defaultRF = {direction: new Cartesian3(), right: new Cartesian3(), up: new Cartesian3()}; function rectangleCameraPosition3D (camera, rectangle, ellipsoid, result, positionOnly) { if (!defined(result)) { @@ -1693,9 +1694,14 @@ define([ cart.latitude = north; var northWest = ellipsoid.cartographicToCartesian(cart, viewRectangle3DNorthWest); - var center = Cartesian3.subtract(northEast, southWest, viewRectangle3DCenter); + var center1 = Cartesian3.add(northEast, southWest, viewRectangle3DCenter); + Cartesian3.multiplyByScalar(center1, 0.5, center1); + + var center2 = Cartesian3.add(northWest, southEast, viewRectangle3DCenter2); + Cartesian3.multiplyByScalar(center2, 0.5, center2); + + var center = Cartesian3.add(center1, center2, viewRectangle3DCenter); Cartesian3.multiplyByScalar(center, 0.5, center); - Cartesian3.add(southWest, center, center); var mag = Cartesian3.magnitude(center); if (mag < CesiumMath.EPSILON6) { diff --git a/Specs/Scene/CameraSpec.js b/Specs/Scene/CameraSpec.js index 1a0157a14158..b2e9f4e2dfa0 100644 --- a/Specs/Scene/CameraSpec.js +++ b/Specs/Scene/CameraSpec.js @@ -1294,10 +1294,10 @@ defineSuite([ CesiumMath.toRadians(21.51), CesiumMath.toRadians(41.38)); camera.viewRectangle(rectangle, Ellipsoid.WGS84); - expect(camera.position).toEqualEpsilon(new Cartesian3(4481581.054168208, 1754494.5938935655, 4200573.072090136), CesiumMath.EPSILON6); - expect(camera.direction).toEqualEpsilon(new Cartesian3(-0.7015530983057745, -0.2746510892984876, -0.6575637074875123), CesiumMath.EPSILON10); - expect(camera.up).toEqualEpsilon(new Cartesian3(-0.6123128513437499, -0.23971441651266895, 0.7533989451779698), CesiumMath.EPSILON10); - expect(camera.right).toEqualEpsilon(new Cartesian3(-0.36454934142973716, 0.9311840729217532, 0.0), CesiumMath.EPSILON10); + expect(camera.position).toEqualEpsilon(new Cartesian3(4481576.462641985, 1754506.2333086901, 4200573.043826864), CesiumMath.EPSILON6); + expect(camera.direction).toEqualEpsilon(new Cartesian3(-0.7015523842633958, -0.2746529131976636, -0.6575637074887735), CesiumMath.EPSILON10); + expect(camera.up).toEqualEpsilon(new Cartesian3(-0.6123122281323717, -0.23971600840567894, 0.753398945176869), CesiumMath.EPSILON10); + expect(camera.right).toEqualEpsilon(new Cartesian3(-0.36455176232452213, 0.9311831251617939, 0), CesiumMath.EPSILON10); }); it('views rectangle in 3D (3)', function() { @@ -1307,10 +1307,23 @@ defineSuite([ CesiumMath.toRadians(157.0), CesiumMath.toRadians(0.0)); camera.viewRectangle(rectangle); - expect(camera.position).toEqualEpsilon(new Cartesian3(-7210721.873278953, 8105929.1576369405, -5972336.199381728), CesiumMath.EPSILON6); - expect(camera.direction).toEqualEpsilon(new Cartesian3(0.5822498554483325, -0.6545358652367963, 0.48225294913469874), CesiumMath.EPSILON10); - expect(camera.up).toEqualEpsilon(new Cartesian3(-0.32052676705406324, 0.3603199946588929, 0.8760320159964963), CesiumMath.EPSILON10); - expect(camera.right).toEqualEpsilon(new Cartesian3(-0.7471597536218517, -0.6646444933705039, 0.0), CesiumMath.EPSILON10); + expect(camera.position).toEqualEpsilon(new Cartesian3(-5354265.048954285, 8089412.071902344, -5394849.1980100395), CesiumMath.EPSILON6); + expect(camera.direction).toEqualEpsilon(new Cartesian3(0.482363989580257, -0.7287724915903437, 0.4860202023140807), CesiumMath.EPSILON10); + expect(camera.up).toEqualEpsilon(new Cartesian3(-0.2682525252659903, 0.40528535594792864, 0.8739475744817764), CesiumMath.EPSILON10); + expect(camera.right).toEqualEpsilon(new Cartesian3(-0.8338858220671682, -0.5519369853120581, 0), CesiumMath.EPSILON10); + }); + + it('views rectangle in 3D (4)', function() { + var rectangle = new Rectangle( + CesiumMath.toRadians(90.0), + CesiumMath.toRadians(-62.0), + CesiumMath.toRadians(174.0), + CesiumMath.toRadians(-4.0)); + camera.viewRectangle(rectangle); + expect(camera.position).toEqualEpsilon(new Cartesian3(-6052171.694828278, 6721617.626171295, -7863430.682248364), CesiumMath.EPSILON6); + expect(camera.direction).toEqualEpsilon(new Cartesian3(0.5049749224362994, -0.5608314685326552, 0.6561009004825087), CesiumMath.EPSILON10); + expect(camera.up).toEqualEpsilon(new Cartesian3(-0.4390171933724539, 0.4875779891846352, 0.7546731798507491), CesiumMath.EPSILON10); + expect(camera.right).toEqualEpsilon(new Cartesian3(-0.7431448254773944, -0.6691306063588581, 0), CesiumMath.EPSILON10); }); it('views rectangle in 3D across IDL', function() { From 54b833ca15bc94cfe1293199b40f19d763bc78ef Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Fri, 29 May 2015 13:19:05 +1000 Subject: [PATCH 2/6] Update CHANGES.md. --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 3aa6e0d26cd1..b47dd6fa0916 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -51,6 +51,7 @@ Change Log * Added debug option to `Scene` to show the depth buffer information for a specified view frustum slice and exposed capability in `CesiumInspector` widget. * Added new leap second for 30 June 2015 at UTC 23:59:60. * Upgraded Autolinker from version 0.15.2 to 0.17.1. +* Improved the algorithm that `Camera.viewRectangle` uses to select the position of the camera, so that the specified rectangle is now better centered on the screen. ### 1.9 - 2015-05-01 From 690bca30720fbc1916b0bbc564df68df924a1838 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Fri, 29 May 2015 14:12:21 +1000 Subject: [PATCH 3/6] Simplify the code. --- Source/Scene/Camera.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js index be34c91e55cd..09688e9be14e 100644 --- a/Source/Scene/Camera.js +++ b/Source/Scene/Camera.js @@ -1662,7 +1662,6 @@ define([ var viewRectangle3DNorthWest = new Cartesian3(); var viewRectangle3DSouthEast = new Cartesian3(); var viewRectangle3DCenter = new Cartesian3(); - var viewRectangle3DCenter2 = new Cartesian3(); var defaultRF = {direction: new Cartesian3(), right: new Cartesian3(), up: new Cartesian3()}; function rectangleCameraPosition3D (camera, rectangle, ellipsoid, result, positionOnly) { if (!defined(result)) { @@ -1694,14 +1693,10 @@ define([ cart.latitude = north; var northWest = ellipsoid.cartographicToCartesian(cart, viewRectangle3DNorthWest); - var center1 = Cartesian3.add(northEast, southWest, viewRectangle3DCenter); - Cartesian3.multiplyByScalar(center1, 0.5, center1); - - var center2 = Cartesian3.add(northWest, southEast, viewRectangle3DCenter2); - Cartesian3.multiplyByScalar(center2, 0.5, center2); - - var center = Cartesian3.add(center1, center2, viewRectangle3DCenter); - Cartesian3.multiplyByScalar(center, 0.5, center); + var center = Cartesian3.add(northEast, southWest, viewRectangle3DCenter); + center = Cartesian3.add(center, northWest, center); + center = Cartesian3.add(center, southEast, center); + Cartesian3.multiplyByScalar(center, 0.25, center); var mag = Cartesian3.magnitude(center); if (mag < CesiumMath.EPSILON6) { From b5ace2374e4a6420cc9ab7b1ed771072115e26bd Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 3 Jun 2015 13:43:54 +1000 Subject: [PATCH 4/6] Further improvements to viewRectangle. --- Source/Core/EllipsoidGeodesic.js | 21 +++-- Source/Scene/Camera.js | 132 +++++++++++++++++++++++-------- Specs/Scene/CameraSpec.js | 18 ++--- 3 files changed, 124 insertions(+), 47 deletions(-) diff --git a/Source/Core/EllipsoidGeodesic.js b/Source/Core/EllipsoidGeodesic.js index d382bd0c296f..c77c6fc9ad31 100644 --- a/Source/Core/EllipsoidGeodesic.js +++ b/Source/Core/EllipsoidGeodesic.js @@ -224,7 +224,18 @@ define([ defineProperties(EllipsoidGeodesic.prototype, { /** - * The surface distance between the start and end point + * Gets the ellipsoid. + * @memberof EllipsoidGeodesic.prototype + * @type {Ellipsoid} + */ + ellipsoid : { + get : function() { + return this._ellipsoid; + } + }, + + /** + * Gets the surface distance between the start and end point * @memberof EllipsoidGeodesic.prototype * @type {Number} */ @@ -241,7 +252,7 @@ define([ }, /** - * The initial planetodetic point on the path. + * Gets the initial planetodetic point on the path. * @memberof EllipsoidGeodesic.prototype * @type {Cartographic} */ @@ -252,7 +263,7 @@ define([ }, /** - * The final planetodetic point on the path. + * Gets the final planetodetic point on the path. * @memberof EllipsoidGeodesic.prototype * @type {Cartographic} */ @@ -263,7 +274,7 @@ define([ }, /** - * The heading at the initial point. + * Gets the heading at the initial point. * @memberof EllipsoidGeodesic.prototype * @type {Number} */ @@ -280,7 +291,7 @@ define([ }, /** - * The heading at the final point. + * Gets the heading at the final point. * @memberof EllipsoidGeodesic.prototype * @type {Number} */ diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js index 09688e9be14e..febd6ab0fe12 100644 --- a/Source/Scene/Camera.js +++ b/Source/Scene/Camera.js @@ -10,6 +10,7 @@ define([ '../Core/DeveloperError', '../Core/EasingFunction', '../Core/Ellipsoid', + '../Core/EllipsoidGeodesic', '../Core/Event', '../Core/IntersectionTests', '../Core/Math', @@ -34,6 +35,7 @@ define([ DeveloperError, EasingFunction, Ellipsoid, + EllipsoidGeodesic, Event, IntersectionTests, CesiumMath, @@ -1656,13 +1658,19 @@ define([ Cartesian3.normalize(this.up, this.up); }; - var viewRectangle3DCartographic = new Cartographic(); + var viewRectangle3DCartographic1 = new Cartographic(); + var viewRectangle3DCartographic2 = new Cartographic(); var viewRectangle3DNorthEast = new Cartesian3(); var viewRectangle3DSouthWest = new Cartesian3(); var viewRectangle3DNorthWest = new Cartesian3(); var viewRectangle3DSouthEast = new Cartesian3(); + var viewRectangle3DNorthCenter = new Cartesian3(); + var viewRectangle3DSouthCenter = new Cartesian3(); var viewRectangle3DCenter = new Cartesian3(); + var viewRectangle3DEquator = new Cartesian3(); var defaultRF = {direction: new Cartesian3(), right: new Cartesian3(), up: new Cartesian3()}; + var viewRectangle3DEllipsoidGeodesic; + function rectangleCameraPosition3D (camera, rectangle, ellipsoid, result, positionOnly) { if (!defined(result)) { result = new Cartesian3(); @@ -1672,6 +1680,7 @@ define([ if (positionOnly) { cameraRF = defaultRF; } + var north = rectangle.north; var south = rectangle.south; var east = rectangle.east; @@ -1682,58 +1691,115 @@ define([ east += CesiumMath.TWO_PI; } - var cart = viewRectangle3DCartographic; + // Find the midpoint latitude. + // + // EllipsoidGeodesic will fail if the north and south edges are very close to being on opposite sides of the ellipsoid. + // Ideally we'd just call EllipsoidGeodesic.setEndPoints and let it throw when it detects this case, but sadly it doesn't + // even look for this case in optimized builds, so we have to test for it here instead. + // + // Fortunately, this case can only happen (here) when north is very close to the north pole and south is very close to the south pole, + // so handle it just by using 0 latitude as the center. It's certainliy possible to use a smaller tolerance + // than one degree here, but one degree is safe and putting the center at 0 latitude should be good enough for any + // rectangle that spans 178+ of the 180 degrees of latitude. + var longitude = (west + east) * 0.5; + var latitude; + if (south < -CesiumMath.PI_OVER_TWO + CesiumMath.RADIANS_PER_DEGREE && north > CesiumMath.PI_OVER_TWO - CesiumMath.RADIANS_PER_DEGREE) { + latitude = 0.0; + } else { + var northCartographic = viewRectangle3DCartographic1; + northCartographic.longitude = longitude; + northCartographic.latitude = north; + northCartographic.height = 0.0; + + var southCartographic = viewRectangle3DCartographic2; + southCartographic.longitude = longitude; + southCartographic.latitude = south; + southCartographic.height = 0.0; + + var ellipsoidGeodesic = viewRectangle3DEllipsoidGeodesic; + if (!defined(ellipsoidGeodesic) || ellipsoidGeodesic.ellipsoid !== ellipsoid) { + viewRectangle3DEllipsoidGeodesic = ellipsoidGeodesic = new EllipsoidGeodesic(undefined, undefined, ellipsoid); + } + + ellipsoidGeodesic.setEndPoints(northCartographic, southCartographic); + latitude = ellipsoidGeodesic.interpolateUsingFraction(0.5, viewRectangle3DCartographic1).latitude; + } + + var centerCartographic = viewRectangle3DCartographic1; + centerCartographic.longitude = longitude; + centerCartographic.latitude = latitude; + centerCartographic.height = 0.0; + + var center = ellipsoid.cartographicToCartesian(centerCartographic, viewRectangle3DCenter); + + var cart = viewRectangle3DCartographic1; cart.longitude = east; cart.latitude = north; var northEast = ellipsoid.cartographicToCartesian(cart, viewRectangle3DNorthEast); + cart.longitude = west; + var northWest = ellipsoid.cartographicToCartesian(cart, viewRectangle3DNorthWest); + cart.longitude = longitude; + var northCenter = ellipsoid.cartographicToCartesian(cart, viewRectangle3DNorthCenter); cart.latitude = south; + var southCenter = ellipsoid.cartographicToCartesian(cart, viewRectangle3DSouthCenter); + cart.longitude = east; var southEast = ellipsoid.cartographicToCartesian(cart, viewRectangle3DSouthEast); cart.longitude = west; var southWest = ellipsoid.cartographicToCartesian(cart, viewRectangle3DSouthWest); - cart.latitude = north; - var northWest = ellipsoid.cartographicToCartesian(cart, viewRectangle3DNorthWest); - - var center = Cartesian3.add(northEast, southWest, viewRectangle3DCenter); - center = Cartesian3.add(center, northWest, center); - center = Cartesian3.add(center, southEast, center); - Cartesian3.multiplyByScalar(center, 0.25, center); - - var mag = Cartesian3.magnitude(center); - if (mag < CesiumMath.EPSILON6) { - cart.longitude = (east + west) * 0.5; - cart.latitude = (north + south) * 0.5; - ellipsoid.cartographicToCartesian(cart, center); - } Cartesian3.subtract(northWest, center, northWest); Cartesian3.subtract(southEast, center, southEast); Cartesian3.subtract(northEast, center, northEast); Cartesian3.subtract(southWest, center, southWest); + Cartesian3.subtract(northCenter, center, northCenter); + Cartesian3.subtract(southCenter, center, southCenter); - var direction = Cartesian3.negate(center, cameraRF.direction); - Cartesian3.normalize(direction, direction); + var direction = ellipsoid.geodeticSurfaceNormal(center, cameraRF.direction); + Cartesian3.negate(direction, direction); var right = Cartesian3.cross(direction, Cartesian3.UNIT_Z, cameraRF.right); Cartesian3.normalize(right, right); var up = Cartesian3.cross(right, direction, cameraRF.up); - var height = Math.max( - Math.abs(Cartesian3.dot(up, northWest)), - Math.abs(Cartesian3.dot(up, southEast)), - Math.abs(Cartesian3.dot(up, northEast)), - Math.abs(Cartesian3.dot(up, southWest)) - ); - var width = Math.max( - Math.abs(Cartesian3.dot(right, northWest)), - Math.abs(Cartesian3.dot(right, southEast)), - Math.abs(Cartesian3.dot(right, northEast)), - Math.abs(Cartesian3.dot(right, southWest)) - ); - var tanPhi = Math.tan(camera.frustum.fovy * 0.5); var tanTheta = camera.frustum.aspectRatio * tanPhi; - var d = Math.max(width / tanTheta, height / tanPhi); - var scalar = mag + d; + function computeD(direction, upOrRight, corner, tanThetaOrPhi) { + var opposite = Math.abs(Cartesian3.dot(upOrRight, corner)); + return opposite / tanThetaOrPhi - Cartesian3.dot(direction, corner); + } + + var d = Math.max( + computeD(direction, up, northWest, tanPhi), + computeD(direction, up, southEast, tanPhi), + computeD(direction, up, northEast, tanPhi), + computeD(direction, up, southWest, tanPhi), + computeD(direction, up, northCenter, tanPhi), + computeD(direction, up, southCenter, tanPhi), + computeD(direction, right, northWest, tanTheta), + computeD(direction, right, southEast, tanTheta), + computeD(direction, right, northEast, tanTheta), + computeD(direction, right, southWest, tanTheta), + computeD(direction, right, northCenter, tanTheta), + computeD(direction, right, southCenter, tanTheta)); + + // If the rectangle crosses the equator, compute D at the equator, too, because that's the + // widest part of the rectangle when projected onto the globe. + if (south < 0 && north > 0) { + var equatorCartographic = viewRectangle3DCartographic1; + equatorCartographic.longitude = west; + equatorCartographic.latitude = 0.0; + equatorCartographic.height = 0.0; + var equatorPosition = ellipsoid.cartographicToCartesian(equatorCartographic, viewRectangle3DEquator); + Cartesian3.subtract(equatorPosition, center, equatorPosition); + d = Math.max(d, computeD(direction, up, equatorPosition, tanPhi), computeD(direction, right, equatorPosition, tanTheta)); + + equatorCartographic.longitude = east; + equatorPosition = ellipsoid.cartographicToCartesian(equatorCartographic, viewRectangle3DEquator); + Cartesian3.subtract(equatorPosition, center, equatorPosition); + d = Math.max(d, computeD(direction, up, equatorPosition, tanPhi), computeD(direction, right, equatorPosition, tanTheta)); + } + + var scalar = Cartesian3.magnitude(center) + d; Cartesian3.normalize(center, center); return Cartesian3.multiplyByScalar(center, scalar, result); } diff --git a/Specs/Scene/CameraSpec.js b/Specs/Scene/CameraSpec.js index b2e9f4e2dfa0..8db4da45cedf 100644 --- a/Specs/Scene/CameraSpec.js +++ b/Specs/Scene/CameraSpec.js @@ -1294,9 +1294,9 @@ defineSuite([ CesiumMath.toRadians(21.51), CesiumMath.toRadians(41.38)); camera.viewRectangle(rectangle, Ellipsoid.WGS84); - expect(camera.position).toEqualEpsilon(new Cartesian3(4481576.462641985, 1754506.2333086901, 4200573.043826864), CesiumMath.EPSILON6); - expect(camera.direction).toEqualEpsilon(new Cartesian3(-0.7015523842633958, -0.2746529131976636, -0.6575637074887735), CesiumMath.EPSILON10); - expect(camera.up).toEqualEpsilon(new Cartesian3(-0.6123122281323717, -0.23971600840567894, 0.753398945176869), CesiumMath.EPSILON10); + expect(camera.position).toEqualEpsilon(new Cartesian3(4481594.74880154, 1754513.392213863, 4200579.395187099), CesiumMath.EPSILON6); + expect(camera.direction).toEqualEpsilon(new Cartesian3(-0.6995108433013301, -0.27385366401082994, -0.6600672320390594), CesiumMath.EPSILON10); + expect(camera.up).toEqualEpsilon(new Cartesian3(-0.6146434679470263, -0.24062867269250837, 0.75120652898407), CesiumMath.EPSILON10); expect(camera.right).toEqualEpsilon(new Cartesian3(-0.36455176232452213, 0.9311831251617939, 0), CesiumMath.EPSILON10); }); @@ -1307,9 +1307,9 @@ defineSuite([ CesiumMath.toRadians(157.0), CesiumMath.toRadians(0.0)); camera.viewRectangle(rectangle); - expect(camera.position).toEqualEpsilon(new Cartesian3(-5354265.048954285, 8089412.071902344, -5394849.1980100395), CesiumMath.EPSILON6); - expect(camera.direction).toEqualEpsilon(new Cartesian3(0.482363989580257, -0.7287724915903437, 0.4860202023140807), CesiumMath.EPSILON10); - expect(camera.up).toEqualEpsilon(new Cartesian3(-0.2682525252659903, 0.40528535594792864, 0.8739475744817764), CesiumMath.EPSILON10); + expect(camera.position).toEqualEpsilon(new Cartesian3(-6020987.145335815, 9096719.279476268, -5061902.525777783), CesiumMath.EPSILON6); + expect(camera.direction).toEqualEpsilon(new Cartesian3(0.5000640869795608, -0.7555144216716235, 0.4232420909591703), CesiumMath.EPSILON10); + expect(camera.up).toEqualEpsilon(new Cartesian3(-0.23360296374117637, 0.35293557895291494, 0.9060166292295686), CesiumMath.EPSILON10); expect(camera.right).toEqualEpsilon(new Cartesian3(-0.8338858220671682, -0.5519369853120581, 0), CesiumMath.EPSILON10); }); @@ -1320,9 +1320,9 @@ defineSuite([ CesiumMath.toRadians(174.0), CesiumMath.toRadians(-4.0)); camera.viewRectangle(rectangle); - expect(camera.position).toEqualEpsilon(new Cartesian3(-6052171.694828278, 6721617.626171295, -7863430.682248364), CesiumMath.EPSILON6); - expect(camera.direction).toEqualEpsilon(new Cartesian3(0.5049749224362994, -0.5608314685326552, 0.6561009004825087), CesiumMath.EPSILON10); - expect(camera.up).toEqualEpsilon(new Cartesian3(-0.4390171933724539, 0.4875779891846352, 0.7546731798507491), CesiumMath.EPSILON10); + expect(camera.position).toEqualEpsilon(new Cartesian3(-7315343.706901635, 8124512.271161941, -7068894.119227167), CesiumMath.EPSILON6); + expect(camera.direction).toEqualEpsilon(new Cartesian3(0.5607858365117034, -0.622815768168856, 0.5455453826109309), CesiumMath.EPSILON10); + expect(camera.up).toEqualEpsilon(new Cartesian3(-0.3650411126627274, 0.4054192281503986, 0.8380812821629494), CesiumMath.EPSILON10); expect(camera.right).toEqualEpsilon(new Cartesian3(-0.7431448254773944, -0.6691306063588581, 0), CesiumMath.EPSILON10); }); From 1cbb66c8dd757b3def79d30975eb86069290c7a0 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Thu, 4 Jun 2015 09:32:30 +1000 Subject: [PATCH 5/6] Displace d along the geodetic normal instead of geocentric. --- Source/Scene/Camera.js | 4 +--- Specs/Scene/CameraSpec.js | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js index febd6ab0fe12..dd47c2eea875 100644 --- a/Source/Scene/Camera.js +++ b/Source/Scene/Camera.js @@ -1799,9 +1799,7 @@ define([ d = Math.max(d, computeD(direction, up, equatorPosition, tanPhi), computeD(direction, right, equatorPosition, tanTheta)); } - var scalar = Cartesian3.magnitude(center) + d; - Cartesian3.normalize(center, center); - return Cartesian3.multiplyByScalar(center, scalar, result); + return Cartesian3.add(center, Cartesian3.multiplyByScalar(direction, -d, viewRectangle3DEquator), result); } var viewRectangleCVCartographic = new Cartographic(); diff --git a/Specs/Scene/CameraSpec.js b/Specs/Scene/CameraSpec.js index 8db4da45cedf..79a3beec4f59 100644 --- a/Specs/Scene/CameraSpec.js +++ b/Specs/Scene/CameraSpec.js @@ -1294,7 +1294,7 @@ defineSuite([ CesiumMath.toRadians(21.51), CesiumMath.toRadians(41.38)); camera.viewRectangle(rectangle, Ellipsoid.WGS84); - expect(camera.position).toEqualEpsilon(new Cartesian3(4481594.74880154, 1754513.392213863, 4200579.395187099), CesiumMath.EPSILON6); + expect(camera.position).toEqualEpsilon(new Cartesian3(4481555.454147325, 1754498.0086281248, 4200627.581953675), CesiumMath.EPSILON6); expect(camera.direction).toEqualEpsilon(new Cartesian3(-0.6995108433013301, -0.27385366401082994, -0.6600672320390594), CesiumMath.EPSILON10); expect(camera.up).toEqualEpsilon(new Cartesian3(-0.6146434679470263, -0.24062867269250837, 0.75120652898407), CesiumMath.EPSILON10); expect(camera.right).toEqualEpsilon(new Cartesian3(-0.36455176232452213, 0.9311831251617939, 0), CesiumMath.EPSILON10); @@ -1307,7 +1307,7 @@ defineSuite([ CesiumMath.toRadians(157.0), CesiumMath.toRadians(0.0)); camera.viewRectangle(rectangle); - expect(camera.position).toEqualEpsilon(new Cartesian3(-6020987.145335815, 9096719.279476268, -5061902.525777783), CesiumMath.EPSILON6); + expect(camera.position).toEqualEpsilon(new Cartesian3(-6017603.25625715, 9091606.78076493, -5075070.862292178), CesiumMath.EPSILON6); expect(camera.direction).toEqualEpsilon(new Cartesian3(0.5000640869795608, -0.7555144216716235, 0.4232420909591703), CesiumMath.EPSILON10); expect(camera.up).toEqualEpsilon(new Cartesian3(-0.23360296374117637, 0.35293557895291494, 0.9060166292295686), CesiumMath.EPSILON10); expect(camera.right).toEqualEpsilon(new Cartesian3(-0.8338858220671682, -0.5519369853120581, 0), CesiumMath.EPSILON10); @@ -1320,7 +1320,7 @@ defineSuite([ CesiumMath.toRadians(174.0), CesiumMath.toRadians(-4.0)); camera.viewRectangle(rectangle); - expect(camera.position).toEqualEpsilon(new Cartesian3(-7315343.706901635, 8124512.271161941, -7068894.119227167), CesiumMath.EPSILON6); + expect(camera.position).toEqualEpsilon(new Cartesian3(-7307919.685704952, 8116267.060310548, -7085995.891547672), CesiumMath.EPSILON6); expect(camera.direction).toEqualEpsilon(new Cartesian3(0.5607858365117034, -0.622815768168856, 0.5455453826109309), CesiumMath.EPSILON10); expect(camera.up).toEqualEpsilon(new Cartesian3(-0.3650411126627274, 0.4054192281503986, 0.8380812821629494), CesiumMath.EPSILON10); expect(camera.right).toEqualEpsilon(new Cartesian3(-0.7431448254773944, -0.6691306063588581, 0), CesiumMath.EPSILON10); From e2af4fc3158ec8480c381bcd4736d05ae3749f48 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 3 Jun 2015 20:53:50 -0400 Subject: [PATCH 6/6] Update CHANGES.md. --- CHANGES.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index b47dd6fa0916..5e459519d18e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,7 +1,16 @@ Change Log ========== +### 1.11 - 2015-07-01 + +* Breaking changes + * +* Deprecated + * +* Improved the algorithm that `Camera.viewRectangle` uses to select the position of the camera, so that the specified rectangle is now better centered on the screen. + ### 1.10 - 2015-06-01 + * Breaking changes * Existing bookmarks to documentation of static members have changed [#2757](https://github.com/AnalyticalGraphicsInc/cesium/issues/2757). * Removed `InfoBoxViewModel.defaultSanitizer`, `InfoBoxViewModel.sanitizer`, and `Cesium.sanitize`, which was deprecated in 1.7. @@ -51,7 +60,6 @@ Change Log * Added debug option to `Scene` to show the depth buffer information for a specified view frustum slice and exposed capability in `CesiumInspector` widget. * Added new leap second for 30 June 2015 at UTC 23:59:60. * Upgraded Autolinker from version 0.15.2 to 0.17.1. -* Improved the algorithm that `Camera.viewRectangle` uses to select the position of the camera, so that the specified rectangle is now better centered on the screen. ### 1.9 - 2015-05-01