From 09d8c22d0dc2e2a93c06acd81d16cdfffb6668bb Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 13 Sep 2013 18:12:58 -0400 Subject: [PATCH] Fix ellipsoid tangent planes for ellipsoids other than the unit sphere. --- CHANGES.md | 1 + Source/Core/EllipsoidTangentPlane.js | 7 +++++-- Specs/Core/EllipsoidTangentPlaneSpec.js | 26 +++++++++++++++++++++++-- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 2a57b5ed080f..e4bae3f9b9dc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -36,6 +36,7 @@ if (defined(p) && defined(p.primitive)) { * Added `Scene.sunBloom` to enable/disable the bloom filter on the sun. The bloom filter should be disabled for better frame rates on mobile devices. * Fix geometries not closing completely. [#1093](https://github.com/AnalyticalGraphicsInc/cesium/issues/1093) * Improved graphics performance. For example, an Everest terrain view went from 135-140 to over 150 frames per second. +* Fix `EllipsoidTangentPlane.projectPointOntoPlane` for tangent planes on an ellipsoid other than the unit sphere. ### b20 - 2013-09-03 diff --git a/Source/Core/EllipsoidTangentPlane.js b/Source/Core/EllipsoidTangentPlane.js index 61c0160add33..4ef58323f9bf 100644 --- a/Source/Core/EllipsoidTangentPlane.js +++ b/Source/Core/EllipsoidTangentPlane.js @@ -56,8 +56,7 @@ define([ this._yAxis = Cartesian3.fromCartesian4(eastNorthUp.getColumn(1)); var normal = Cartesian3.fromCartesian4(eastNorthUp.getColumn(2)); - var distance = -Cartesian3.dot(origin, origin); //The shortest distance from the origin to the plane. - this._plane = new Plane(normal, distance); + this._plane = Plane.fromPointNormal(origin, normal); }; var tmp = new AxisAlignedBoundingBox(); @@ -119,6 +118,10 @@ define([ Cartesian3.normalize(cartesian, ray.direction); var intersectionPoint = IntersectionTests.rayPlane(ray, this._plane, projectPointOntoPlaneCartesian3); + if (!defined(intersectionPoint)) { + Cartesian3.negate(ray.direction, ray.direction); + intersectionPoint = IntersectionTests.rayPlane(ray, this._plane, projectPointOntoPlaneCartesian3); + } if (defined(intersectionPoint)) { var v = intersectionPoint.subtract(this._origin, intersectionPoint); diff --git a/Specs/Core/EllipsoidTangentPlaneSpec.js b/Specs/Core/EllipsoidTangentPlaneSpec.js index c02f356d90b5..b947c6f4caa5 100644 --- a/Specs/Core/EllipsoidTangentPlaneSpec.js +++ b/Specs/Core/EllipsoidTangentPlaneSpec.js @@ -3,12 +3,14 @@ defineSuite([ 'Core/EllipsoidTangentPlane', 'Core/Ellipsoid', 'Core/Cartesian2', - 'Core/Cartesian3' + 'Core/Cartesian3', + 'Core/Cartographic' ], function( EllipsoidTangentPlane, Ellipsoid, Cartesian2, - Cartesian3) { + Cartesian3, + Cartographic) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ @@ -167,4 +169,24 @@ defineSuite([ return tangentPlane.projectPointsOntoEllipsoid(undefined); }).toThrow(); }); + + it('projectPointsOntoEllipsoid works with an arbitrary ellipsoid using fromPoints', function () { + var ellipsoid = Ellipsoid.WGS84; + + var points = ellipsoid.cartographicArrayToCartesianArray([ + Cartographic.fromDegrees(-72.0, 40.0), + Cartographic.fromDegrees(-68.0, 35.0), + Cartographic.fromDegrees(-75.0, 30.0), + Cartographic.fromDegrees(-70.0, 30.0), + Cartographic.fromDegrees(-68.0, 40.0) + ]); + + var tangentPlane = EllipsoidTangentPlane.fromPoints(points, ellipsoid); + var points2D = tangentPlane.projectPointsOntoPlane(points); + var positionsBack = tangentPlane.projectPointsOntoEllipsoid(points2D); + + expect(positionsBack[0].x).toBeCloseTo(points[0].x); + expect(positionsBack[0].y).toBeCloseTo(points[0].y); + expect(positionsBack[0].z).toBeCloseTo(points[0].z); + }); });