From ead79f498d56f0188754463c97ec1868aa8f914a Mon Sep 17 00:00:00 2001 From: "duvi.fn" Date: Wed, 2 Nov 2016 21:46:32 +0200 Subject: [PATCH 01/19] fix_billboardOnTerrain --- Source/Scene/QuadtreePrimitive.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/Scene/QuadtreePrimitive.js b/Source/Scene/QuadtreePrimitive.js index 3c013df87671..3bb47d6f65f3 100644 --- a/Source/Scene/QuadtreePrimitive.js +++ b/Source/Scene/QuadtreePrimitive.js @@ -631,8 +631,10 @@ define([ } if (mode === SceneMode.SCENE3D) { - Cartesian3.clone(Cartesian3.ZERO, scratchRay.origin); - Cartesian3.normalize(data.position, scratchRay.direction); + var surfaceNormal = ellipsoid.geodeticSurfaceNormal(data.position, scratchRay.direction); + // subtract by earth minor axis radius, to account for a case where the terrain is under ellipsoid surface - is that OK or should I use lower value (maybe -11500.0 which appears some lines bellow)? + var radiusLengthVector = Cartesian3.multiplyByScalar(surfaceNormal, ellipsoid.minimumRadius, scratchPosition); + Cartesian3.subtract(data.position, radiusLengthVector, scratchRay.origin); } else { Cartographic.clone(data.positionCartographic, scratchCartographic); From 9f7d91186fa7cbe368f633386ecc13b81227260d Mon Sep 17 00:00:00 2001 From: "duvi.fn" Date: Thu, 3 Nov 2016 19:59:38 +0200 Subject: [PATCH 02/19] fix Globe.getHeight function better handling of under ellipsoid surface terrain --- Source/Scene/Globe.js | 11 ++++++++++- Source/Scene/QuadtreePrimitive.js | 12 +++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index e84b483997b0..0d96fda711ae 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -430,7 +430,16 @@ define([ var cartesian = ellipsoid.cartographicToCartesian(cartographic, scratchGetHeightCartesian); var ray = scratchGetHeightRay; - Cartesian3.normalize(cartesian, ray.direction); + var surfaceNormal = ellipsoid.geodeticSurfaceNormal(cartesian, ray.direction); + + // compute origin point, to account for a case where the terrain is under ellipsoid surface + var minimumHeight = Math.min(defaultValue(tile.data.minimumHeight, 0.0), 0.0); + + // take into account the position height + minimumHeight -= cartographic.height; + + var minimumHeightVector = Cartesian3.multiplyByScalar(surfaceNormal, minimumHeight - 1.0, scratchGetHeightIntersection); + Cartesian3.add(cartesian, minimumHeightVector, ray.origin); var intersection = tile.data.pick(ray, undefined, undefined, false, scratchGetHeightIntersection); if (!defined(intersection)) { diff --git a/Source/Scene/QuadtreePrimitive.js b/Source/Scene/QuadtreePrimitive.js index 3bb47d6f65f3..2555401f7f42 100644 --- a/Source/Scene/QuadtreePrimitive.js +++ b/Source/Scene/QuadtreePrimitive.js @@ -632,9 +632,15 @@ define([ if (mode === SceneMode.SCENE3D) { var surfaceNormal = ellipsoid.geodeticSurfaceNormal(data.position, scratchRay.direction); - // subtract by earth minor axis radius, to account for a case where the terrain is under ellipsoid surface - is that OK or should I use lower value (maybe -11500.0 which appears some lines bellow)? - var radiusLengthVector = Cartesian3.multiplyByScalar(surfaceNormal, ellipsoid.minimumRadius, scratchPosition); - Cartesian3.subtract(data.position, radiusLengthVector, scratchRay.origin); + + // compute origin point, to account for a case where the terrain is under ellipsoid surface + var minimumHeight = Math.min(defaultValue(tile.data.minimumHeight, 0.0), 0.0); + + // take into account the position height + minimumHeight -= data.positionCartographic.height; + + var minimumHeightVector = Cartesian3.multiplyByScalar(surfaceNormal, minimumHeight - 1.0, scratchPosition); + Cartesian3.add(data.position, minimumHeightVector, scratchRay.origin); } else { Cartographic.clone(data.positionCartographic, scratchCartographic); From 156d5bb52f2d7139f142e045722d1409e5809228 Mon Sep 17 00:00:00 2001 From: "duvi.fn" Date: Sun, 27 Nov 2016 14:50:23 +0200 Subject: [PATCH 03/19] compute origin point at the intersection of the surface normal with the z-axis --- Source/Scene/Globe.js | 40 ++++++++++++++++++++++++++----- Source/Scene/QuadtreePrimitive.js | 39 +++++++++++++++++++++++++----- 2 files changed, 67 insertions(+), 12 deletions(-) diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index 0d96fda711ae..5490aeb2a36c 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -15,6 +15,7 @@ define([ '../Core/GeographicProjection', '../Core/IntersectionTests', '../Core/loadImage', + '../Core/Math', '../Core/Ray', '../Core/Rectangle', '../Renderer/ShaderSource', @@ -45,6 +46,7 @@ define([ GeographicProjection, IntersectionTests, loadImage, + CesiumMath, Ray, Rectangle, ShaderSource, @@ -432,14 +434,40 @@ define([ var ray = scratchGetHeightRay; var surfaceNormal = ellipsoid.geodeticSurfaceNormal(cartesian, ray.direction); - // compute origin point, to account for a case where the terrain is under ellipsoid surface - var minimumHeight = Math.min(defaultValue(tile.data.minimumHeight, 0.0), 0.0); + // compute origin point - // take into account the position height - minimumHeight -= cartographic.height; + // try to find the intersection point between the surface normal and z-axis. + // Ellipsoid is a surface of revolution, so surface normal intersects the rotation axis (z-axis) - var minimumHeightVector = Cartesian3.multiplyByScalar(surfaceNormal, minimumHeight - 1.0, scratchGetHeightIntersection); - Cartesian3.add(cartesian, minimumHeightVector, ray.origin); + // compute the magnitude required to bring surface normal to x=0, y=0, from data.position + var magnitude; + + // avoid dividing by zero + if (Math.abs(surfaceNormal.x) > CesiumMath.EPSILON16){ + magnitude = cartesian.x / surfaceNormal.x; + } else if (Math.abs(surfaceNormal.y) > CesiumMath.EPSILON16){ + magnitude = cartesian.y / surfaceNormal.y; + } else if (Math.abs(surfaceNormal.z) > CesiumMath.EPSILON16){ //surface normal is (0,0,1) | (0,0,-1) | (0,0,0) + magnitude = cartesian.z / surfaceNormal.z; + } else { //(0,0,0), just for case + magnitude = 0; + } + + var vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, magnitude, scratchGetHeightIntersection); + Cartesian3.subtract(cartesian, vectorToMinimumPoint, ray.origin); + + // Theoretically, the intersection point can be outside the ellipsoid, so we have to check if the result's 'z' is inside the ellipsoid (with some buffer) + if (Math.abs(ray.origin.z) >= ellipsoid.radii.z -11500.0){ + // intersection point is outside the ellipsoid, try other value + magnitude = Math.min(defaultValue(tile.data.minimumHeight, 0.0),-11500.0); + + // take into account the position height + magnitude -= cartographic.height; + + // multiply by the *positive* value of the magnitude + vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, Math.abs(magnitude) + 1, scratchGetHeightIntersection); + Cartesian3.subtract(cartesian, vectorToMinimumPoint, ray.origin); + } var intersection = tile.data.pick(ray, undefined, undefined, false, scratchGetHeightIntersection); if (!defined(intersection)) { diff --git a/Source/Scene/QuadtreePrimitive.js b/Source/Scene/QuadtreePrimitive.js index 2555401f7f42..e602e260404c 100644 --- a/Source/Scene/QuadtreePrimitive.js +++ b/Source/Scene/QuadtreePrimitive.js @@ -633,14 +633,41 @@ define([ if (mode === SceneMode.SCENE3D) { var surfaceNormal = ellipsoid.geodeticSurfaceNormal(data.position, scratchRay.direction); - // compute origin point, to account for a case where the terrain is under ellipsoid surface - var minimumHeight = Math.min(defaultValue(tile.data.minimumHeight, 0.0), 0.0); + // compute origin point + + // try to find the intersection point between the surface normal and z-axis. + // Ellipsoid is a surface of revolution, so surface normal intersects the rotation axis (z-axis) + + // compute the magnitude required to bring surface normal to x=0, y=0, from data.position + var magnitude; + + // avoid dividing by zero + if (Math.abs(surfaceNormal.x) > CesiumMath.EPSILON16){ + magnitude = data.position.x / surfaceNormal.x; + } else if (Math.abs(surfaceNormal.y) > CesiumMath.EPSILON16){ + magnitude = data.position.y / surfaceNormal.y; + } else if (Math.abs(surfaceNormal.z) > CesiumMath.EPSILON16){ //surface normal is (0,0,1) | (0,0,-1) | (0,0,0) + magnitude = data.position.z / surfaceNormal.z; + } else { //(0,0,0), just for case + magnitude = 0; + } + + var vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, magnitude, scratchPosition); + Cartesian3.subtract(data.position, vectorToMinimumPoint, scratchRay.origin); + + // Theoretically, the intersection point can be outside the ellipsoid, so we have to check if the result's 'z' is inside the ellipsoid (with some buffer) + if (Math.abs(scratchRay.origin.z) >= ellipsoid.radii.z -11500.0){ + // intersection point is outside the ellipsoid, try other value + magnitude = Math.min(defaultValue(tile.data.minimumHeight, 0.0),-11500.0); - // take into account the position height - minimumHeight -= data.positionCartographic.height; + // take into account the position height + magnitude -= data.positionCartographic.height; + + // multiply by the *positive* value of the magnitude + vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, Math.abs(magnitude) + 1, scratchPosition); + Cartesian3.subtract(data.position, vectorToMinimumPoint, scratchRay.origin); + } - var minimumHeightVector = Cartesian3.multiplyByScalar(surfaceNormal, minimumHeight - 1.0, scratchPosition); - Cartesian3.add(data.position, minimumHeightVector, scratchRay.origin); } else { Cartographic.clone(data.positionCartographic, scratchCartographic); From 4d12c0e09780163baa729abb98e0301a855e0d38 Mon Sep 17 00:00:00 2001 From: "duvi.fn" Date: Sun, 27 Nov 2016 16:08:32 +0200 Subject: [PATCH 04/19] add to CHANGES.md --- CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index d0d3c642ca21..1502c0be539b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,9 @@ Change Log ========== +* Fixed issue where billboards on terrain have some offset. [#4598](https://github.com/AnalyticalGraphicsInc/cesium/issues/4598) +* Fixed issue where `globe.getHeight` randomly returns 'undefined'. [#3411](https://github.com/AnalyticalGraphicsInc/cesium/issues/3411) + ### 1.27 - 2016-11-01 * Deprecated * Individual heading, pitch, and roll options to `Transforms.headingPitchRollToFixedFrame` and `Transforms.headingPitchRollQuaternion` have been deprecated and will be removed in 1.30. Pass the new `HeadingPitchRoll` object instead. [#4498](https://github.com/AnalyticalGraphicsInc/cesium/pull/4498) From 9f551ab85d9b675c5368fdd802d51940df944269 Mon Sep 17 00:00:00 2001 From: "duvi.fn" Date: Sun, 27 Nov 2016 16:21:03 +0200 Subject: [PATCH 05/19] typos --- Source/Scene/Globe.js | 4 ++-- Source/Scene/QuadtreePrimitive.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index 5490aeb2a36c..8389c9fa0c3f 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -436,10 +436,10 @@ define([ // compute origin point - // try to find the intersection point between the surface normal and z-axis. + // Try to find the intersection point between the surface normal and z-axis. // Ellipsoid is a surface of revolution, so surface normal intersects the rotation axis (z-axis) - // compute the magnitude required to bring surface normal to x=0, y=0, from data.position + // compute the magnitude required to bring surface normal to x=0, y=0, from cartesian var magnitude; // avoid dividing by zero diff --git a/Source/Scene/QuadtreePrimitive.js b/Source/Scene/QuadtreePrimitive.js index e602e260404c..ed78571563f0 100644 --- a/Source/Scene/QuadtreePrimitive.js +++ b/Source/Scene/QuadtreePrimitive.js @@ -635,7 +635,7 @@ define([ // compute origin point - // try to find the intersection point between the surface normal and z-axis. + // Try to find the intersection point between the surface normal and z-axis. // Ellipsoid is a surface of revolution, so surface normal intersects the rotation axis (z-axis) // compute the magnitude required to bring surface normal to x=0, y=0, from data.position From 74a7de59635826c1b5eefa6d258a01a82001e4d8 Mon Sep 17 00:00:00 2001 From: "duvi.fn" Date: Mon, 5 Dec 2016 12:21:02 +0200 Subject: [PATCH 06/19] cartesian is computed on the ellipsoid surface --- Source/Scene/Globe.js | 7 +++---- Source/Scene/QuadtreePrimitive.js | 24 +++++++++++------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index fd1ade9f8b39..5416ec721012 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -426,7 +426,9 @@ define([ } var ellipsoid = this._surface._tileProvider.tilingScheme.ellipsoid; - var cartesian = ellipsoid.cartographicToCartesian(cartographic, scratchGetHeightCartesian); + + //cartesian has to be on the ellipsoid surface for `ellipsoid.geodeticSurfaceNormal` + var cartesian = Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0, ellipsoid, scratchGetHeightCartesian); var ray = scratchGetHeightRay; var surfaceNormal = ellipsoid.geodeticSurfaceNormal(cartesian, ray.direction); @@ -458,9 +460,6 @@ define([ // intersection point is outside the ellipsoid, try other value magnitude = Math.min(defaultValue(tile.data.minimumHeight, 0.0),-11500.0); - // take into account the position height - magnitude -= cartographic.height; - // multiply by the *positive* value of the magnitude vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, Math.abs(magnitude) + 1, scratchGetHeightIntersection); Cartesian3.subtract(cartesian, vectorToMinimumPoint, ray.origin); diff --git a/Source/Scene/QuadtreePrimitive.js b/Source/Scene/QuadtreePrimitive.js index d9b21d574b24..07d572570f5a 100644 --- a/Source/Scene/QuadtreePrimitive.js +++ b/Source/Scene/QuadtreePrimitive.js @@ -240,7 +240,7 @@ define([ QuadtreePrimitive.prototype.updateHeight = function(cartographic, callback) { var primitive = this; var object = { - position : undefined, + positionOnEllipsoidSurface : undefined, positionCartographic : cartographic, level : -1, callback : callback @@ -455,7 +455,7 @@ define([ customDataRemoved.length = 0; } - // Our goal with load ordering is to first load all of the tiles we need to + // Our goal with load ordering is to first load all of the tiles we need to // render the current scene at full detail. Loading any other tiles is just // a form of prefetching, and we need not do it at all (other concerns aside). This // simple and obvious statement gets more complicated when we realize that, because @@ -761,12 +761,13 @@ define([ var data = customData[i]; if (tile.level > data.level) { - if (!defined(data.position)) { - data.position = ellipsoid.cartographicToCartesian(data.positionCartographic); + if (!defined(data.positionOnEllipsoidSurface)) { + // cartesian has to be on the ellipsoid surface for `ellipsoid.geodeticSurfaceNormal` + data.positionOnEllipsoidSurface = Cartesian3.fromRadians(data.positionCartographic.longitude, data.positionCartographic.latitude, 0.0, ellipsoid); } if (mode === SceneMode.SCENE3D) { - var surfaceNormal = ellipsoid.geodeticSurfaceNormal(data.position, scratchRay.direction); + var surfaceNormal = ellipsoid.geodeticSurfaceNormal(data.positionOnEllipsoidSurface, scratchRay.direction); // compute origin point @@ -778,29 +779,26 @@ define([ // avoid dividing by zero if (Math.abs(surfaceNormal.x) > CesiumMath.EPSILON16){ - magnitude = data.position.x / surfaceNormal.x; + magnitude = data.positionOnEllipsoidSurface.x / surfaceNormal.x; } else if (Math.abs(surfaceNormal.y) > CesiumMath.EPSILON16){ - magnitude = data.position.y / surfaceNormal.y; + magnitude = data.positionOnEllipsoidSurface.y / surfaceNormal.y; } else if (Math.abs(surfaceNormal.z) > CesiumMath.EPSILON16){ //surface normal is (0,0,1) | (0,0,-1) | (0,0,0) - magnitude = data.position.z / surfaceNormal.z; + magnitude = data.positionOnEllipsoidSurface.z / surfaceNormal.z; } else { //(0,0,0), just for case magnitude = 0; } var vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, magnitude, scratchPosition); - Cartesian3.subtract(data.position, vectorToMinimumPoint, scratchRay.origin); + Cartesian3.subtract(data.positionOnEllipsoidSurface, vectorToMinimumPoint, scratchRay.origin); // Theoretically, the intersection point can be outside the ellipsoid, so we have to check if the result's 'z' is inside the ellipsoid (with some buffer) if (Math.abs(scratchRay.origin.z) >= ellipsoid.radii.z -11500.0){ // intersection point is outside the ellipsoid, try other value magnitude = Math.min(defaultValue(tile.data.minimumHeight, 0.0),-11500.0); - // take into account the position height - magnitude -= data.positionCartographic.height; - // multiply by the *positive* value of the magnitude vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, Math.abs(magnitude) + 1, scratchPosition); - Cartesian3.subtract(data.position, vectorToMinimumPoint, scratchRay.origin); + Cartesian3.subtract(data.positionOnEllipsoidSurface, vectorToMinimumPoint, scratchRay.origin); } } else { From 30e73ff1ef9f404b086aa53187a037ae949274eb Mon Sep 17 00:00:00 2001 From: "duvi.fn" Date: Mon, 5 Dec 2016 13:18:28 +0200 Subject: [PATCH 07/19] fix typo --- CHANGES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index ffc6059001a3..14a9ec3f4c56 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,7 +1,7 @@ Change Log ========== -* Fixed issue where billboards on terrain have some offset. [#4598](https://github.com/AnalyticalGraphicsInc/cesium/issues/4598) -* Fixed issue where `globe.getHeight` randomly returns 'undefined'. [#3411](https://github.com/AnalyticalGraphicsInc/cesium/issues/3411) +* Fixed issue where billboards on terrain had some offset. [#4598](https://github.com/AnalyticalGraphicsInc/cesium/issues/4598) +* Fixed issue where `globe.getHeight` randomly returned 'undefined'. [#3411](https://github.com/AnalyticalGraphicsInc/cesium/issues/3411) ### 1.28 - 2016-12-01 From 7894d20cc736c08285f335ca36021498726c5f5d Mon Sep 17 00:00:00 2001 From: "duvi.fn" Date: Wed, 7 Dec 2016 11:49:36 +0200 Subject: [PATCH 08/19] added Ellipsoid.getSurfaceNormalRayFromZAxis. no tested --- Source/Core/Ellipsoid.js | 64 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/Source/Core/Ellipsoid.js b/Source/Core/Ellipsoid.js index 5428122a9ef0..cd8f29868a0c 100644 --- a/Source/Core/Ellipsoid.js +++ b/Source/Core/Ellipsoid.js @@ -8,6 +8,7 @@ define([ './DeveloperError', './freezeObject', './Math', + './Ray', './scaleToGeodeticSurface' ], function( Cartesian3, @@ -18,6 +19,7 @@ define([ DeveloperError, freezeObject, CesiumMath, + Ray, scaleToGeodeticSurface) { 'use strict'; @@ -608,5 +610,67 @@ define([ return this._radii.toString(); }; + var vectorToZAxisScratch = new Cartesian3(); + /** + * Computes a ray which its direction is the geodetic surface normal at a position and its + * origin is the intersection of this normal with the z-axis. + * + * There is no guarantee that the result would be inside the ellipsoid. + * + * @param {Cartesian3} position the position *on the surface of the ellipsoid* + * @param {Ellipsoid} [ellipsoid = Ellipsoid.WGS84] The ellipsoid for which to compute this ray + * @param {Ray} [result] The cartesian to which to copy the result, or undefined to create and + * return a new instance. + * @returns {Ray} the ray + * + * @exception {DeveloperError} position is required. + * @exception {DeveloperError} Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y). + * @exception {DeveloperError} Result is not on the z-axis. Please ensure that your input data is valid. + */ + Ellipsoid.prototype.getSurfaceNormalRayFromZAxis = function(position, ellipsoid, result) { + //>>includeStart('debug', pragmas.debug); + if (!defined(position)) { + throw new DeveloperError('position is required.'); + } + if (defined(ellipsoid) && !CesiumMath.equalsEpsilon(ellipsoid.radii.x, ellipsoid.radii.y, CesiumMath.EPSILON15)) { + throw new DeveloperError('Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y)'); + } + //>>includeEnd('debug'); + + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + + if (!defined(result)){ + result = new Ray(); + } + + var surfaceNormal = ellipsoid.geodeticSurfaceNormal(position, result.direction); + + // compute the magnitude required to bring surface normal to x=0, y=0, from position + var magnitude; + + // avoid dividing by zero + if (Math.abs(surfaceNormal.x) > CesiumMath.EPSILON16){ + magnitude = cartesian.x / surfaceNormal.x; + } else if (Math.abs(surfaceNormal.y) > CesiumMath.EPSILON16){ + magnitude = cartesian.y / surfaceNormal.y; + } else if (Math.abs(surfaceNormal.z) > CesiumMath.EPSILON16){ //surface normal is (0,0,1) | (0,0,-1) | (0,0,0) + magnitude = cartesian.z / surfaceNormal.z; + } else { //(0,0,0), just in case + magnitude = 0; + } + + var vectorToZAxis = Cartesian3.multiplyByScalar(surfaceNormal, magnitude, vectorToZAxisScratch); + Cartesian3.subtract(position, vectorToZAxis, result.origin); + + //>>includeStart('debug', pragmas.debug); + // sub millimeter accuracy + if (Math.abs(result.origin.x > CesiumMath.EPSILON4) || Math.abs(result.origin.y > CesiumMath.EPSILON4)){ + throw new DeveloperError('Result is not on the z-axis. Please ensure that your input data is valid.'); + } + //>>includeEnd('debug'); + + return result; + }; + return Ellipsoid; }); From edfd68543db0bbc68c7c317273ba481fad506e75 Mon Sep 17 00:00:00 2001 From: "duvi.fn" Date: Mon, 12 Dec 2016 17:23:47 +0200 Subject: [PATCH 09/19] fix Ellipsoid.getSurfaceNormalIntersectionWithZAxis change Globe.js and QuadtreePrimitive.js to work with Ellipsoid.getSurfaceNormalIntersectionWithZAxis add tests --- Source/Core/Ellipsoid.js | 62 +++++++++-------------- Source/Scene/Globe.js | 30 +++-------- Source/Scene/QuadtreePrimitive.js | 29 +++-------- Specs/Core/EllipsoidSpec.js | 82 +++++++++++++++++++++++++++++++ 4 files changed, 120 insertions(+), 83 deletions(-) diff --git a/Source/Core/Ellipsoid.js b/Source/Core/Ellipsoid.js index cd8f29868a0c..9e14e396e6e6 100644 --- a/Source/Core/Ellipsoid.js +++ b/Source/Core/Ellipsoid.js @@ -610,64 +610,50 @@ define([ return this._radii.toString(); }; - var vectorToZAxisScratch = new Cartesian3(); /** - * Computes a ray which its direction is the geodetic surface normal at a position and its - * origin is the intersection of this normal with the z-axis. - * - * There is no guarantee that the result would be inside the ellipsoid. - * - * @param {Cartesian3} position the position *on the surface of the ellipsoid* - * @param {Ellipsoid} [ellipsoid = Ellipsoid.WGS84] The ellipsoid for which to compute this ray - * @param {Ray} [result] The cartesian to which to copy the result, or undefined to create and + * Computes a point which is the intersection of the surface normal with the z-axis. + * + * @param {Cartesian3} position the position. must be on the surface of the ellipsoid. + * @param {Number} [buffer = 0.0] A buffer to subtract from the ellipsoid size when checking if the point is inside the ellipsoid. + * In earth case, with common earth datums, there is no need for this buffer since the intersection point is always (relatively) very close to the center. + * In WGS84 datum, intersection point is at max z = +-42841.31151331382 (0.673% of z-axis). + * Intersection point could be outside the ellipsoid if the ratio of MajorAxis / MinorAxis is bigger than the square root of 2 + * @param {Cartesian} [result] The cartesian to which to copy the result, or undefined to create and * return a new instance. - * @returns {Ray} the ray + * @returns {Cartesian | undefined} the intersection point if it's inside the ellipsoid, undefined otherwise * * @exception {DeveloperError} position is required. * @exception {DeveloperError} Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y). - * @exception {DeveloperError} Result is not on the z-axis. Please ensure that your input data is valid. */ - Ellipsoid.prototype.getSurfaceNormalRayFromZAxis = function(position, ellipsoid, result) { + + Ellipsoid.prototype.getSurfaceNormalIntersectionWithZAxis = function(position, buffer, result) { + + var ellipsoid = this; + //>>includeStart('debug', pragmas.debug); if (!defined(position)) { throw new DeveloperError('position is required.'); } - if (defined(ellipsoid) && !CesiumMath.equalsEpsilon(ellipsoid.radii.x, ellipsoid.radii.y, CesiumMath.EPSILON15)) { + if (!CesiumMath.equalsEpsilon(ellipsoid.radii.x, ellipsoid.radii.y, CesiumMath.EPSILON15)) { throw new DeveloperError('Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y)'); } //>>includeEnd('debug'); - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + buffer = defaultValue(buffer, 0.0); + + var sqauredAOverSquaredB = ellipsoid.radiiSquared.x / ellipsoid.radiiSquared.z; if (!defined(result)){ - result = new Ray(); + result = new Cartesian3(); } - var surfaceNormal = ellipsoid.geodeticSurfaceNormal(position, result.direction); - - // compute the magnitude required to bring surface normal to x=0, y=0, from position - var magnitude; - - // avoid dividing by zero - if (Math.abs(surfaceNormal.x) > CesiumMath.EPSILON16){ - magnitude = cartesian.x / surfaceNormal.x; - } else if (Math.abs(surfaceNormal.y) > CesiumMath.EPSILON16){ - magnitude = cartesian.y / surfaceNormal.y; - } else if (Math.abs(surfaceNormal.z) > CesiumMath.EPSILON16){ //surface normal is (0,0,1) | (0,0,-1) | (0,0,0) - magnitude = cartesian.z / surfaceNormal.z; - } else { //(0,0,0), just in case - magnitude = 0; + result.x = 0; + result.y = 0; + result.z = position.z * (1 - sqauredAOverSquaredB); + if (Math.abs(result.z) >= ellipsoid.radii.z - buffer){ + return undefined; } - var vectorToZAxis = Cartesian3.multiplyByScalar(surfaceNormal, magnitude, vectorToZAxisScratch); - Cartesian3.subtract(position, vectorToZAxis, result.origin); - - //>>includeStart('debug', pragmas.debug); - // sub millimeter accuracy - if (Math.abs(result.origin.x > CesiumMath.EPSILON4) || Math.abs(result.origin.y > CesiumMath.EPSILON4)){ - throw new DeveloperError('Result is not on the z-axis. Please ensure that your input data is valid.'); - } - //>>includeEnd('debug'); return result; }; diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index 5416ec721012..2c7e1ec18a78 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -433,35 +433,19 @@ define([ var ray = scratchGetHeightRay; var surfaceNormal = ellipsoid.geodeticSurfaceNormal(cartesian, ray.direction); - // compute origin point - // Try to find the intersection point between the surface normal and z-axis. - // Ellipsoid is a surface of revolution, so surface normal intersects the rotation axis (z-axis) - - // compute the magnitude required to bring surface normal to x=0, y=0, from cartesian - var magnitude; - - // avoid dividing by zero - if (Math.abs(surfaceNormal.x) > CesiumMath.EPSILON16){ - magnitude = cartesian.x / surfaceNormal.x; - } else if (Math.abs(surfaceNormal.y) > CesiumMath.EPSILON16){ - magnitude = cartesian.y / surfaceNormal.y; - } else if (Math.abs(surfaceNormal.z) > CesiumMath.EPSILON16){ //surface normal is (0,0,1) | (0,0,-1) | (0,0,0) - magnitude = cartesian.z / surfaceNormal.z; - } else { //(0,0,0), just for case - magnitude = 0; - } + // minimum height (-11500.0) for the terrain set, need to get this information from the terrain provider + var rayOrigin = ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesian, 11500.0, ray.origin); - var vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, magnitude, scratchGetHeightIntersection); - Cartesian3.subtract(cartesian, vectorToMinimumPoint, ray.origin); - // Theoretically, the intersection point can be outside the ellipsoid, so we have to check if the result's 'z' is inside the ellipsoid (with some buffer) - if (Math.abs(ray.origin.z) >= ellipsoid.radii.z -11500.0){ + // Theoretically, not with Earth datums, the intersection point can be outside the ellipsoid + if (!defined(rayOrigin)){ // intersection point is outside the ellipsoid, try other value - magnitude = Math.min(defaultValue(tile.data.minimumHeight, 0.0),-11500.0); + // minimum height (-11500.0) for the terrain set, need to get this information from the terrain provider + var magnitude = Math.min(defaultValue(tile.data.minimumHeight, 0.0),-11500.0); // multiply by the *positive* value of the magnitude - vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, Math.abs(magnitude) + 1, scratchGetHeightIntersection); + var vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, Math.abs(magnitude) + 1, scratchGetHeightIntersection); Cartesian3.subtract(cartesian, vectorToMinimumPoint, ray.origin); } diff --git a/Source/Scene/QuadtreePrimitive.js b/Source/Scene/QuadtreePrimitive.js index 07d572570f5a..cb48a48878d5 100644 --- a/Source/Scene/QuadtreePrimitive.js +++ b/Source/Scene/QuadtreePrimitive.js @@ -772,32 +772,17 @@ define([ // compute origin point // Try to find the intersection point between the surface normal and z-axis. - // Ellipsoid is a surface of revolution, so surface normal intersects the rotation axis (z-axis) - - // compute the magnitude required to bring surface normal to x=0, y=0, from data.position - var magnitude; - - // avoid dividing by zero - if (Math.abs(surfaceNormal.x) > CesiumMath.EPSILON16){ - magnitude = data.positionOnEllipsoidSurface.x / surfaceNormal.x; - } else if (Math.abs(surfaceNormal.y) > CesiumMath.EPSILON16){ - magnitude = data.positionOnEllipsoidSurface.y / surfaceNormal.y; - } else if (Math.abs(surfaceNormal.z) > CesiumMath.EPSILON16){ //surface normal is (0,0,1) | (0,0,-1) | (0,0,0) - magnitude = data.positionOnEllipsoidSurface.z / surfaceNormal.z; - } else { //(0,0,0), just for case - magnitude = 0; - } - - var vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, magnitude, scratchPosition); - Cartesian3.subtract(data.positionOnEllipsoidSurface, vectorToMinimumPoint, scratchRay.origin); + // minimum height (-11500.0) for the terrain set, need to get this information from the terrain provider + var rayOrigin = ellipsoid.getSurfaceNormalIntersectionWithZAxis(data.positionOnEllipsoidSurface, 11500.0, scratchRay.origin); - // Theoretically, the intersection point can be outside the ellipsoid, so we have to check if the result's 'z' is inside the ellipsoid (with some buffer) - if (Math.abs(scratchRay.origin.z) >= ellipsoid.radii.z -11500.0){ + // Theoretically, not with Earth datums, the intersection point can be outside the ellipsoid + if (!defined(rayOrigin)){ // intersection point is outside the ellipsoid, try other value - magnitude = Math.min(defaultValue(tile.data.minimumHeight, 0.0),-11500.0); + // minimum height (-11500.0) for the terrain set, need to get this information from the terrain provider + var magnitude = Math.min(defaultValue(tile.data.minimumHeight, 0.0),-11500.0); // multiply by the *positive* value of the magnitude - vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, Math.abs(magnitude) + 1, scratchPosition); + var vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, Math.abs(magnitude) + 1, scratchPosition); Cartesian3.subtract(data.positionOnEllipsoidSurface, vectorToMinimumPoint, scratchRay.origin); } diff --git a/Specs/Core/EllipsoidSpec.js b/Specs/Core/EllipsoidSpec.js index d4dfa16d1092..d09cef50cd19 100644 --- a/Specs/Core/EllipsoidSpec.js +++ b/Specs/Core/EllipsoidSpec.js @@ -434,5 +434,87 @@ defineSuite([ expect(cloned).toEqual(myEllipsoid); }); + it('getSurfaceNormalIntersectionWithZAxis throws with no position', function() { + expect(function() { + Ellipsoid.WGS84.getSurfaceNormalIntersectionWithZAxis(undefined); + }).toThrowDeveloperError(); + }); + + it('getSurfaceNormalIntersectionWithZAxis throws if the ellipsoid is no ellipsoid of revolution', function() { + expect(function() { + var ellipsoid = new Ellipsoid(1,2,3); + var cartesian = new Cartesian3(); + ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesian); + }).toThrowDeveloperError(); + }); + + it('getSurfaceNormalIntersectionWithZAxis works without a result parameter', function() { + var ellipsoid = Ellipsoid.WGS84; + var cartographic = Cartographic.fromDegrees(35.23,33.23); + var cartesianOnTheSurface = ellipsoid.cartographicToCartesian(cartographic); + var returnedResult = ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesianOnTheSurface); + expect(returnedResult instanceof Cartesian3).toBe(true); + }); + + it('getSurfaceNormalIntersectionWithZAxis works with a result parameter', function() { + var ellipsoid = Ellipsoid.WGS84; + var cartographic = Cartographic.fromDegrees(35.23,33.23); + var cartesianOnTheSurface = ellipsoid.cartographicToCartesian(cartographic); + var returnedResult = ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesianOnTheSurface, undefined , cartesianOnTheSurface); + expect(returnedResult).toBe(cartesianOnTheSurface); + }); + + it('getSurfaceNormalIntersectionWithZAxis returns undefined if the result is outside the ellipsoid with buffer parameter', function() { + var ellipsoid = Ellipsoid.WGS84; + var cartographic = Cartographic.fromDegrees(35.23,33.23); + var cartesianOnTheSurface = ellipsoid.cartographicToCartesian(cartographic); + var returnedResult = ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesianOnTheSurface, ellipsoid.radii.z); + expect(returnedResult).toBe(undefined); + }); + + it('getSurfaceNormalIntersectionWithZAxis returns undefined if the result is outside the ellipsoid without buffer parameter', function() { + var majorAxis = 10; + var minorAxis = 1; + var ellipsoid = new Ellipsoid(majorAxis,majorAxis,minorAxis); + var cartographic = Cartographic.fromDegrees(45.0,90.0); + var cartesianOnTheSurface = ellipsoid.cartographicToCartesian(cartographic); + var returnedResult = ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesianOnTheSurface, undefined); + expect(returnedResult).toBe(undefined); + }); + + it('getSurfaceNormalIntersectionWithZAxis returns a result that is equal to the value which computed in a different way', function() { + var ellipsoid = Ellipsoid.WGS84; + var cartographic = Cartographic.fromDegrees(35.23,33.23); + var cartesianOnTheSurface = ellipsoid.cartographicToCartesian(cartographic); + var surfaceNormal = ellipsoid.geodeticSurfaceNormal(cartesianOnTheSurface); + var magnitude = cartesianOnTheSurface.x / surfaceNormal.x; + + var expected = new Cartesian3(); + expected.z = cartesianOnTheSurface.z - surfaceNormal.z * magnitude; + var result = ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesianOnTheSurface, undefined); + expect(result).toEqualEpsilon(expected, CesiumMath.EPSILON8); + + // at the equator + cartesianOnTheSurface = new Cartesian3(ellipsoid.radii.x, 0 , 0); + result = ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesianOnTheSurface, undefined); + expect(result).toEqualEpsilon(Cartesian3.ZERO, CesiumMath.EPSILON8); + }); + + it('getSurfaceNormalIntersectionWithZAxis returns a result that when a it\'s used as origin to a vector with the surface normal direction it produces an accurate cartographic', function() { + var ellipsoid = Ellipsoid.WGS84; + var cartographic = Cartographic.fromDegrees(35.23,33.23); + var cartesianOnTheSurface = ellipsoid.cartographicToCartesian(cartographic); + var surfaceNormal = ellipsoid.geodeticSurfaceNormal(cartesianOnTheSurface); + + var result = ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesianOnTheSurface, undefined); + + var surfaceNormalWithLength = Cartesian3.multiplyByScalar(surfaceNormal, ellipsoid.maximumRadius, new Cartesian3()); + var position = Cartesian3.add(result,surfaceNormalWithLength,new Cartesian3()); + var resultCartographic = ellipsoid.cartesianToCartographic(position); + resultCartographic.height = 0.0; + expect(resultCartographic).toEqualEpsilon(cartographic, CesiumMath.EPSILON8); + + }); + createPackableSpecs(Ellipsoid, Ellipsoid.WGS84, [Ellipsoid.WGS84.radii.x, Ellipsoid.WGS84.radii.y, Ellipsoid.WGS84.radii.z]); }); From 23d2fea036f4db558e3158b38ae8560040204595 Mon Sep 17 00:00:00 2001 From: "duvi.fn" Date: Tue, 13 Dec 2016 11:05:50 +0200 Subject: [PATCH 10/19] factor out sqauredAOverSquaredB --- Source/Core/Ellipsoid.js | 4 +++- Specs/Core/EllipsoidSpec.js | 23 +++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Source/Core/Ellipsoid.js b/Source/Core/Ellipsoid.js index 9e14e396e6e6..c4f1db8eb2c5 100644 --- a/Source/Core/Ellipsoid.js +++ b/Source/Core/Ellipsoid.js @@ -57,6 +57,8 @@ define([ ellipsoid._maximumRadius = Math.max(x, y, z); ellipsoid._centerToleranceSquared = CesiumMath.EPSILON1; + + ellipsoid._sqauredAOverSquaredB = ellipsoid.radiiSquared.x / ellipsoid.radiiSquared.z; } /** @@ -641,7 +643,7 @@ define([ buffer = defaultValue(buffer, 0.0); - var sqauredAOverSquaredB = ellipsoid.radiiSquared.x / ellipsoid.radiiSquared.z; + var sqauredAOverSquaredB = ellipsoid._sqauredAOverSquaredB; if (!defined(result)){ result = new Cartesian3(); diff --git a/Specs/Core/EllipsoidSpec.js b/Specs/Core/EllipsoidSpec.js index d09cef50cd19..9c525c4c8a82 100644 --- a/Specs/Core/EllipsoidSpec.js +++ b/Specs/Core/EllipsoidSpec.js @@ -482,7 +482,7 @@ defineSuite([ expect(returnedResult).toBe(undefined); }); - it('getSurfaceNormalIntersectionWithZAxis returns a result that is equal to the value which computed in a different way', function() { + it('getSurfaceNormalIntersectionWithZAxis returns a result that is equal to a value that computed in a different way', function() { var ellipsoid = Ellipsoid.WGS84; var cartographic = Cartographic.fromDegrees(35.23,33.23); var cartesianOnTheSurface = ellipsoid.cartographicToCartesian(cartographic); @@ -498,9 +498,10 @@ defineSuite([ cartesianOnTheSurface = new Cartesian3(ellipsoid.radii.x, 0 , 0); result = ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesianOnTheSurface, undefined); expect(result).toEqualEpsilon(Cartesian3.ZERO, CesiumMath.EPSILON8); + }); - it('getSurfaceNormalIntersectionWithZAxis returns a result that when a it\'s used as origin to a vector with the surface normal direction it produces an accurate cartographic', function() { + it('getSurfaceNormalIntersectionWithZAxis returns a result that when a it\'s used as origin for a vector with the surface normal direction it produces an accurate cartographic', function() { var ellipsoid = Ellipsoid.WGS84; var cartographic = Cartographic.fromDegrees(35.23,33.23); var cartesianOnTheSurface = ellipsoid.cartographicToCartesian(cartographic); @@ -514,6 +515,24 @@ defineSuite([ resultCartographic.height = 0.0; expect(resultCartographic).toEqualEpsilon(cartographic, CesiumMath.EPSILON8); + // at the north pole + cartographic = Cartographic.fromDegrees(0,90); + cartesianOnTheSurface = new Cartesian3(0, 0 ,ellipsoid.radii.z); + surfaceNormal = ellipsoid.geodeticSurfaceNormal(cartesianOnTheSurface); + surfaceNormalWithLength = Cartesian3.multiplyByScalar(surfaceNormal, ellipsoid.maximumRadius, new Cartesian3()); + result = ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesianOnTheSurface, undefined); + position = Cartesian3.add(result,surfaceNormalWithLength,new Cartesian3()); + resultCartographic = ellipsoid.cartesianToCartographic(position); + resultCartographic.height = 0.0; + expect(resultCartographic).toEqualEpsilon(cartographic, CesiumMath.EPSILON8); + + }); + + it('ellipsoid is initialized with _sqauredAOverSquaredB property', function() { + var ellipsoid = new Ellipsoid(4 , 4 , 3); + + var squaredAOverB = ellipsoid.radiiSquared.x / ellipsoid.radiiSquared.z; + expect(ellipsoid._sqauredAOverSquaredB).toEqual(squaredAOverB); }); createPackableSpecs(Ellipsoid, Ellipsoid.WGS84, [Ellipsoid.WGS84.radii.x, Ellipsoid.WGS84.radii.y, Ellipsoid.WGS84.radii.z]); From dbd917dc9e34ac6aba112c77f25aa75b829c29d1 Mon Sep 17 00:00:00 2001 From: "duvi.fn" Date: Tue, 13 Dec 2016 11:16:45 +0200 Subject: [PATCH 11/19] add _sqauredAOverSquaredB to the Ellipsoid constructor --- Source/Core/Ellipsoid.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Core/Ellipsoid.js b/Source/Core/Ellipsoid.js index c4f1db8eb2c5..8f9ad3117a72 100644 --- a/Source/Core/Ellipsoid.js +++ b/Source/Core/Ellipsoid.js @@ -90,6 +90,7 @@ define([ this._minimumRadius = undefined; this._maximumRadius = undefined; this._centerToleranceSquared = undefined; + this._sqauredAOverSquaredB = undefined; initialize(this, x, y, z); } From 0947e12cb94cf52b8c5435ce5ba4a4eaf978a6d6 Mon Sep 17 00:00:00 2001 From: "duvi.fn" Date: Tue, 13 Dec 2016 11:53:06 +0200 Subject: [PATCH 12/19] add check if radii.z===0 --- Source/Core/Ellipsoid.js | 8 +++++++- Specs/Core/EllipsoidSpec.js | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Source/Core/Ellipsoid.js b/Source/Core/Ellipsoid.js index 8f9ad3117a72..bef67a517e6d 100644 --- a/Source/Core/Ellipsoid.js +++ b/Source/Core/Ellipsoid.js @@ -58,7 +58,9 @@ define([ ellipsoid._centerToleranceSquared = CesiumMath.EPSILON1; - ellipsoid._sqauredAOverSquaredB = ellipsoid.radiiSquared.x / ellipsoid.radiiSquared.z; + if (ellipsoid._radiiSquared.z !== 0){ + ellipsoid._sqauredAOverSquaredB = ellipsoid._radiiSquared.x / ellipsoid._radiiSquared.z; + } } /** @@ -627,6 +629,7 @@ define([ * * @exception {DeveloperError} position is required. * @exception {DeveloperError} Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y). + * @exception {DeveloperError} Ellipsoid.radii.z must be greater than 0. */ Ellipsoid.prototype.getSurfaceNormalIntersectionWithZAxis = function(position, buffer, result) { @@ -640,6 +643,9 @@ define([ if (!CesiumMath.equalsEpsilon(ellipsoid.radii.x, ellipsoid.radii.y, CesiumMath.EPSILON15)) { throw new DeveloperError('Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y)'); } + if (ellipsoid.radii.z === 0) { + throw new DeveloperError('Ellipsoid.radii.z must be greater than 0'); + } //>>includeEnd('debug'); buffer = defaultValue(buffer, 0.0); diff --git a/Specs/Core/EllipsoidSpec.js b/Specs/Core/EllipsoidSpec.js index 9c525c4c8a82..cc95635d46eb 100644 --- a/Specs/Core/EllipsoidSpec.js +++ b/Specs/Core/EllipsoidSpec.js @@ -448,6 +448,14 @@ defineSuite([ }).toThrowDeveloperError(); }); + it('getSurfaceNormalIntersectionWithZAxis throws if the ellipsoid has radii.z === 0', function() { + expect(function() { + var ellipsoid = new Ellipsoid(1,2,0); + var cartesian = new Cartesian3(); + ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesian); + }).toThrowDeveloperError(); + }); + it('getSurfaceNormalIntersectionWithZAxis works without a result parameter', function() { var ellipsoid = Ellipsoid.WGS84; var cartographic = Cartographic.fromDegrees(35.23,33.23); From 244cc523c9bc6cf71d56b574dd2254858d63b211 Mon Sep 17 00:00:00 2001 From: "duvi.fn" Date: Tue, 13 Dec 2016 22:26:14 +0200 Subject: [PATCH 13/19] remove unused dependency, change sqauredAOverSquaredB to sqauredXOverSquaredZ --- Source/Core/Ellipsoid.js | 20 ++++++++------------ Specs/Core/EllipsoidSpec.js | 6 +++--- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/Source/Core/Ellipsoid.js b/Source/Core/Ellipsoid.js index bef67a517e6d..1e91f1d78428 100644 --- a/Source/Core/Ellipsoid.js +++ b/Source/Core/Ellipsoid.js @@ -8,7 +8,6 @@ define([ './DeveloperError', './freezeObject', './Math', - './Ray', './scaleToGeodeticSurface' ], function( Cartesian3, @@ -19,7 +18,6 @@ define([ DeveloperError, freezeObject, CesiumMath, - Ray, scaleToGeodeticSurface) { 'use strict'; @@ -59,7 +57,7 @@ define([ ellipsoid._centerToleranceSquared = CesiumMath.EPSILON1; if (ellipsoid._radiiSquared.z !== 0){ - ellipsoid._sqauredAOverSquaredB = ellipsoid._radiiSquared.x / ellipsoid._radiiSquared.z; + ellipsoid._sqauredXOverSquaredZ = ellipsoid._radiiSquared.x / ellipsoid._radiiSquared.z; } } @@ -92,7 +90,7 @@ define([ this._minimumRadius = undefined; this._maximumRadius = undefined; this._centerToleranceSquared = undefined; - this._sqauredAOverSquaredB = undefined; + this._sqauredXOverSquaredZ = undefined; initialize(this, x, y, z); } @@ -622,7 +620,7 @@ define([ * @param {Number} [buffer = 0.0] A buffer to subtract from the ellipsoid size when checking if the point is inside the ellipsoid. * In earth case, with common earth datums, there is no need for this buffer since the intersection point is always (relatively) very close to the center. * In WGS84 datum, intersection point is at max z = +-42841.31151331382 (0.673% of z-axis). - * Intersection point could be outside the ellipsoid if the ratio of MajorAxis / MinorAxis is bigger than the square root of 2 + * Intersection point could be outside the ellipsoid if the ratio of MajorAxis / AxisOfRotation is bigger than the square root of 2 * @param {Cartesian} [result] The cartesian to which to copy the result, or undefined to create and * return a new instance. * @returns {Cartesian | undefined} the intersection point if it's inside the ellipsoid, undefined otherwise @@ -634,23 +632,21 @@ define([ Ellipsoid.prototype.getSurfaceNormalIntersectionWithZAxis = function(position, buffer, result) { - var ellipsoid = this; - //>>includeStart('debug', pragmas.debug); if (!defined(position)) { throw new DeveloperError('position is required.'); } - if (!CesiumMath.equalsEpsilon(ellipsoid.radii.x, ellipsoid.radii.y, CesiumMath.EPSILON15)) { + if (!CesiumMath.equalsEpsilon(this._radii.x, this._radii.y, CesiumMath.EPSILON15)) { throw new DeveloperError('Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y)'); } - if (ellipsoid.radii.z === 0) { + if (this._radii.z === 0) { throw new DeveloperError('Ellipsoid.radii.z must be greater than 0'); } //>>includeEnd('debug'); buffer = defaultValue(buffer, 0.0); - var sqauredAOverSquaredB = ellipsoid._sqauredAOverSquaredB; + var sqauredXOverSquaredZ = this._sqauredXOverSquaredZ; if (!defined(result)){ result = new Cartesian3(); @@ -658,8 +654,8 @@ define([ result.x = 0; result.y = 0; - result.z = position.z * (1 - sqauredAOverSquaredB); - if (Math.abs(result.z) >= ellipsoid.radii.z - buffer){ + result.z = position.z * (1 - sqauredXOverSquaredZ); + if (Math.abs(result.z) >= this._radii.z - buffer){ return undefined; } diff --git a/Specs/Core/EllipsoidSpec.js b/Specs/Core/EllipsoidSpec.js index cc95635d46eb..dea3c73a56de 100644 --- a/Specs/Core/EllipsoidSpec.js +++ b/Specs/Core/EllipsoidSpec.js @@ -536,11 +536,11 @@ defineSuite([ }); - it('ellipsoid is initialized with _sqauredAOverSquaredB property', function() { + it('ellipsoid is initialized with _sqauredXOverSquaredZ property', function() { var ellipsoid = new Ellipsoid(4 , 4 , 3); - var squaredAOverB = ellipsoid.radiiSquared.x / ellipsoid.radiiSquared.z; - expect(ellipsoid._sqauredAOverSquaredB).toEqual(squaredAOverB); + var sqauredXOverSquaredZ = ellipsoid.radiiSquared.x / ellipsoid.radiiSquared.z; + expect(ellipsoid._sqauredXOverSquaredZ).toEqual(sqauredXOverSquaredZ); }); createPackableSpecs(Ellipsoid, Ellipsoid.WGS84, [Ellipsoid.WGS84.radii.x, Ellipsoid.WGS84.radii.y, Ellipsoid.WGS84.radii.z]); From 9ae322c9f898dc91cd229bf9f962745c9e5df225 Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Sat, 24 Dec 2016 16:21:19 -0500 Subject: [PATCH 14/19] Whitespace --- Source/Core/Ellipsoid.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Source/Core/Ellipsoid.js b/Source/Core/Ellipsoid.js index 1e91f1d78428..c49cde15bb32 100644 --- a/Source/Core/Ellipsoid.js +++ b/Source/Core/Ellipsoid.js @@ -629,9 +629,7 @@ define([ * @exception {DeveloperError} Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y). * @exception {DeveloperError} Ellipsoid.radii.z must be greater than 0. */ - Ellipsoid.prototype.getSurfaceNormalIntersectionWithZAxis = function(position, buffer, result) { - //>>includeStart('debug', pragmas.debug); if (!defined(position)) { throw new DeveloperError('position is required.'); @@ -652,14 +650,14 @@ define([ result = new Cartesian3(); } - result.x = 0; - result.y = 0; + result.x = 0.0; + result.y = 0.0; result.z = position.z * (1 - sqauredXOverSquaredZ); + if (Math.abs(result.z) >= this._radii.z - buffer){ return undefined; } - return result; }; From 056fc20d914c89fe9746671774e422b99ba4155f Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Sat, 24 Dec 2016 16:21:50 -0500 Subject: [PATCH 15/19] Whitespace --- Source/Scene/Globe.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index 2c7e1ec18a78..807bb74563a1 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -437,7 +437,6 @@ define([ // minimum height (-11500.0) for the terrain set, need to get this information from the terrain provider var rayOrigin = ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesian, 11500.0, ray.origin); - // Theoretically, not with Earth datums, the intersection point can be outside the ellipsoid if (!defined(rayOrigin)){ // intersection point is outside the ellipsoid, try other value From b3943352cc0bec6ef7b1e593ab2a1fab68ca9786 Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Sat, 24 Dec 2016 16:22:47 -0500 Subject: [PATCH 16/19] Style tweak --- Source/Core/Ellipsoid.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Core/Ellipsoid.js b/Source/Core/Ellipsoid.js index c49cde15bb32..deca2629e1ae 100644 --- a/Source/Core/Ellipsoid.js +++ b/Source/Core/Ellipsoid.js @@ -56,7 +56,7 @@ define([ ellipsoid._centerToleranceSquared = CesiumMath.EPSILON1; - if (ellipsoid._radiiSquared.z !== 0){ + if (ellipsoid._radiiSquared.z !== 0) { ellipsoid._sqauredXOverSquaredZ = ellipsoid._radiiSquared.x / ellipsoid._radiiSquared.z; } } @@ -646,7 +646,7 @@ define([ var sqauredXOverSquaredZ = this._sqauredXOverSquaredZ; - if (!defined(result)){ + if (!defined(result)) { result = new Cartesian3(); } @@ -654,7 +654,7 @@ define([ result.y = 0.0; result.z = position.z * (1 - sqauredXOverSquaredZ); - if (Math.abs(result.z) >= this._radii.z - buffer){ + if (Math.abs(result.z) >= this._radii.z - buffer) { return undefined; } From 1f325e5bfc7f176103e4be56e71ee8ee3daee31b Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Sat, 24 Dec 2016 16:23:21 -0500 Subject: [PATCH 17/19] Style tweak --- Source/Scene/Globe.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index 807bb74563a1..bb92954ec673 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -438,7 +438,7 @@ define([ var rayOrigin = ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesian, 11500.0, ray.origin); // Theoretically, not with Earth datums, the intersection point can be outside the ellipsoid - if (!defined(rayOrigin)){ + if (!defined(rayOrigin)) { // intersection point is outside the ellipsoid, try other value // minimum height (-11500.0) for the terrain set, need to get this information from the terrain provider var magnitude = Math.min(defaultValue(tile.data.minimumHeight, 0.0),-11500.0); From 761eda4c6c81bffed11a06a702c69931f5e9c8ed Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Sat, 24 Dec 2016 16:23:54 -0500 Subject: [PATCH 18/19] Style tweak --- Source/Scene/QuadtreePrimitive.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/Scene/QuadtreePrimitive.js b/Source/Scene/QuadtreePrimitive.js index cb48a48878d5..9149b60359e4 100644 --- a/Source/Scene/QuadtreePrimitive.js +++ b/Source/Scene/QuadtreePrimitive.js @@ -776,7 +776,7 @@ define([ var rayOrigin = ellipsoid.getSurfaceNormalIntersectionWithZAxis(data.positionOnEllipsoidSurface, 11500.0, scratchRay.origin); // Theoretically, not with Earth datums, the intersection point can be outside the ellipsoid - if (!defined(rayOrigin)){ + if (!defined(rayOrigin)) { // intersection point is outside the ellipsoid, try other value // minimum height (-11500.0) for the terrain set, need to get this information from the terrain provider var magnitude = Math.min(defaultValue(tile.data.minimumHeight, 0.0),-11500.0); @@ -785,7 +785,6 @@ define([ var vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, Math.abs(magnitude) + 1, scratchPosition); Cartesian3.subtract(data.positionOnEllipsoidSurface, vectorToMinimumPoint, scratchRay.origin); } - } else { Cartographic.clone(data.positionCartographic, scratchCartographic); From d01196bb2fe0f9e0dfa76924c60093525f6ba486 Mon Sep 17 00:00:00 2001 From: "duvi.fn" Date: Mon, 26 Dec 2016 14:25:41 +0200 Subject: [PATCH 19/19] fix typo in spec title --- Specs/Core/EllipsoidSpec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Specs/Core/EllipsoidSpec.js b/Specs/Core/EllipsoidSpec.js index dea3c73a56de..944c388ebb21 100644 --- a/Specs/Core/EllipsoidSpec.js +++ b/Specs/Core/EllipsoidSpec.js @@ -440,7 +440,7 @@ defineSuite([ }).toThrowDeveloperError(); }); - it('getSurfaceNormalIntersectionWithZAxis throws if the ellipsoid is no ellipsoid of revolution', function() { + it('getSurfaceNormalIntersectionWithZAxis throws if the ellipsoid is not an ellipsoid of revolution', function() { expect(function() { var ellipsoid = new Ellipsoid(1,2,3); var cartesian = new Cartesian3(); @@ -509,7 +509,7 @@ defineSuite([ }); - it('getSurfaceNormalIntersectionWithZAxis returns a result that when a it\'s used as origin for a vector with the surface normal direction it produces an accurate cartographic', function() { + it('getSurfaceNormalIntersectionWithZAxis returns a result that when it\'s used as an origin for a vector with the surface normal direction it produces an accurate cartographic', function() { var ellipsoid = Ellipsoid.WGS84; var cartographic = Cartographic.fromDegrees(35.23,33.23); var cartesianOnTheSurface = ellipsoid.cartographicToCartesian(cartographic);