function fromCartesian(cartesian) { const oneOverRadii = { x: 1.0 / 6378137.0, y: 1.0 / 6378137.0, z: 1.0 / 6356752.3142451793 }; const oneOverRadiiSquared = { x: 1.0 / (6378137.0 * 6378137.0), y: 1.0 / (6378137.0 * 6378137.0), z: 1.0 / (6356752.3142451793 * 6356752.3142451793) }; const p = scaleToGeodeticSurface( cartesian, oneOverRadii, oneOverRadiiSquared, 0.1 ); if (!(p !== undefined && p !== null)) { return undefined; } let n = { x: p.x * oneOverRadiiSquared.x, y: p.y * oneOverRadiiSquared.y, z: p.z * oneOverRadiiSquared.z }; const m1 = magnitude(n); n = { x: n.x / m1, y: n.y / m1, z: n.z / m1 }; const h = { x: cartesian.x - p.x, y: cartesian.y - p.y, z: cartesian.z - p.z }; const longitude = Math.atan2(n.y, n.x); const latitude = Math.asin(n.z); const height = Math.sign(h.x * cartesian.x + h.y * cartesian.y + h.z * cartesian.z) * magnitude(h); let result = {}; result.longitude = (longitude * 180.0) / Math.PI; result.latitude = (latitude * 180.0) / Math.PI; result.height = height; return result; } function scaleToGeodeticSurface( cartesian, oneOverRadii, oneOverRadiiSquared, centerToleranceSquared ) { const positionX = cartesian.x; const positionY = cartesian.y; const positionZ = cartesian.z; const oneOverRadiiX = oneOverRadii.x; const oneOverRadiiY = oneOverRadii.y; const oneOverRadiiZ = oneOverRadii.z; const x2 = positionX * positionX * oneOverRadiiX * oneOverRadiiX; const y2 = positionY * positionY * oneOverRadiiY * oneOverRadiiY; const z2 = positionZ * positionZ * oneOverRadiiZ * oneOverRadiiZ; // Compute the squared ellipsoid norm. const squaredNorm = x2 + y2 + z2; const ratio = Math.sqrt(1.0 / squaredNorm); // As an initial approximation, assume that the radial intersection is the projection point. const intersection = { x: cartesian.x * ratio, y: cartesian.y * ratio, z: cartesian.z * ratio }; // If the position is near the center, the iteration will not converge. if (squaredNorm < centerToleranceSquared) { return !isFinite(ratio) ? undefined : intersection; } const oneOverRadiiSquaredX = oneOverRadiiSquared.x; const oneOverRadiiSquaredY = oneOverRadiiSquared.y; const oneOverRadiiSquaredZ = oneOverRadiiSquared.z; // Use the gradient at the intersection point in place of the true unit normal. // The difference in magnitude will be absorbed in the multiplier. const gradient = { x: intersection.x * oneOverRadiiSquaredX * 2.0, y: intersection.y * oneOverRadiiSquaredY * 2.0, z: intersection.z * oneOverRadiiSquaredZ * 2.0 }; // Compute the initial guess at the normal vector multiplier, lambda. let lambda = ((1.0 - ratio) * magnitude(cartesian)) / (0.5 * magnitude(gradient)); let correction = 0.0; let func; let denominator; let xMultiplier; let yMultiplier; let zMultiplier; let xMultiplier2; let yMultiplier2; let zMultiplier2; let xMultiplier3; let yMultiplier3; let zMultiplier3; do { lambda -= correction; xMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredX); yMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredY); zMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredZ); xMultiplier2 = xMultiplier * xMultiplier; yMultiplier2 = yMultiplier * yMultiplier; zMultiplier2 = zMultiplier * zMultiplier; xMultiplier3 = xMultiplier2 * xMultiplier; yMultiplier3 = yMultiplier2 * yMultiplier; zMultiplier3 = zMultiplier2 * zMultiplier; func = x2 * xMultiplier2 + y2 * yMultiplier2 + z2 * zMultiplier2 - 1.0; // "denominator" here refers to the use of this expression in the velocity and acceleration // computations in the sections to follow. denominator = x2 * xMultiplier3 * oneOverRadiiSquaredX + y2 * yMultiplier3 * oneOverRadiiSquaredY + z2 * zMultiplier3 * oneOverRadiiSquaredZ; const derivative = -2.0 * denominator; correction = func / derivative; } while (Math.abs(func) > 0.000000000001); // if (!(result !== undefined && result !== null)) { // return new Cartesian3( // positionX * xMultiplier, // positionY * yMultiplier, // positionZ * zMultiplier // ); // } let result = { x: positionX * xMultiplier, y: positionY * yMultiplier, z: positionZ * zMultiplier }; return result; } function magnitude(cartesian) { return Math.sqrt( cartesian.x * cartesian.x + cartesian.y * cartesian.y + cartesian.z * cartesian.z ); } fromCartesian({x:-2307065.8,y:5418833.5,z:2440308.2})
标签:cartesian,const,经纬度,笛卡尔,oneOverRadiiSquared,let,坐标,1.0,result From: https://www.cnblogs.com/xiaohanyanliu/p/18323829