cesium/packages/engine/Specs/Core/PolygonGeometryLibrarySpec.js

612 lines
20 KiB
JavaScript

import {
ArcType,
Cartesian3,
Ellipsoid,
Math as CesiumMath,
PolygonGeometryLibrary,
} from "../../index.js";
describe("Core/PolygonGeometryLibrary", function () {
describe("subdivideRhumbLine", () => {
it("returns first point if both points are the same", function () {
const p0 = new Cartesian3(3813220.0, -5085291.0, 527179.0);
const p1 = new Cartesian3(3813220.0, -5085291.0, 527179.0);
const positions = PolygonGeometryLibrary.subdivideRhumbLine(
Ellipsoid.WGS84,
p0,
p1,
2,
);
expect(positions.length).toEqual(3);
expect(positions).toEqual([3813220.0, -5085291.0, 527179.0]);
});
it("returns first point if the points are closer than minDistance", function () {
const p0 = new Cartesian3(3813220.0, -5085291.0, 527179.0);
const p1 = new Cartesian3(3813220.0, -5085291.0, 527179.0 + 1);
// actual surface distance is ~0.997
const positions = PolygonGeometryLibrary.subdivideRhumbLine(
Ellipsoid.WGS84,
p0,
p1,
2,
);
expect(positions.length).toEqual(3);
expect(positions).toEqual([3813220.0, -5085291.0, 527179.0]);
});
it("subdivides the line between 2 points", function () {
const p0 = new Cartesian3(3813220.0, -5085291.0, 527179.0);
const p1 = new Cartesian3(3813220.0, -5085291.0, 527179.0 + 5);
// actual surface distance is ~4.983
const positions = PolygonGeometryLibrary.subdivideRhumbLine(
Ellipsoid.WGS84,
p0,
p1,
2,
);
expect(positions.length).toEqual(12);
expect(positions).toEqualEpsilon(
[
3813220.447295841, -5085291.596511482, 527179.0622555692,
3813220.3851130935, -5085291.513584885, 527180.3036009098,
3813220.3229302, -5085291.430658091, 527181.5449462304,
3813220.2607471617, -5085291.347731101, 527182.7862915307,
],
CesiumMath.EPSILON7,
);
});
});
describe("splitPolygonsOnEquator", function () {
it("splits a simple polygon at the equator", function () {
const positions = Cartesian3.unpackArray([
3813220.0, -5085291.0, 527179.0, 3701301.0, -5097773.0, -993503.0,
5037375.0, -3776794.0, -1017021.0, 5049166.0, -3865306.0, 494270.0,
]);
const polygons = PolygonGeometryLibrary.splitPolygonsOnEquator(
[positions],
Ellipsoid.WGS84,
ArcType.GEODESIC,
);
const expectedIntersection1 = new Cartesian3(
3799258.6687873346,
-5123110.886796548,
0.0,
);
const expectedIntersection2 = new Cartesian3(
5077099.353935631,
-3860530.240917096,
0.0,
);
expect(polygons.length).toBe(2);
expect(polygons[0].length).toBe(4);
expect(polygons[0][0]).toEqual(positions[0]);
expect(polygons[0][1]).toEqualEpsilon(
expectedIntersection1,
CesiumMath.EPSILON7,
);
expect(polygons[0][2]).toEqualEpsilon(
expectedIntersection2,
CesiumMath.EPSILON7,
);
expect(polygons[0][3]).toEqual(positions[3]);
expect(polygons[1].length).toBe(4);
expect(polygons[1][0]).toEqualEpsilon(
expectedIntersection1,
CesiumMath.EPSILON7,
);
expect(polygons[1][1]).toEqual(positions[1]);
expect(polygons[1][2]).toEqual(positions[2]);
expect(polygons[1][3]).toEqualEpsilon(
expectedIntersection2,
CesiumMath.EPSILON7,
);
});
it("does not split a simple polygon with one position touching the equator", function () {
const positions = Cartesian3.unpackArray([
3813220.0, -5085291.0, 527179.0, 3701301.0, -5097773.0, 0.0, 5049166.0,
-3865306.0, 494270.0,
]);
const polygons = PolygonGeometryLibrary.splitPolygonsOnEquator(
[positions],
Ellipsoid.WGS84,
ArcType.GEODESIC,
);
expect(polygons.length).toBe(1);
expect(polygons[0].length).toBe(3);
expect(polygons[0][0]).toEqual(positions[0]);
expect(polygons[0][1]).toEqual(positions[1]);
expect(polygons[0][2]).toEqual(positions[2]);
});
it("does not split a simple polygon with one edge on the equator, starting above the equator", function () {
const positions = Cartesian3.unpackArray([
-3219367.0, -5491259.0, 401098.0, -3217795.0, -5506913.0, 0.0,
-2713036.0, -5772334.0, 0.0, -2713766.0, -5757498.0, 406910.0,
]);
const polygons = PolygonGeometryLibrary.splitPolygonsOnEquator(
[positions],
Ellipsoid.WGS84,
ArcType.GEODESIC,
);
expect(polygons.length).toBe(1);
expect(polygons[0].length).toBe(4);
expect(polygons[0][0]).toEqual(positions[0]);
expect(polygons[0][1]).toEqual(positions[1]);
expect(polygons[0][2]).toEqual(positions[2]);
expect(polygons[0][3]).toEqual(positions[3]);
});
it("does not split a simple polygon with one edge on the equator, starting below the equator", function () {
const positions = Cartesian3.unpackArray([
-3180138.0, -5441382.0, -974441.0, -3186540.0, -5525048.0, 0.0,
-2198716.0, -5986569.0, 0.0, -2135113.0, -5925878.0, -996868.0,
]);
const polygons = PolygonGeometryLibrary.splitPolygonsOnEquator(
[positions],
Ellipsoid.WGS84,
ArcType.GEODESIC,
);
expect(polygons.length).toBe(1);
expect(polygons[0].length).toBe(4);
expect(polygons[0][0]).toEqual(positions[0]);
expect(polygons[0][1]).toEqual(positions[1]);
expect(polygons[0][2]).toEqual(positions[2]);
expect(polygons[0][3]).toEqual(positions[3]);
});
it("splits a positively concave polygon at the equator", function () {
const positions = Cartesian3.unpackArray([
-3723536.687096985, -5140643.423654287, 622159.6094790212,
-3706443.9124709764, -5089398.802336418, -1016836.564118223,
-1818346.3577937474, -5988204.417556031, -1226992.0906221648,
-1949728.2308330906, -6022778.780648997, 775419.1678640501,
-2891108.934831509, -5659936.656854747, -534148.7427656263,
]);
const polygons = PolygonGeometryLibrary.splitPolygonsOnEquator(
[positions],
Ellipsoid.WGS84,
ArcType.GEODESIC,
);
const expectedIntersection1 = new Cartesian3(
-3746523.7934060274,
-5161801.144582336,
0,
);
const expectedIntersection2 = new Cartesian3(
-3298992.8935172106,
-5458688.2562839165,
0,
);
const expectedIntersection3 = new Cartesian3(
-2527814.313071595,
-5855833.534980258,
0,
);
const expectedIntersection4 = new Cartesian3(
-1921714.863778476,
-6081746.753450187,
0,
);
expect(polygons.length).toBe(3);
expect(polygons[0].length).toBe(3);
expect(polygons[0][0]).toEqual(positions[0]);
expect(polygons[0][1]).toEqualEpsilon(
expectedIntersection1,
CesiumMath.EPSILON7,
);
expect(polygons[0][2]).toEqualEpsilon(
expectedIntersection2,
CesiumMath.EPSILON7,
);
expect(polygons[1].length).toBe(7);
expect(polygons[1][0]).toEqualEpsilon(
expectedIntersection1,
CesiumMath.EPSILON7,
);
expect(polygons[1][1]).toEqual(positions[1]);
expect(polygons[1][2]).toEqual(positions[2]);
expect(polygons[1][3]).toEqualEpsilon(
expectedIntersection4,
CesiumMath.EPSILON7,
);
expect(polygons[1][4]).toEqualEpsilon(
expectedIntersection3,
CesiumMath.EPSILON7,
);
expect(polygons[1][5]).toEqual(positions[4]);
expect(polygons[1][6]).toEqualEpsilon(
expectedIntersection2,
CesiumMath.EPSILON7,
);
expect(polygons[2].length).toBe(3);
expect(polygons[2][0]).toEqualEpsilon(
expectedIntersection4,
CesiumMath.EPSILON7,
);
expect(polygons[2][1]).toEqual(positions[3]);
expect(polygons[2][2]).toEqualEpsilon(
expectedIntersection3,
CesiumMath.EPSILON7,
);
});
it("splits a negatively concave polygon at the equator", function () {
const positions = Cartesian3.unpackArray([
-4164072.7435535816, -4791571.5503237555, 605958.8290040599,
-4167507.7232260685, -4800497.02674794, -508272.2109012767,
-3712172.6000501625, -5184159.589216706, 116723.13202563708,
-3259646.0020361557, -5455158.378873343, -532227.4715966922,
-3283717.3855494126, -5434359.545068984, 592819.1229613343,
]);
const polygons = PolygonGeometryLibrary.splitPolygonsOnEquator(
[positions],
Ellipsoid.WGS84,
ArcType.GEODESIC,
);
const expectedIntersection1 = new Cartesian3(
-4182416.3757553473,
-4815394.568525253,
0,
);
const expectedIntersection2 = new Cartesian3(
-3803015.1382151386,
-5120322.982906009,
0,
);
const expectedIntersection3 = new Cartesian3(
-3635913.2183307745,
-5240302.153458,
0,
);
const expectedIntersection4 = new Cartesian3(
-3284360.5276909056,
-5467504.688147503,
0,
);
expect(polygons.length).toBe(3);
expect(polygons[0].length).toBe(7);
expect(polygons[0][0]).toEqual(positions[0]);
expect(polygons[0][1]).toEqualEpsilon(
expectedIntersection1,
CesiumMath.EPSILON7,
);
expect(polygons[0][2]).toEqualEpsilon(
expectedIntersection2,
CesiumMath.EPSILON7,
);
expect(polygons[0][3]).toEqual(positions[2]);
expect(polygons[0][4]).toEqualEpsilon(
expectedIntersection3,
CesiumMath.EPSILON7,
);
expect(polygons[0][5]).toEqualEpsilon(
expectedIntersection4,
CesiumMath.EPSILON7,
);
expect(polygons[0][6]).toEqual(positions[4]);
expect(polygons[1].length).toBe(3);
expect(polygons[1][0]).toEqualEpsilon(
expectedIntersection1,
CesiumMath.EPSILON7,
);
expect(polygons[1][1]).toEqual(positions[1]);
expect(polygons[1][2]).toEqualEpsilon(
expectedIntersection2,
CesiumMath.EPSILON7,
);
expect(polygons[2].length).toBe(3);
expect(polygons[2][0]).toEqualEpsilon(
expectedIntersection3,
CesiumMath.EPSILON7,
);
expect(polygons[2][1]).toEqual(positions[3]);
expect(polygons[2][2]).toEqualEpsilon(
expectedIntersection4,
CesiumMath.EPSILON7,
);
});
it("splits a positively concave polygon with a point on the equator", function () {
const positions = Cartesian3.unpackArray([
-3592289.0, -5251493.0, 433532.0, -3568746.0, -5245699.0, -646544.0,
-2273628.0, -5915229.0, -715098.0, -2410175.0, -5885323.0, 475855.0,
-3012338.0, -5621469.0, 0.0,
]);
const polygons = PolygonGeometryLibrary.splitPolygonsOnEquator(
[positions],
Ellipsoid.WGS84,
ArcType.GEODESIC,
);
const expectedIntersection1 = new Cartesian3(
-3595684.3882232937,
-5267986.8423389485,
0,
);
const expectedIntersection2 = new Cartesian3(
-2365929.6862513637,
-5923091.111107741,
0,
);
expect(polygons.length).toBe(3);
expect(polygons[0].length).toBe(3);
expect(polygons[0][0]).toEqual(positions[0]);
expect(polygons[0][1]).toEqualEpsilon(
expectedIntersection1,
CesiumMath.EPSILON7,
);
expect(polygons[0][2]).toEqual(positions[4]);
expect(polygons[1].length).toBe(5);
expect(polygons[1][0]).toEqualEpsilon(
expectedIntersection1,
CesiumMath.EPSILON7,
);
expect(polygons[1][1]).toEqual(positions[1]);
expect(polygons[1][2]).toEqual(positions[2]);
expect(polygons[1][3]).toEqualEpsilon(
expectedIntersection2,
CesiumMath.EPSILON7,
);
expect(polygons[1][4]).toEqual(positions[4]);
expect(polygons[2].length).toBe(3);
expect(polygons[2][0]).toEqualEpsilon(
expectedIntersection2,
CesiumMath.EPSILON7,
);
expect(polygons[2][1]).toEqual(positions[3]);
expect(polygons[2][2]).toEqual(positions[4]);
});
it("splits a negatively concave polygon with a point on the equator", function () {
const positions = Cartesian3.unpackArray([
-3774632.0, -5136123.0, 222459.0, -3714187.0, -5173580.0, -341046.0,
-3516544.0, -5320967.0, 0.0, -3304860.0, -5444086.0, -342567.0,
-3277484.0, -5466977.0, 218213.0,
]);
const polygons = PolygonGeometryLibrary.splitPolygonsOnEquator(
[positions],
Ellipsoid.WGS84,
ArcType.GEODESIC,
);
const expectedIntersection1 = new Cartesian3(
-3754485.468265927,
-5156013.039098039,
0,
);
const expectedIntersection2 = new Cartesian3(
-3291304.258941832,
-5463327.545172482,
0,
);
expect(polygons.length).toBe(3);
expect(polygons[0].length).toBe(5);
expect(polygons[0][0]).toEqual(positions[0]);
expect(polygons[0][1]).toEqualEpsilon(
expectedIntersection1,
CesiumMath.EPSILON7,
);
expect(polygons[0][2]).toEqual(positions[2]);
expect(polygons[0][3]).toEqualEpsilon(
expectedIntersection2,
CesiumMath.EPSILON7,
);
expect(polygons[0][4]).toEqual(positions[4]);
expect(polygons[1].length).toBe(3);
expect(polygons[1][0]).toEqualEpsilon(
expectedIntersection1,
CesiumMath.EPSILON7,
);
expect(polygons[1][1]).toEqual(positions[1]);
expect(polygons[1][2]).toEqual(positions[2]);
expect(polygons[2].length).toBe(3);
expect(polygons[2][0]).toEqual(positions[2]);
expect(polygons[2][1]).toEqual(positions[3]);
expect(polygons[2][2]).toEqualEpsilon(
expectedIntersection2,
CesiumMath.EPSILON7,
);
});
it("splits a polygon with an edge equator", function () {
const positions = Cartesian3.unpackArray([
-3227931.0, -5469496.0, 584508.0, -3150093.0, -5488360.0, -792747.0,
-1700622.0, -6089685.0, -835364.0, -1786389.0, -6122714.0, 0.0,
-2593600.0, -5826977.0, 0.0, -2609132.0, -5790155.0, 584508.0,
]);
const polygons = PolygonGeometryLibrary.splitPolygonsOnEquator(
[positions],
Ellipsoid.WGS84,
ArcType.GEODESIC,
);
const expectedIntersection = new Cartesian3(
-3213523.577073882,
-5509437.159126084,
0,
);
expect(polygons.length).toBe(2);
expect(polygons[0].length).toBe(4);
expect(polygons[0][0]).toEqual(positions[0]);
expect(polygons[0][1]).toEqualEpsilon(
expectedIntersection,
CesiumMath.EPSILON7,
);
expect(polygons[0][2]).toEqual(positions[4]);
expect(polygons[0][3]).toEqual(positions[5]);
expect(polygons[1].length).toBe(5);
expect(polygons[1][0]).toEqualEpsilon(
expectedIntersection,
CesiumMath.EPSILON7,
);
expect(polygons[1][1]).toEqual(positions[1]);
expect(polygons[1][2]).toEqual(positions[2]);
expect(polygons[1][3]).toEqual(positions[3]);
expect(polygons[1][4]).toEqual(positions[4]);
});
it("splits a polygon with a backtracking edge on the equator", function () {
const positions = Cartesian3.unpackArray([
-3491307.0, -5296123.0, 650596.0, -3495031.0, -5334507.0, 0.0,
-4333607.0, -4677312.0, 0.0, -4275491.0, -4629182.0, -968553.0,
-2403691.0, -5827997.0, -943662.0, -2484409.0, -5837281.0, 631344.0,
]);
const polygons = PolygonGeometryLibrary.splitPolygonsOnEquator(
[positions],
Ellipsoid.WGS84,
ArcType.GEODESIC,
);
const expectedIntersection = new Cartesian3(
-2471499.3842933537,
-5879823.32933623,
0,
);
expect(polygons.length).toBe(2);
expect(polygons[0].length).toBe(4);
expect(polygons[0][0]).toEqual(positions[0]);
expect(polygons[0][1]).toEqual(positions[1]);
expect(polygons[0][2]).toEqualEpsilon(
expectedIntersection,
CesiumMath.EPSILON7,
);
expect(polygons[0][3]).toEqual(positions[5]);
expect(polygons[1].length).toBe(5);
expect(polygons[1][0]).toEqual(positions[1]);
expect(polygons[1][1]).toEqual(positions[2]);
expect(polygons[1][2]).toEqual(positions[3]);
expect(polygons[1][3]).toEqual(positions[4]);
expect(polygons[1][4]).toEqualEpsilon(
expectedIntersection,
CesiumMath.EPSILON7,
);
});
it("splits a simple rhumb polygon at the equator", function () {
const positions = Cartesian3.unpackArray([
3813220.0, -5085291.0, 527179.0, 3701301.0, -5097773.0, -993503.0,
5037375.0, -3776794.0, -1017021.0, 5049166.0, -3865306.0, 494270.0,
]);
const polygons = PolygonGeometryLibrary.splitPolygonsOnEquator(
[positions],
Ellipsoid.WGS84,
ArcType.RHUMB,
);
const expectedIntersection1 = new Cartesian3(
3799205.595277112,
-5123150.245267465,
0.0,
);
const expectedIntersection2 = new Cartesian3(
5077127.456540122,
-3860493.2820580625,
0.0,
);
expect(polygons.length).toBe(2);
expect(polygons[0].length).toBe(4);
expect(polygons[0][0]).toEqual(positions[0]);
expect(polygons[0][1]).toEqualEpsilon(
expectedIntersection1,
CesiumMath.EPSILON7,
);
expect(polygons[0][2]).toEqualEpsilon(
expectedIntersection2,
CesiumMath.EPSILON7,
);
expect(polygons[0][3]).toEqual(positions[3]);
expect(polygons[1].length).toBe(4);
expect(polygons[1][0]).toEqualEpsilon(
expectedIntersection1,
CesiumMath.EPSILON7,
);
expect(polygons[1][1]).toEqual(positions[1]);
expect(polygons[1][2]).toEqual(positions[2]);
expect(polygons[1][3]).toEqualEpsilon(
expectedIntersection2,
CesiumMath.EPSILON7,
);
});
it("splits a simple rhumb polygon at the equator across the IDL", function () {
const positions = Cartesian3.fromDegreesArray([
30, -30, 20, 30, -20, 30, -30, -30,
]);
const polygons = PolygonGeometryLibrary.splitPolygonsOnEquator(
[positions],
Ellipsoid.WGS84,
ArcType.RHUMB,
);
const expectedIntersection1 = new Cartesian3(
5780555.229886577,
2695517.1720840395,
0.0,
);
const expectedIntersection2 = new Cartesian3(
5780555.229886577,
-2695517.1720840395,
0.0,
);
expect(polygons.length).toBe(2);
expect(polygons[0].length).toBe(4);
expect(polygons[0][0]).toEqual(positions[0]);
expect(polygons[0][1]).toEqualEpsilon(
expectedIntersection1,
CesiumMath.EPSILON7,
);
expect(polygons[0][2]).toEqualEpsilon(
expectedIntersection2,
CesiumMath.EPSILON7,
);
expect(polygons[0][3]).toEqual(positions[3]);
expect(polygons[1].length).toBe(4);
expect(polygons[1][0]).toEqualEpsilon(
expectedIntersection1,
CesiumMath.EPSILON7,
);
expect(polygons[1][1]).toEqual(positions[1]);
expect(polygons[1][2]).toEqual(positions[2]);
expect(polygons[1][3]).toEqualEpsilon(
expectedIntersection2,
CesiumMath.EPSILON7,
);
});
it("splits an array of polygons", function () {
const positions = Cartesian3.unpackArray([
3813220.0, -5085291.0, 527179.0, 3701301.0, -5097773.0, -993503.0,
5037375.0, -3776794.0, -1017021.0, 5049166.0, -3865306.0, 494270.0,
]);
const polygons = PolygonGeometryLibrary.splitPolygonsOnEquator(
[positions, positions],
Ellipsoid.WGS84,
ArcType.GEODESIC,
);
expect(polygons.length).toBe(4);
});
});
});