Skip to content

Commit

Permalink
Merge pull request #6733 from AnalyticalGraphicsInc/geometry-compute-…
Browse files Browse the repository at this point in the history
…rectangle

Add static computeRectangle function to CorridorGeometry, EllipseGeometry, PolygonGeometry and RectangleGeometry
  • Loading branch information
mramato authored Jun 27, 2018
2 parents 0025abc + c72e8d4 commit be53c18
Show file tree
Hide file tree
Showing 10 changed files with 417 additions and 175 deletions.
54 changes: 35 additions & 19 deletions Source/Core/CorridorGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ define([
'./defaultValue',
'./defined',
'./defineProperties',
'./DeveloperError',
'./Ellipsoid',
'./Geometry',
'./GeometryAttribute',
Expand All @@ -36,7 +35,6 @@ define([
defaultValue,
defined,
defineProperties,
DeveloperError,
Ellipsoid,
Geometry,
GeometryAttribute,
Expand Down Expand Up @@ -725,7 +723,7 @@ define([
var scratchCartographicMin = new Cartographic();
var scratchCartographicMax = new Cartographic();

function computeRectangle(positions, ellipsoid, width, cornerType) {
function computeRectangle(positions, ellipsoid, width, cornerType, result) {
positions = scaleToSurface(positions, ellipsoid);
var cleanPositions = arrayRemoveDuplicates(positions, Cartesian3.equalsEpsilon);
var length = cleanPositions.length;
Expand Down Expand Up @@ -783,7 +781,7 @@ define([
scratchCartographicMax.longitude = Math.max(scratchCartographicMax.longitude, lon);
}

var rectangle = new Rectangle();
var rectangle = defined(result) ? result : new Rectangle();
rectangle.north = scratchCartographicMax.latitude;
rectangle.south = scratchCartographicMin.latitude;
rectangle.east = scratchCartographicMax.longitude;
Expand Down Expand Up @@ -826,12 +824,8 @@ define([
var width = options.width;

//>>includeStart('debug', pragmas.debug);
if (!defined(positions)) {
throw new DeveloperError('options.positions is required.');
}
if (!defined(width)) {
throw new DeveloperError('options.width is required.');
}
Check.defined('options.positions', positions);
Check.defined('options.width', width);
//>>includeEnd('debug');

var height = defaultValue(options.height, 0.0);
Expand Down Expand Up @@ -868,12 +862,8 @@ define([
*/
CorridorGeometry.pack = function(value, array, startingIndex) {
//>>includeStart('debug', pragmas.debug);
if (!defined(value)) {
throw new DeveloperError('value is required');
}
if (!defined(array)) {
throw new DeveloperError('array is required');
}
Check.defined('value', value);
Check.defined('array', array);
//>>includeEnd('debug');

startingIndex = defaultValue(startingIndex, 0);
Expand Down Expand Up @@ -928,9 +918,7 @@ define([
*/
CorridorGeometry.unpack = function(array, startingIndex, result) {
//>>includeStart('debug', pragmas.debug);
if (!defined(array)) {
throw new DeveloperError('array is required');
}
Check.defined('array', array);
//>>includeEnd('debug');

startingIndex = defaultValue(startingIndex, 0);
Expand Down Expand Up @@ -983,6 +971,34 @@ define([
return result;
};

/**
* Computes the bounding rectangle given the provided options
*
* @param {Object} options Object with the following properties:
* @param {Cartesian3[]} options.positions An array of positions that define the center of the corridor.
* @param {Number} options.width The distance between the edges of the corridor in meters.
* @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference.
* @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners.
* @param {Rectangle} [result] An object in which to store the result.
*
* @returns {Rectangle} The result rectangle.
*/
CorridorGeometry.computeRectangle = function(options, result) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
var positions = options.positions;
var width = options.width;

//>>includeStart('debug', pragmas.debug);
Check.defined('options.positions', positions);
Check.defined('options.width', width);
//>>includeEnd('debug');

var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84);
var cornerType = defaultValue(options.cornerType, CornerType.ROUNDED);

return computeRectangle(positions, ellipsoid, width, cornerType, result);
};

/**
* Computes the geometric representation of a corridor, including its vertices, indices, and a bounding sphere.
*
Expand Down
81 changes: 55 additions & 26 deletions Source/Core/EllipseGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ define([
'./Cartesian2',
'./Cartesian3',
'./Cartographic',
'./Check',
'./ComponentDatatype',
'./defaultValue',
'./defined',
Expand Down Expand Up @@ -31,6 +32,7 @@ define([
Cartesian2,
Cartesian3,
Cartographic,
Check,
ComponentDatatype,
defaultValue,
defined,
Expand Down Expand Up @@ -684,21 +686,21 @@ define([
};
}

function computeRectangle(ellipseGeometry) {
function computeRectangle(center, semiMajorAxis, semiMinorAxis, rotation, granularity, ellipsoid, result) {
var cep = EllipseGeometryLibrary.computeEllipsePositions({
center : ellipseGeometry._center,
semiMajorAxis : ellipseGeometry._semiMajorAxis,
semiMinorAxis : ellipseGeometry._semiMinorAxis,
rotation : ellipseGeometry._rotation,
granularity : ellipseGeometry._granularity
center : center,
semiMajorAxis : semiMajorAxis,
semiMinorAxis : semiMinorAxis,
rotation : rotation,
granularity : granularity
}, false, true);
var positionsFlat = cep.outerPositions;
var positionsCount = positionsFlat.length / 3;
var positions = new Array(positionsCount);
for (var i = 0; i < positionsCount; ++i) {
positions[i] = Cartesian3.fromArray(positionsFlat, i * 3);
}
var rectangle = Rectangle.fromCartesianArray(positions, ellipseGeometry._ellipsoid);
var rectangle = Rectangle.fromCartesianArray(positions, ellipsoid, result);
// Rectangle width goes beyond 180 degrees when the ellipse crosses a pole.
// When this happens, make the rectangle into a "circle" around the pole
if (rectangle.width > CesiumMath.PI) {
Expand Down Expand Up @@ -756,15 +758,9 @@ define([
var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT);

//>>includeStart('debug', pragmas.debug);
if (!defined(center)) {
throw new DeveloperError('center is required.');
}
if (!defined(semiMajorAxis)) {
throw new DeveloperError('semiMajorAxis is required.');
}
if (!defined(semiMinorAxis)) {
throw new DeveloperError('semiMinorAxis is required.');
}
Check.defined('options.center', center);
Check.typeOf.number('options.semiMajorAxis', semiMajorAxis);
Check.typeOf.number('options.semiMinorAxis', semiMinorAxis);
if (semiMajorAxis < semiMinorAxis) {
throw new DeveloperError('semiMajorAxis must be greater than or equal to the semiMinorAxis.');
}
Expand Down Expand Up @@ -811,12 +807,8 @@ define([
*/
EllipseGeometry.pack = function(value, array, startingIndex) {
//>>includeStart('debug', pragmas.debug);
if (!defined(value)) {
throw new DeveloperError('value is required');
}
if (!defined(array)) {
throw new DeveloperError('array is required');
}
Check.defined('value', value);
Check.defined('array', array);
//>>includeEnd('debug');

startingIndex = defaultValue(startingIndex, 0);
Expand Down Expand Up @@ -871,9 +863,7 @@ define([
*/
EllipseGeometry.unpack = function(array, startingIndex, result) {
//>>includeStart('debug', pragmas.debug);
if (!defined(array)) {
throw new DeveloperError('array is required');
}
Check.defined('array', array);
//>>includeEnd('debug');

startingIndex = defaultValue(startingIndex, 0);
Expand Down Expand Up @@ -927,6 +917,45 @@ define([
return result;
};

/**
* Computes the bounding rectangle based on the provided options
*
* @param {Object} options Object with the following properties:
* @param {Cartesian3} options.center The ellipse's center point in the fixed frame.
* @param {Number} options.semiMajorAxis The length of the ellipse's semi-major axis in meters.
* @param {Number} options.semiMinorAxis The length of the ellipse's semi-minor axis in meters.
* @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the ellipse will be on.
* @param {Number} [options.rotation=0.0] The angle of rotation counter-clockwise from north.
* @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The angular distance between points on the ellipse in radians.
* @param {Rectangle} [result] An object in which to store the result
*
* @returns {Rectangle} The result rectangle
*/
EllipseGeometry.computeRectangle = function(options, result) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);

var center = options.center;
var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84);
var semiMajorAxis = options.semiMajorAxis;
var semiMinorAxis = options.semiMinorAxis;
var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE);
var rotation = defaultValue(options.rotation, 0.0);

//>>includeStart('debug', pragmas.debug);
Check.defined('options.center', center);
Check.typeOf.number('options.semiMajorAxis', semiMajorAxis);
Check.typeOf.number('options.semiMinorAxis', semiMinorAxis);
if (semiMajorAxis < semiMinorAxis) {
throw new DeveloperError('semiMajorAxis must be greater than or equal to the semiMinorAxis.');
}
if (granularity <= 0.0) {
throw new DeveloperError('granularity must be greater than zero.');
}
//>>includeEnd('debug');

return computeRectangle(center, semiMajorAxis, semiMinorAxis, rotation, granularity, ellipsoid, result);
};

/**
* Computes the geometric representation of a ellipse on an ellipsoid, including its vertices, indices, and a bounding sphere.
*
Expand Down Expand Up @@ -1041,7 +1070,7 @@ define([
rectangle : {
get : function() {
if (!defined(this._rectangle)) {
this._rectangle = computeRectangle(this);
this._rectangle = computeRectangle(this._center, this._semiMajorAxis, this._semiMinorAxis, this._rotation, this._granularity, this._ellipsoid);
}
return this._rectangle;
}
Expand Down
42 changes: 37 additions & 5 deletions Source/Core/PolygonGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,20 @@ define([
return geometry;
}

function computeRectangle(positions, ellipsoid, result) {
if (!defined(positions) || positions.length < 3) {
if (!defined(result)) {
return new Rectangle();
}
result.west = 0.0;
result.north = 0.0;
result.south = 0.0;
result.east = 0.0;
return result;
}
return Rectangle.fromCartesianArray(positions, ellipsoid, result);
}

var createGeometryFromPositionsExtrudedPositions = [];

function createGeometryFromPositionsExtruded(ellipsoid, polygon, granularity, hierarchy, perPositionHeight, closeTop, closeBottom, vertexFormat) {
Expand Down Expand Up @@ -794,6 +808,28 @@ define([
return result;
};

/**
* Returns the bounding rectangle given the provided options
*
* @param {Object} options Object with the following properties:
* @param {PolygonHierarchy} options.polygonHierarchy A polygon hierarchy that can include holes.
* @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference.
* @param {Rectangle} [result] An object in which to store the result.
*
* @returns {Rectangle} The result rectangle
*/
PolygonGeometry.computeRectangle = function(options, result) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object('options', options);
Check.typeOf.object('options.polygonHierarchy', options.polygonHierarchy);
//>>includeEnd('debug');

var polygonHierarchy = options.polygonHierarchy;
var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84);

return computeRectangle(polygonHierarchy.positions, ellipsoid, result);
};

/**
* Computes the geometric representation of a polygon, including its vertices, indices, and a bounding sphere.
*
Expand Down Expand Up @@ -973,11 +1009,7 @@ define([
get : function() {
if (!defined(this._rectangle)) {
var positions = this._polygonHierarchy.positions;
if (!defined(positions) || positions.length < 3) {
this._rectangle = new Rectangle();
} else {
this._rectangle = Rectangle.fromCartesianArray(positions, this._ellipsoid);
}
this._rectangle = computeRectangle(positions, this._ellipsoid);
}

return this._rectangle;
Expand Down
Loading

0 comments on commit be53c18

Please sign in to comment.