var CalcVol = { upPos: [], downPos: [], upClipPos: [], //上表面最低点集合 downClipPos: [], //下表面最高点集合 upMinHight: -Infinity, //上表面最低点高度值 downMaxHight: Infinity, //下表面最高点高度值 upVolume: 0, centerVolume: 0, downVolume: 0, init: function (upPos, downPos) { this.initData(upPos, downPos); this.clipUpByPoint(); this.clipBottomByPoint(); this.createUpSolid(); this.createDownSolid(); var s1 = this.calculateUpVolume(); var s2 = this.calculateDownVolume(); return this.calculateCenterVolume(s2.height, s2.bottom); }, initData: function (upPos, downPos) { this.upPos = upPos; this.downPos = downPos; this.upClipPos = []; this.downClipPos = []; this.upMinHight = -Infinity; this.downMaxHight = Infinity; this.upVolume = 0; this.centerVolume = 0; this.downVolume = 0; }, // 上表面水平切割 clipUpByPoint: function () { this.upPos.sort(this.compare("z")); this.upMinHight = this.upPos[0].z; var upClipPoints = []; for (var i = 0; i < this.upPos.length; i++) { var upEle = this.upPos[i]; var x = upEle.x; var y = upEle.y; var z = this.upMinHight; this.upClipPos.push({ x: x, y: y, z: z }); upClipPoints.push(x, y, z); } }, // 下表面水平切割 clipBottomByPoint: function () { this.downPos.sort(this.compare("z")); this.downMaxHight = this.downPos[this.downPos.length - 1].z; var downClipPoints = []; for (var i = 0; i < this.downPos.length; i++) { var downEle = this.downPos[i]; var x = downEle.x; var y = downEle.y; var z = this.downMaxHight; this.downClipPos.push({ x: x, y: y, z: z }); downClipPoints.push(x, y, z); } }, // 创建上半部分空间体 createUpSolid: function () { var vertex = this.upPos[0]; var upSolidPolygonPoints = []; var fourpoints0 = []; var fourpoints1 = []; for (var i = 1; i < this.upPos.length; i++) { var upEle = this.upPos[i]; var upClipEle = this.upClipPos[i]; var upClipEle1 = this.upClipPos[this.upPos.length - i]; fourpoints0.push(upEle.x, upEle.y, upEle.z); fourpoints1.push(upClipEle1.x, upClipEle1.y, upClipEle1.z); var curPolygonPoints = [ vertex.x, vertex.y, vertex.z, upEle.x, upEle.y, upEle.z, upClipEle.x, upClipEle.y, upClipEle.z, ]; upSolidPolygonPoints.push(curPolygonPoints); } var fourpoints = fourpoints0.concat(fourpoints1); //上半部分顶点对应的那个面的四个顶点 upSolidPolygonPoints.push(fourpoints); for (var n = 0; n < upSolidPolygonPoints.length; n++) { var element = upSolidPolygonPoints[n]; } }, // 创建下半部分空间体 createDownSolid: function () { var vertex = this.downPos[this.downPos.length - 1]; var downSolidPolygonPoints = []; var fourpoints0 = []; var fourpoints1 = []; for (var i = 0; i < this.downPos.length - 1; i++) { var downEle = this.downPos[i]; var downClipEle = this.downClipPos[i]; var downClipEle1 = this.downClipPos[this.downPos.length - 2 - i]; fourpoints0.push(downEle.x, downEle.y, downEle.z); fourpoints1.push(downClipEle1.x, downClipEle1.y, downClipEle1.z); var curPolygonPoints = [ vertex.x, vertex.y, vertex.z, downEle.x, downEle.y, downEle.z, downClipEle.x, downClipEle.y, downClipEle.z, ]; downSolidPolygonPoints.push(curPolygonPoints); } var fourpoints = fourpoints0.concat(fourpoints1); //下半部分顶点对应的那个面的四个顶点 downSolidPolygonPoints.push(fourpoints); for (var n = 0; n < downSolidPolygonPoints.length; n++) { var element = downSolidPolygonPoints[n]; } }, // 计算上半部分体积//四棱锥体积计算公式:体积=底面积*高/3 calculateUpVolume: function () { // 底面积=(上底+下底)*高/2,上底长度和下底长度 //console.log("计算上半部分的底面积:", this.upPos, this.upClipPos); var clipLine = []; var upAndDownDistance = 0; for (var i = 1; i < this.upPos.length; i++) { var upEle = this.upPos[i]; var upClipEle = this.upClipPos[i]; clipLine.push(upClipEle); var distance = this.getSpaceDistance(upEle, upClipEle); //console.log("底面上下底边长度" + i, distance); upAndDownDistance += distance; } var height = this.getSpaceDistance(clipLine[0], clipLine[1]); //console.log("底面的高", height); var bottomArea = (upAndDownDistance * height) / 2; //console.log("底面积", bottomArea); //高 var pt = turf.point([this.upClipPos[0].x, this.upClipPos[0].y]); var line = turf.lineString([ [this.upClipPos[1].x, this.upClipPos[1].y], [this.upClipPos[2].x, this.upClipPos[2].y], ]); var heightDistance = turf.pointToLineDistance(pt, line) * 1000; //console.log("顶点到底面的高:", heightDistance); this.upVolume = (bottomArea * heightDistance) / 3; //console.log("上半部分体积(黄色):", this.upVolume); return { height: heightDistance, bottom: height }; }, // 计算下半部分体积//四棱锥体积计算公式:体积=底面积*高/3 calculateDownVolume: function () { // 底面积=(上底+下底)*高/2 // 上底长度和下底长度 //console.log("计算下半部分的底面积:", this.downPos, this.downClipPos); var clipLine = []; var upAndDownDistance = 0; for (var i = 0; i < this.downPos.length - 1; i++) { var upEle = this.downPos[i]; var upClipEle = this.downClipPos[i]; clipLine.push(upClipEle); var distance = this.getSpaceDistance(upEle, upClipEle); //console.log("底面上下底边长度" + i, distance); upAndDownDistance += distance; } var height = this.getSpaceDistance(clipLine[0], clipLine[1]); //console.log("底面的高", height); var bottomArea = (upAndDownDistance * height) / 2; //console.log("底面积", bottomArea); //高 var pt = turf.point([this.downClipPos[2].x, this.downClipPos[2].y]); var line = turf.lineString([ [this.downClipPos[0].x, this.downClipPos[0].y], [this.downClipPos[1].x, this.downClipPos[1].y], ]); var heightDistance = turf.pointToLineDistance(pt, line) * 1000; //console.log("顶点到底面的高:", heightDistance); this.downVolume = (bottomArea * heightDistance) / 3; //console.log("下半部分体积(绿色):", this.downVolume); return { height: heightDistance, bottom: height }; }, // 计算中间部分体积//三棱柱体积计算公式:体积=底面积*高 //height:三棱柱底面三角形的高,bottom:三棱柱底面三角形的底边 calculateCenterVolume: function (height, bottom) { //底面积 var area = (height * bottom) / 2; //console.log("底面三角形面积:", area); var h = Math.abs(this.upClipPos[0].z - this.downClipPos[2].z); //三棱柱高 this.centerVolume = area * h; //console.log("中间部分三棱柱体积:", this.centerVolume); var volume = this.upVolume + this.downVolume + this.centerVolume; //console.log("当前空间立方体的体积是(m³):", volume); return volume; }, // 空间两点间距离,单位m getSpaceDistance: function (pos1, pos2) { var h = Math.abs(pos1.z - pos2.z); var from = turf.point([pos1.x, pos1.y]); var to = turf.point([pos2.x, pos2.y]); var distance = turf.distance(from, to); //这里计算出来的单位是km,要转换成m,所以后面开平方的时候*1000 var result = Math.sqrt(Math.pow(distance * 1000, 2) + Math.pow(h, 2)); return result; }, //数组根据某一字段从高到低排序 compare: function (property) { return function (a, b) { var value1 = a[property]; var value2 = b[property]; return value1 - value2; }; } };