diff --git a/Source/Core/PolygonPipeline.js b/Source/Core/PolygonPipeline.js index cd59af0c3530..fdbb8404a26c 100644 --- a/Source/Core/PolygonPipeline.js +++ b/Source/Core/PolygonPipeline.js @@ -8,6 +8,7 @@ define([ './defaultValue', './defined', './Ellipsoid', + './EllipsoidRhumbLine', './Geometry', './GeometryAttribute', './Math', @@ -23,6 +24,7 @@ define([ defaultValue, defined, Ellipsoid, + EllipsoidRhumbLine, Geometry, GeometryAttribute, CesiumMath, @@ -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. @@ -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(); @@ -296,13 +300,12 @@ 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; @@ -310,17 +313,16 @@ define([ 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; @@ -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; @@ -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; diff --git a/Specs/Core/PolygonGeometrySpec.js b/Specs/Core/PolygonGeometrySpec.js index 935473324227..dd59aab49846 100644 --- a/Specs/Core/PolygonGeometrySpec.js +++ b/Specs/Core/PolygonGeometrySpec.js @@ -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() { diff --git a/Specs/Core/PolygonPipelineSpec.js b/Specs/Core/PolygonPipelineSpec.js index cb343750e8ff..bd3bda0b53b0 100644 --- a/Specs/Core/PolygonPipelineSpec.js +++ b/Specs/Core/PolygonPipelineSpec.js @@ -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 }); });