Skip to content

Commit

Permalink
Merge pull request #7520 from shehzan10/fix-rhumb-polygons-idl
Browse files Browse the repository at this point in the history
Fix polygons using rhumb lines across IDL
  • Loading branch information
likangning93 committed Jan 29, 2019
2 parents e18870a + 549b5cd commit 1f780d1
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 27 deletions.
46 changes: 23 additions & 23 deletions Source/Core/PolygonPipeline.js
Expand Up @@ -8,6 +8,7 @@ define([
'./defaultValue',
'./defined',
'./Ellipsoid',
'./EllipsoidRhumbLine',
'./Geometry',
'./GeometryAttribute',
'./Math',
Expand All @@ -23,6 +24,7 @@ define([
defaultValue,
defined,
Ellipsoid,
EllipsoidRhumbLine,
Geometry,
GeometryAttribute,
CesiumMath,
Expand Down Expand Up @@ -232,10 +234,7 @@ define([
var subdivisionC0Scratch = new Cartographic();
var subdivisionC1Scratch = new Cartographic();
var subdivisionC2Scratch = new Cartographic();
var subdivisionCart2Scratch0 = new Cartesian2();
var subdivisionCart2Scratch1 = new Cartesian2();
var subdivisionCart2Scratch2 = new Cartesian2();
var subdivisionMidCart2Scratch = new Cartesian2();
var subdivisionCartographicScratch = new Cartographic();

/**
* Subdivides positions on rhumb lines and raises points to the surface of the ellipsoid.
Expand Down Expand Up @@ -281,7 +280,12 @@ define([
// Used to make sure shared edges are not split more than once.
var edges = {};

var granularitySqrd = granularity * granularity;
var radius = ellipsoid.maximumRadius;
var minDistance = CesiumMath.chordLength(granularity, radius);

var rhumb0 = new EllipsoidRhumbLine(undefined, undefined, ellipsoid);
var rhumb1 = new EllipsoidRhumbLine(undefined, undefined, ellipsoid);
var rhumb2 = new EllipsoidRhumbLine(undefined, undefined, ellipsoid);

while (triangles.length > 0) {
var i2 = triangles.pop();
Expand All @@ -296,31 +300,29 @@ define([
var c1 = ellipsoid.cartesianToCartographic(v1, subdivisionC1Scratch);
var c2 = ellipsoid.cartesianToCartographic(v2, subdivisionC2Scratch);

var c0Cart2 = Cartesian2.fromElements(c0.longitude, c0.latitude, subdivisionCart2Scratch0);
var c1Cart2 = Cartesian2.fromElements(c1.longitude, c1.latitude, subdivisionCart2Scratch1);
var c2Cart2 = Cartesian2.fromElements(c2.longitude, c2.latitude, subdivisionCart2Scratch2);

var g0 = Cartesian2.distanceSquared(c0Cart2, c1Cart2);
var g1 = Cartesian2.distanceSquared(c1Cart2, c2Cart2);
var g2 = Cartesian2.distanceSquared(c2Cart2, c0Cart2);
rhumb0.setEndPoints(c0, c1);
var g0 = rhumb0.surfaceDistance;
rhumb1.setEndPoints(c1, c2);
var g1 = rhumb1.surfaceDistance;
rhumb2.setEndPoints(c2, c0);
var g2 = rhumb2.surfaceDistance;

var max = Math.max(g0, g1, g2);
var edge;
var mid;
var midHeight;
var midCartesian3;

// if the max length squared of a triangle edge is greater than squared granularity, subdivide the triangle
if (max > granularitySqrd) {
// if the max length squared of a triangle edge is greater than granularity, subdivide the triangle
if (max > minDistance) {
if (g0 === max) {
edge = Math.min(i0, i1) + ' ' + Math.max(i0, i1);

i = edges[edge];
if (!defined(i)) {
mid = Cartesian2.add(c0Cart2, c1Cart2, subdivisionMidCart2Scratch);
Cartesian2.multiplyByScalar(mid, 0.5, mid);
mid = rhumb0.interpolateUsingFraction(0.5, subdivisionCartographicScratch);
midHeight = (c0.height + c1.height) * 0.5;
midCartesian3 = Cartesian3.fromRadians(mid.x, mid.y, midHeight, ellipsoid, subdivisionMidScratch);
midCartesian3 = Cartesian3.fromRadians(mid.longitude, mid.latitude, midHeight, ellipsoid, subdivisionMidScratch);
subdividedPositions.push(midCartesian3.x, midCartesian3.y, midCartesian3.z);
i = subdividedPositions.length / 3 - 1;
edges[edge] = i;
Expand All @@ -333,10 +335,9 @@ define([

i = edges[edge];
if (!defined(i)) {
mid = Cartesian2.add(c1Cart2, c2Cart2, subdivisionMidCart2Scratch);
Cartesian2.multiplyByScalar(mid, 0.5, mid);
mid = rhumb1.interpolateUsingFraction(0.5, subdivisionCartographicScratch);
midHeight = (c1.height + c2.height) * 0.5;
midCartesian3 = Cartesian3.fromRadians(mid.x, mid.y, midHeight, ellipsoid, subdivisionMidScratch);
midCartesian3 = Cartesian3.fromRadians(mid.longitude, mid.latitude, midHeight, ellipsoid, subdivisionMidScratch);
subdividedPositions.push(midCartesian3.x, midCartesian3.y, midCartesian3.z);
i = subdividedPositions.length / 3 - 1;
edges[edge] = i;
Expand All @@ -349,10 +350,9 @@ define([

i = edges[edge];
if (!defined(i)) {
mid = Cartesian2.add(c2Cart2, c0Cart2, subdivisionMidCart2Scratch);
Cartesian2.multiplyByScalar(mid, 0.5, mid);
mid = rhumb2.interpolateUsingFraction(0.5, subdivisionCartographicScratch);
midHeight = (c2.height + c0.height) * 0.5;
midCartesian3 = Cartesian3.fromRadians(mid.x, mid.y, midHeight, ellipsoid, subdivisionMidScratch);
midCartesian3 = Cartesian3.fromRadians(mid.longitude, mid.latitude, midHeight, ellipsoid, subdivisionMidScratch);
subdividedPositions.push(midCartesian3.x, midCartesian3.y, midCartesian3.z);
i = subdividedPositions.length / 3 - 1;
edges[edge] = i;
Expand Down
4 changes: 2 additions & 2 deletions Specs/Core/PolygonGeometrySpec.js
Expand Up @@ -202,8 +202,8 @@ defineSuite([
arcType : ArcType.RHUMB
}));

expect(p.attributes.position.values.length).toEqual(13 * 3); // 8 around edge + 5 in the middle
expect(p.indices.length).toEqual(16 * 3); //4 squares * 4 triangles per square
expect(p.attributes.position.values.length).toEqual(15 * 3); // 8 around edge + 7 in the middle
expect(p.indices.length).toEqual(20 * 3); //5 squares * 4 triangles per square
});

it('create geometry throws if arcType is STRAIGHT', function() {
Expand Down
17 changes: 15 additions & 2 deletions Specs/Core/PolygonPipelineSpec.js
Expand Up @@ -265,7 +265,20 @@ defineSuite([
var indices = [0, 1, 2];
var subdivision = PolygonPipeline.computeRhumbLineSubdivision(Ellipsoid.WGS84, positions, indices, 0.5 * CesiumMath.RADIANS_PER_DEGREE);

expect(subdivision.attributes.position.values.length).toEqual(30); // 10 vertices
expect(subdivision.indices.length).toEqual(27); // 9 triangles
expect(subdivision.attributes.position.values.length).toEqual(36); // 12 vertices
expect(subdivision.indices.length).toEqual(36); // 12 triangles
});

it('computeRhumbLineSubdivision with subdivisions across the IDL', function() {
var positions = Cartesian3.fromDegreesArray([
178, 0,
-178, 0,
-178, 1
]);
var indices = [0, 1, 2];
var subdivision = PolygonPipeline.computeRhumbLineSubdivision(Ellipsoid.WGS84, positions, indices, 0.5 * CesiumMath.RADIANS_PER_DEGREE);

expect(subdivision.attributes.position.values.length).toEqual(180); // 60 vertices
expect(subdivision.indices.length).toEqual(252); // 84 triangles
});
});

0 comments on commit 1f780d1

Please sign in to comment.