营销方案 网站深圳市住房和城乡建设厅网站

当前位置: 首页 > news >正文

营销方案 网站,深圳市住房和城乡建设厅网站,成都关键词快速排名,西安百度推广外包Cesium 地球网格构造 Cesium原理篇#xff1a;3最长的一帧之地形(2#xff1a;高度图) HeightmapTessellator 用于从高程图像创建网格。提供了一个函数 computeVertices#xff0c;可以根据高程图像创建顶点数组。 该函数的参数包括高程图像、高度数据的结构、网格宽高、…Cesium 地球网格构造 Cesium原理篇3最长的一帧之地形(2高度图) HeightmapTessellator 用于从高程图像创建网格。提供了一个函数 computeVertices可以根据高程图像创建顶点数组。 该函数的参数包括高程图像、高度数据的结构、网格宽高、边缘裙板高度、矩形范围、相机中心点等。函数的实现使用了许多性能优化技巧如将函数内常量化、内联等。 该模块的输出为一个对象包括创建好的顶点数组、最大与最小高度、该网格的边界球、边界方向盒等信息。 1、函数定义 // 声明 static computeVertices(options) {}// 使用 const width 5; const height 5; const statistics Cesium.HeightmapTessellator.computeVertices({heightmap : [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0],width : width,height : height,skirtHeight : 0.0,nativeRectangle : {west : 10.0,east : 20.0,south : 30.0,north : 40.0} });const encoding statistics.encoding; const position encoding.decodePosition(statistics.vertices, index);options 参数: 参数类型描述heightmapArray要镶嵌的高度图。widthnumber高度图的宽度以高度样本计。heightnumber高度图的高度以高度样本计。skirtHeightnumber要悬垂在高度图边缘的裙子的高度。nativeRectangleRectangle高度贴图投影的原始坐标中的矩形。对于具有地理投影的高度图这是度数。对于 Web 墨卡托投影这是米。exaggerationnumber用于夸大地形的比例尺。默认为1.exaggerationRelativeHeightnumber地形夸大的高度以米为单位。默认为0.rectangleRectangle高度图覆盖的矩形大地坐标为北、南、东和西属性弧度。必须提供矩形或本机矩形。如果同时提供两者则假定它们是一致的。isGeographicboolean如果高度图使用{link GeographicProjection}则为true如果使用{link WebMercatorProjection}则为false。默认为true。relativeToCenterCartesian3将计算出的位置作为Cartesian3.subtract(worldPosition, relativeToCenter)。默认为Cartesian3.ZERO。ellipsoidEllipsoid高度贴图适用的椭球体。默认为Ellipsoid.WGS84。structureobject描述高度数据结构的对象。 裙边(skirt) 防止不同层级mesh加载时出现裂缝 实现 static computeVertices(options) {const cos Math.cos;const sin Math.sin;const sqrt Math.sqrt;const toRadians CesiumMath.toRadians;const heightmap options.heightmap;const width options.width;const height options.height;const skirtHeight options.skirtHeight;const hasSkirts skirtHeight 0.0;const ellipsoid defaultValue(options.ellipsoid, Ellipsoid.WGS84);const nativeRectangle Rectangle.clone(options.nativeRectangle);const rectangle Rectangle.clone(options.rectangle);const geographicWest rectangle.west;const geographicSouth rectangle.south;const geographicEast rectangle.east;const geographicNorth rectangle.north;const relativeToCenter options.relativeToCenter;const includeWebMercatorT defaultValue(options.includeWebMercatorT, false);const exaggeration defaultValue(options.exaggeration, 1.0);const exaggerationRelativeHeight defaultValue(options.exaggerationRelativeHeight,0.0);const hasExaggeration exaggeration ! 1.0;const includeGeodeticSurfaceNormals hasExaggeration;const rectangleWidth Rectangle.computeWidth(nativeRectangle);const rectangleHeight Rectangle.computeHeight(nativeRectangle);// 每个网格的长宽const granularityX rectangleWidth / (width - 1);const granularityY rectangleHeight / (height - 1);const radiiSquared ellipsoid.radiiSquared;const radiiSquaredX radiiSquared.x;const radiiSquaredY radiiSquared.y;const radiiSquaredZ radiiSquared.z;let minimumHeight 65536.0;let maximumHeight -65536.0;const fromENU Transforms.eastNorthUpToFixedFrame(relativeToCenter,ellipsoid);const minimum minimumScratch;minimum.x Number.POSITIVE_INFINITY;minimum.y Number.POSITIVE_INFINITY;minimum.z Number.POSITIVE_INFINITY;const maximum maximumScratch;maximum.x Number.NEGATIVE_INFINITY;maximum.y Number.NEGATIVE_INFINITY;maximum.z Number.NEGATIVE_INFINITY;let hMin Number.POSITIVE_INFINITY;const gridVertexCount width * height;const edgeVertexCount skirtHeight 0.0 ? width * 2 height * 2 : 0;const vertexCount gridVertexCount edgeVertexCount;const positions new Array(vertexCount);const heights new Array(vertexCount);const uvs new Array(vertexCount);let startRow 0;let endRow height;let startCol 0;let endCol width;if (hasSkirts) {–startRow;endRow;–startCol;endCol;}for (let rowIndex startRow; rowIndex endRow; rowIndex) {let row rowIndex;if (row 0) {row 0;}if (row height) {row height - 1;}//// ^ latitude(纬度)// |// | North(90)// | ———// | | |// | West(-180) | | East(0)// | | |// | ———// | South(-90)// —————————– longitude(经度)// 地理坐标系下// 当前纬度(latitude) 距离最北头(North) 的距离// 这个值是越来越小的, 随着行数越来越大let latitude nativeRectangle.north - granularityY * row;latitude toRadians(latitude);// 当前纬度(latitude) 距离最南头(South) 的百分比(0~1)let v (latitude - geographicSouth) / (geographicNorth - geographicSouth);v CesiumMath.clamp(v, 0.0, 1.0);const isNorthEdge rowIndex startRow;const isSouthEdge rowIndex endRow - 1;const cosLatitude cos(latitude);const nZ sin(latitude);const kZ radiiSquaredZ * nZ;for (let colIndex startCol; colIndex endCol; colIndex) {let col colIndex;if (col 0) {col 0;}if (col width) {col width - 1;}const terrainOffset row * width col;let heightSample heightmap[terrainOffset]let longitude nativeRectangle.west granularityX * col;longitude toRadians(longitude);let u (longitude - geographicWest) / (geographicEast - geographicWest);u CesiumMath.clamp(u, 0.0, 1.0);let index row * width col;if (skirtHeight 0.0) {const isWestEdge colIndex startCol;const isEastEdge colIndex endCol - 1;const isEdge isNorthEdge || isSouthEdge || isWestEdge || isEastEdge;const isCorner (isNorthEdge || isSouthEdge) (isWestEdge || isEastEdge);if (isCorner) {// Dont generate skirts on the corners.continue;} else if (isEdge) {heightSample - skirtHeight;if (isWestEdge) {// The outer loop iterates north to south but the indices are ordered south to north, hence the index flip below// 外循环从北到南迭代但索引按从南到北的顺序排列因此索引在下面翻转index gridVertexCount (height - row - 1);} else if (isSouthEdge) {// Add after west indices. South indices are ordered east to west.// 加在西方指数之后。南方指数是从东向西排列的。index gridVertexCount height (width - col - 1);} else if (isEastEdge) {// Add after west and south indices. East indices are ordered north to south. The index is flipped like above.// 在西部和南部指数后加上。东部指数是从北向南排列的。索引如上所述翻转。index gridVertexCount height width row;} else if (isNorthEdge) {// Add after west, south, and east indices. North indices are ordered west to east.// 在西部、南部和东部指数后添加。北方指数是从西向东排列的。index gridVertexCount height width height col;}}}// 经纬度转笛卡尔坐标系const nX cosLatitude * cos(longitude);const nY cosLatitude * sin(longitude);const kX radiiSquaredX * nX;const kY radiiSquaredY * nY;const gamma sqrt(kX * nX kY * nY kZ * nZ);const oneOverGamma 1.0 / gamma;const rSurfaceX kX * oneOverGamma;const rSurfaceY kY * oneOverGamma;const rSurfaceZ kZ * oneOverGamma;const position new Cartesian3();position.x rSurfaceX nX * heightSample;position.y rSurfaceY nY * heightSample;position.z rSurfaceZ nZ * heightSample;hMin Math.min(hMin, heightSample);positions[index] position;uvs[index] new Cartesian2(u, v);heights[index] heightSample;}}const aaBox new AxisAlignedBoundingBox(minimum, maximum, relativeToCenter);const encoding new TerrainEncoding(relativeToCenter,aaBox,hMin,maximumHeight,fromENU,false,includeWebMercatorT,includeGeodeticSurfaceNormals,exaggeration,exaggerationRelativeHeight);const vertices new Float32Array(vertexCount * encoding.stride);let bufferIndex 0;for (let j 0; j vertexCount; j) {bufferIndex encoding.encode(vertices,bufferIndex,positions[j],uvs[j],heights[j],undefined,undefined,undefined);}return {vertices: vertices,};}