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