-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrap Longitude #502
Wrap Longitude #502
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -355,5 +355,65 @@ define([ | |
return undefined; | ||
}; | ||
|
||
var lineSegmentPlaneDifference = new Cartesian3(); | ||
|
||
/** | ||
* Computes the intersection of a line segment and a plane. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not an @example? |
||
* @memberof IntersectionTests | ||
* | ||
* @param {Cartesian3} endPoint0 An end point of the line segment. | ||
* @param {Cartesian3} endPoint1 The other end point of the line segment. | ||
* @param {Cartesian3} planeNormal The plane normal. | ||
* @param {Number} planeD The distance from the plane to the origin. | ||
* @param {Cartesian3} [result] The object onto which to store the result. | ||
* @returns {Cartesian3} The intersection point or undefined if there is no intersection. | ||
* | ||
* @exception {DeveloperError} endPoint0 is required. | ||
* @exception {DeveloperError} endPoint1 is required. | ||
* @exception {DeveloperError} planeNormal is required. | ||
* @exception {DeveloperError} planeD is required. | ||
*/ | ||
IntersectionTests.lineSegmentPlane = function(endPoint0, endPoint1, planeNormal, planeD, result) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bummer, the Plane I added is still in a branch. No need to address it now. |
||
if (typeof endPoint0 === 'undefined') { | ||
throw new DeveloperError('endPoint0 is required.'); | ||
} | ||
|
||
if (typeof endPoint1 === 'undefined') { | ||
throw new DeveloperError('endPoint1 is required.'); | ||
} | ||
|
||
if (typeof planeNormal === 'undefined') { | ||
throw new DeveloperError('planeNormal is required.'); | ||
} | ||
|
||
if (typeof planeD === 'undefined') { | ||
throw new DeveloperError('planeD is required.'); | ||
} | ||
|
||
var difference = Cartesian3.subtract(endPoint1, endPoint0, lineSegmentPlaneDifference); | ||
var nDotDiff = Cartesian3.dot(planeNormal, difference); | ||
|
||
// check if the segment and plane are parallel | ||
if (Math.abs(nDotDiff) < CesiumMath.EPSILON6) { | ||
return undefined; | ||
} | ||
|
||
var nDotP0 = Cartesian3.dot(planeNormal, endPoint0); | ||
var t = -(planeD + nDotP0) / nDotDiff; | ||
|
||
// intersection only if t is in [0, 1] | ||
if (t < 0.0 || t > 1.0) { | ||
return undefined; | ||
} | ||
|
||
// intersection is endPoint0 + t * (endPoint1 - endPoint0) | ||
if (typeof result === 'undefined') { | ||
result = new Cartesian3(); | ||
} | ||
Cartesian3.multiplyByScalar(difference, t, result); | ||
Cartesian3.add(endPoint0, result, result); | ||
return result; | ||
}; | ||
|
||
return IntersectionTests; | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,89 +1,115 @@ | ||
/*global define*/ | ||
define(['./Cartographic', | ||
'./Cartesian3' | ||
define([ | ||
'./defaultValue', | ||
'./Cartesian3', | ||
'./Cartesian4', | ||
'./IntersectionTests', | ||
'./Matrix4' | ||
], function( | ||
Cartographic, | ||
Cartesian3) { | ||
defaultValue, | ||
Cartesian3, | ||
Cartesian4, | ||
IntersectionTests, | ||
Matrix4) { | ||
"use strict"; | ||
|
||
/** | ||
* DOC_TBA | ||
* | ||
* @exports PolylinePipeline | ||
*/ | ||
var PolylinePipeline = { | ||
/** | ||
* Breaks a {@link Polyline} into segments such that it does not cross the ±180 degree meridian of an ellipsoid. | ||
* | ||
* @param {Ellipsoid} ellipsoid The ellipsoid to wrap around. | ||
* @param {Array} positions The polyline's Cartesian positions. | ||
* | ||
* @returns An array of polyline segment objects containing the Cartesian and {@link Cartographic} positions and indices. | ||
* | ||
* @see Polyline | ||
* @see PolylineCollection | ||
* | ||
* @example | ||
* var polylines = new PolylineCollection(); | ||
* polylines.add(...); | ||
* var positions = polylines.get(0).getPositions(); | ||
* var segments = PolylinePipeline.wrapLongitude(ellipsoid, positions); | ||
*/ | ||
wrapLongitude : function(ellipsoid, positions) { | ||
var segments = []; | ||
|
||
if (positions && (positions.length > 0)) { | ||
var length = positions.length; | ||
|
||
var currentSegment = [{ | ||
cartesian : Cartesian3.clone(positions[0]), | ||
cartographic : ellipsoid.cartesianToCartographic(positions[0]), | ||
index : 0 | ||
}]; | ||
|
||
var prev = currentSegment[0].cartographic; | ||
|
||
for ( var i = 1; i < length; ++i) { | ||
var cur = ellipsoid.cartesianToCartographic(positions[i]); | ||
|
||
if (Math.abs(prev.longitude - cur.longitude) > Math.PI) { | ||
var interpolatedLongitude = prev.longitude < 0.0 ? -Math.PI : Math.PI; | ||
var longitude = cur.longitude + (2.0 * interpolatedLongitude); | ||
var ratio = (interpolatedLongitude - prev.longitude) / (longitude - prev.longitude); | ||
var interpolatedLatitude = prev.latitude + (cur.latitude - prev.latitude) * ratio; | ||
var interpolatedHeight = prev.height + (cur.height - prev.height) * ratio; | ||
var PolylinePipeline = {}; | ||
|
||
var wrapLongitudeInversMatrix = new Matrix4(); | ||
var wrapLongitudeOrigin = new Cartesian4(); | ||
var wrapLongitudeXZNormal = new Cartesian4(); | ||
var wrapLongitudeYZNormal = new Cartesian4(); | ||
var wrapLongitudeIntersection = new Cartesian3(); | ||
var wrapLongitudeOffset = new Cartesian3(); | ||
|
||
/** | ||
* Breaks a {@link Polyline} into segments such that it does not cross the ±180 degree meridian of an ellipsoid. | ||
* @memberof PolylinePipeline | ||
* | ||
* @param {Array} positions The polyline's Cartesian positions. | ||
* @param {Matrix4} [modelMatrix=Matrix4.IDENTITY] The polyline's model matrix. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Be more explicit about the form of the matrix, like the help for |
||
* | ||
* @returns An array of polyline segment objects containing the Cartesian position and indices. | ||
* | ||
* @see Polyline | ||
* @see PolylineCollection | ||
* | ||
* @example | ||
* var polylines = new PolylineCollection(); | ||
* polylines.add(...); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know you didn't write this (I probably did), but |
||
* var positions = polylines.get(0).getPositions(); | ||
* var modelMatrix = polylines.modelMatrix; | ||
* var segments = PolylinePipeline.wrapLongitude(positions, modelMatrix); | ||
*/ | ||
PolylinePipeline.wrapLongitude = function(positions, modelMatrix) { | ||
var segments = []; | ||
|
||
if (typeof positions !== 'undefined' && positions.length > 0) { | ||
modelMatrix = defaultValue(modelMatrix, Matrix4.IDENTITY); | ||
var inverseModelMatrix = Matrix4.inverseTransformation(modelMatrix, wrapLongitudeInversMatrix); | ||
|
||
var origin = Matrix4.multiplyByPoint(inverseModelMatrix, Cartesian3.ZERO, wrapLongitudeOrigin); | ||
var xzNormal = Matrix4.multiplyByVector(inverseModelMatrix, Cartesian4.UNIT_Y, wrapLongitudeXZNormal); | ||
var xzConstant = -Cartesian3.dot(xzNormal, origin); | ||
var yzNormal = Matrix4.multiplyByVector(inverseModelMatrix, Cartesian4.UNIT_X, wrapLongitudeYZNormal); | ||
var yzConstant = -Cartesian3.dot(yzNormal, origin); | ||
|
||
var currentSegment = [{ | ||
cartesian : Cartesian3.clone(positions[0]), | ||
index : 0 | ||
}]; | ||
var prev = currentSegment[0].cartesian; | ||
|
||
var length = positions.length; | ||
for ( var i = 1; i < length; ++i) { | ||
var cur = positions[i]; | ||
|
||
// intersects the IDL if either endpoint is on the negative side of the yz-plane | ||
if (Cartesian3.dot(prev, yzNormal) + yzConstant < 0.0 || Cartesian3.dot(cur, yzNormal) + yzNormal < 0.0) { | ||
// and intersects the xz-plane | ||
var intersection = IntersectionTests.lineSegmentPlane(prev, cur, xzNormal, xzConstant, wrapLongitudeIntersection); | ||
if (typeof intersection !== 'undefined') { | ||
// move point on the xz-plane slightly away from the plane | ||
var offset = Cartesian3.multiplyByScalar(xzNormal, 5.0e-9, wrapLongitudeOffset); | ||
if (Cartesian3.dot(prev, xzNormal) + xzConstant < 0.0) { | ||
Cartesian3.negate(offset, offset); | ||
} | ||
|
||
currentSegment.push({ | ||
cartesian : ellipsoid.cartographicToCartesian(new Cartographic(interpolatedLongitude, interpolatedLatitude, interpolatedHeight)), | ||
cartographic : new Cartographic(interpolatedLongitude, interpolatedLatitude, interpolatedHeight), | ||
cartesian : Cartesian3.add(intersection, offset), | ||
index : i | ||
}); | ||
segments.push(currentSegment); | ||
|
||
Cartesian3.negate(offset, offset); | ||
|
||
currentSegment = []; | ||
currentSegment.push({ | ||
cartesian : ellipsoid.cartographicToCartesian(new Cartographic(-interpolatedLongitude, interpolatedLatitude, interpolatedHeight)), | ||
cartographic : new Cartographic(-interpolatedLongitude, interpolatedLatitude, interpolatedHeight), | ||
cartesian : Cartesian3.add(intersection, offset), | ||
index : i | ||
}); | ||
} | ||
|
||
currentSegment.push({ | ||
cartesian : Cartesian3.clone(positions[i]), | ||
cartographic : ellipsoid.cartesianToCartographic(positions[i]), | ||
index : i | ||
}); | ||
|
||
prev = cur.clone(); | ||
} | ||
|
||
if (currentSegment.length > 1) { | ||
segments.push(currentSegment); | ||
} | ||
currentSegment.push({ | ||
cartesian : Cartesian3.clone(positions[i]), | ||
index : i | ||
}); | ||
|
||
prev = cur; | ||
} | ||
|
||
return segments; | ||
if (currentSegment.length > 1) { | ||
segments.push(currentSegment); | ||
} | ||
} | ||
|
||
return segments; | ||
}; | ||
|
||
return PolylinePipeline; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -361,8 +361,8 @@ define([ | |
return positions; | ||
}; | ||
|
||
Polyline.prototype._createSegments = function(ellipsoid) { | ||
return PolylinePipeline.wrapLongitude(ellipsoid, this.getPositions()); | ||
Polyline.prototype._createSegments = function(modelMatrix) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function is only one line now. Do we still need it? Actually, the whole segment management in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should wait until we start the material improvements. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeap, OK with me. |
||
return PolylinePipeline.wrapLongitude(this.getPositions(), modelMatrix); | ||
}; | ||
|
||
Polyline.prototype._setSegments = function(segments) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add these to b14