如何用three.js实现数字孪生、3D工厂、3D工业园区、智慧制造、智慧工业、智慧工厂-第十课
文章前,先聊点啥吧。
最近元宇宙炒的挺火热,在所有人都争相定义元宇宙的时候,资本就开始着手入场了。当定义明确,全民皆懂之后,风口也就过去了。
前两天看到新闻,新世界CEO宣布购入最大的数字地块,这块虚拟土地的投资金额约为 3200 万元人民币。在这之前新世界以及他购买的虚拟土地持有公司名称也都是鲜为人知的。这就是资本的力量,即打了广告,又占了风口坑位,一举多得,好像现在没个几千万上亿的动态,都不足以博得大众眼球。
那么何为元宇宙,为何不是元世界、元地球,而是疯狂到了宇宙这个范围。如果真的虚拟到了宇宙的无穷无尽,试想一下,一块虚拟土地能卖到几千万?所以重点不在虚拟土地的价格。重点是资本想让你看到什么。正所谓,见山不是山,见水不是水......
元宇宙,无论是使用还是创造,只有落实到具体应用,普及到全民参与,才能真正体现它的价值。试想一下,全球大部分公司都参与到元宇宙的研发,全球很多人都为元宇宙添砖加瓦,真正做到全民参与。那么元宇宙才真正的发展起来。
所以解决问题的痛点在工具,为全民提供创造元宇宙的工具,才是方向....
序:
前段时间,做了一个数字孪生的项目,所谓数字孪生,百度百科解释说,就是充分利用物理模型、传感器更新、运行历史等数据,集成多学科、多物理量、多尺度、多概率的仿真过程,在虚拟空间中完成映射,从而反映相对应的实体装备的全生命周期过程。数字孪生是一种超越现实的概念,可以被视为一个或多个重要的、彼此依赖的装备系统的数字映射系统。是个普遍适应的理论技术体系,可以在众多领域应用,在产品设计、产品制造、医学分析、工程建设等领域应用较多。在国内应用最深入的是工程建设领域,关注度最高、研究最热的是智能制造领域。
通俗的讲,就是利用三维技术,将生产过程、数据监测监控展示出来。
随着物联网技术发展,数据展示、大屏展示在IT界也是越发的流行与时尚,而这其中所应用到了关键的技术WebGL(three.js),也就理所当然的成为了集万千宠爱于一生的前端焦点。
一、解决方案
数字孪生,解决主要在三大步骤:
1、数据采集:主要在传感器方面,如何选用传感器,适用不同场景,比如炼钢厂,需要采用耐高温传感器,煤矿采用防静电传感器等
2、数据传输与存储:跟传感器配套方案,是否采用无线方案,或者是有线传输,都需要根据实际场景来判断,还有这中间是否采用中间网关,做数据转发等。然后就是数据如何存储与处理。这涉及到平台侧的具体框架方案。
3、数据展示:展示方面,为了配合数字孪生这个名词,只能采用3D显示方案。对于3D的方案,光是展时端,我们就可以选择CS、BS两种方式的一种。当然,本篇我们选择BS(webgl)方案。
前两个部分,后面考虑用较详细的文章篇幅详细介绍。本文主要讲解数据展示这一层的方案。
二、展示效果与代码实现
2.1、工业园区整体效果与实现
这里主要是建模,与流光效果的实现。对于非重点监控车间,我们可以用虚拟建筑模型方块代替。
代码实现:
var initOption = {
far:100000000,
antialias: true, // 启用平滑、抗锯齿效果
loadSyn: false, // 是否启用异步加载
showHelpGrid: false, // 是否显示网格线
clearCoolr: 0x4068b0, // 背景色
clearColorOp: 0, // 透明度
};
var AllModelJsons = [];
//获取园区模型;
httpGetSyn("../js/models/build.json", function (rs) {
AllModelJsons = rs;
});
WT3DModel.initWT3D('canvas-frame', initOption, Aobjects);
2.2、双击重点展示工作车间,进入车间
这里采用最简单的页面跳转方式,显示摄像头推进,然后直接跳转到另一个页面,简单而不失流程。还能充分回收资源。
代码实现:
if (_obj.name.indexOf("b1_112_out") >= 0) {//通过模型名称判断
setTimeout(function () {
window.location = ("room.html");
}, 2000);
modelBussiness.nearCameraPostion(_obj, _face);
}
2.3、双击加热炉,展示加热炉内部锻件的详细信息,与位置
这里采用虚化周边的方案。
modelBussiness.currentState = 10; modelBussiness.removeAllMsgs();
modelBussiness.commonFunc.hideAllModels(function () {
if (_obj.name.indexOf("OBJCREN") > 0) {
_obj = WT3DObj.commonFunc.findObject(_obj.name.split("OBJCREN")[0]);
}
if (_obj.oldPositionY) {
_obj.position.y = _obj.oldPositionY;
}
_obj.visible = true;
// modelBussiness.commonFunc.showJRLDetailMsg(_obj, function () { });
var tkname = "jlr_tiekuai_1";
if (_obj.name.indexOf("xsjrl_1135") >= 0) {
tkname = "jlr_tiekuai_1";
} else if (_obj.name.indexOf("xsjrl_1136") >= 0) {
tkname = "jlr_tiekuai_2";
} else if (_obj.name.indexOf("xsjrl_1137") >= 0) {
tkname = "jlr_tiekuai_3";
}
tk = WT3DObj.commonFunc.findObject(tkname);
tk.visible = true;
if (tk.oldPositionY) {
tk.position.y = tk.oldPositionY;
}
WT3DObj.commonFunc.changeObjsOpacity([tk], 0, 1, 100, function () {
});
WT3DObj.commonFunc.changeObjsOpacity([_obj], 0, 0.2, 1000, function () {
modelBussiness.commonFunc.showNetDetail(WT3DObj.commonFunc.findObject(config.Mrelation[_obj.name + "_tiekuai"]));
});
});
2.4、明显标注传感器,并且查看各部位传感器信息。
这里注意绑定传感器数据,并且使用突显方案,显示传感器标签,在任何角度,都能看到传感器位置。
代码实现:
if (_obj.name.indexOf("wycgq_") >= 0) {
$(".jrlDetail").hide();
// name = "位移传感器";
var screenPostion = WT3DObj.commonFunc.transToScreenCoord(_obj.position);
$("#MarkMessageHelper").remove();
$("body").append("<div id='MarkMessageHelper' style='position:absolute;left:" + (screenPostion.x) + "px;top:" + screenPostion.y + "px;height:2px;width:2px;z-index:1000;'></div>");
$("#airConfig2Detail").show();
$("#airConfig2Detail").css("left", $("#MarkMessageHelper").css("left"));
$("#airConfig2Detail").css("top", (parseFloat($("#MarkMessageHelper").css("top")) - 170) + "px"); } else if (_obj.name.indexOf("dajiliybp") >= 0) {
$(".jrlDetail").hide();
// name = "打击力应变片";
var screenPostion = WT3DObj.commonFunc.transToScreenCoord(_obj.position);
$("#MarkMessageHelper").remove();
$("body").append("<div id='MarkMessageHelper' style='position:absolute;left:" + (screenPostion.x) + "px;top:" + screenPostion.y + "px;height:2px;width:2px;z-index:1000;'></div>");
$("#rackDetail").show();
$("#rackDetail").css("left", $("#MarkMessageHelper").css("left"));
$("#rackDetail").css("top", (parseFloat($("#MarkMessageHelper").css("top")) - 170) + "px");
} else if (_obj.name.indexOf("_qiya") >= 0) {
$(".jrlDetail").hide();
var screenPostion = WT3DObj.commonFunc.transToScreenCoord(_obj.position);
//name = "气压传感器";
$("#MarkMessageHelper").remove();
$("body").append("<div id='MarkMessageHelper' style='position:absolute;left:" + (screenPostion.x) + "px;top:" + screenPostion.y + "px;height:2px;width:2px;z-index:1000;'></div>");
$("#upsDetail").show();
$("#upsDetail").css("left", $("#MarkMessageHelper").css("left"));
$("#upsDetail").css("top", (parseFloat($("#MarkMessageHelper").css("top")) - 170) + "px");
} else if (_obj.name.indexOf("yeyacgq_") >= 0) {
$(".jrlDetail").hide();
var screenPostion = WT3DObj.commonFunc.transToScreenCoord(_obj.position);
//name = "液压传感器";
$("#MarkMessageHelper").remove();
$("body").append("<div id='MarkMessageHelper' style='position:absolute;left:" + (screenPostion.x) + "px;top:" + screenPostion.y + "px;height:2px;width:2px;z-index:1000;'></div>");
$("#upsDetail").show();
$("#upsDetail").css("left", $("#MarkMessageHelper").css("left"));
$("#upsDetail").css("top", (parseFloat($("#MarkMessageHelper").css("top")) - 170) + "px");
} else {
$(".jrlDetail").show();
}
三、数据驱动,根据车间实时动作,在三维内展示实时动作
3.1、轨道机械臂,从加热炉中取料
实现代码:
isDoAction = true; var jxb = WT3DObj.commonFunc.findObject("jxbct_369");
var jxbdp = WT3DObj.commonFunc.findObject("jxbdp_373"); if(name=="xsjrl_1135"){
new TWEEN.Tween(jxb.position).to({
x: 7054.110
}, 1000).onComplete(function () {
}).start();
new TWEEN.Tween(jxbdp.position).to({
x: 7054.110
}, 1000).onComplete(function () {
WT3DObj.commonFunc.changeCameraPosition(
{x: 11987.945516911437, y: 5821.875816333479, z: 639.598300399881}, {x: 5418.917462960544, y: -132.7956226536168, z: 2029.241082946989}, 500, function () {
jrlAnimation(700, name)
setTimeout(function () {
jxbAnimation("sc", null, 500);
setTimeout(function () {
jxbAnimation("showtk");
setTimeout(function () {
jxbAnimation("ss");
setTimeout(function () {
WT3DObj.commonFunc.changeCameraPosition(
{ x: 10739.533256704372, y: 4071.9019928732682, z: 4924.279861011403 }, { x: 6579.256577472461, y: 55.12686192176127, z: 1749.5443318108976 }, 500, function () { jxbAnimation("xz");
setTimeout(function () {
jxbAnimation("sc");
setTimeout(function () {
jxbAnimation("hidetk");
WT3DObj.commonFunc.findObject("tiekuai_0").visible = true; setTimeout(function () {
isDoAction = false;
jxbAnimation("ss");
jxbAnimation("backxz");
}, 200);
}, 600);
}, 600);
}); }, 600);
}, 300);
}, 800);
}, 1000);
});
}).start();
}
加热炉动画:
//加热炉
function jrlAnimation(moveLength,name) {
var ylj_1 = WT3DObj.commonFunc.findObject(name?name:"xsjrl_1135").children[19];//394
var ylj_2 = WT3DObj.commonFunc.findObject(name ? name : "xsjrl_1135").children[11];//-112
var ylj_3 = WT3DObj.commonFunc.findObject(name ? name : "xsjrl_1135").children[12];//-112
if (!ylj_1.oldPostionY) {
ylj_1.oldPostionY = ylj_1.position.y;
}
if (!ylj_2.oldPostionY) {
ylj_2.oldPostionY = ylj_2.position.y;
}
if (!ylj_3.oldPostionY) {
ylj_3.oldPostionY = ylj_3.position.y;
}
ylj_1.currentPostionY = ylj_1.position.y;
ylj_2.currentPostionY = ylj_2.position.y;
ylj_3.currentPostionY = ylj_3.position.y; var movePosition = {
y: 0
}
new TWEEN.Tween(movePosition).to({
y: moveLength
}, 500).onUpdate(function () {
ylj_1.position.y = ylj_1.currentPostionY + this.y;
if (ylj_1.position.y < ylj_1.oldPostionY - moveLength) {
ylj_1.position.y =ylj_1.oldPostionY - moveLength
}
ylj_1.matrixAutoUpdate = true;
ylj_2.position.y = ylj_2.currentPostionY + this.y;
if (ylj_2.position.y < ylj_2.oldPostionY - moveLength) {
ylj_2.position.y = ylj_2.oldPostionY - moveLength
}
ylj_2.matrixAutoUpdate = true;
ylj_3.position.y = ylj_3.currentPostionY + this.y;
if (ylj_3.position.y < ylj_3.oldPostionY - moveLength) {
ylj_3.position.y = ylj_3.oldPostionY - moveLength
}
ylj_3.matrixAutoUpdate = true;
}).onComplete(function () { }).start(); }
3.2、机械臂从中间台上取料
实现代码:
case "ql"://取料
isDoAction = true; WT3DObj.commonFunc.findObject("tiekuai_1_1").visible = false;
WT3DObj.commonFunc.findObject("tiekuai_1").visible = false;
WT3DObj.commonFunc.changeCameraPosition(
{ x: 7131.978477911106, y: 2829.502314368439, z: 2197.1946670176567 }, { x: 6411.024615439089, y: 528.9277768783592, z: 856.9774806044239 }, 500, function() {
var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3");
jxb_zz_6_3.visible = true;
var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1");
jxb_zz_6_3_1.visible = false; jxb_zz_6_3A0(function() {
jxb_zz_6_3A01(function() {
isDoAction = false; })
})
});
break;
3.3、机械臂将取到的料放置到压力机下面
实现代码:
case "2":
case "fl"://放料
isDoAction = true;
WT3DObj.commonFunc.changeCameraPosition(
{ x: 7131.978477911106, y: 2829.502314368439, z: 2197.1946670176567 }, { x: 6411.024615439089, y: 528.9277768783592, z: 856.9774806044239 }, 500, function() { jxb_zz_6_3A2(function () {
WT3DObj.commonFunc.findObject("tiekuai_1_1").visible = false;
WT3DObj.commonFunc.findObject("tiekuai_1").visible = true;
jxb_zz_6_3A3(function () {
var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3");
jxb_zz_6_3.visible = false;
var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1");
jxb_zz_6_3_1.visible = true;
jxb_zz_6_3_1.children[4].children[2].children[4].children[10].children[2].children[5].visible = false;
isDoAction = false;
})
});
});
3.4、压力机摧压货料。
代码实现:
case "3":
case "ylj"://压力机打击
isDoAction = true;
var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3");
jxb_zz_6_3.visible = false;
var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1");
jxb_zz_6_3_1.visible = true;
jxb_zz_6_3_1.children[4].children[2].children[4].children[10].children[2].children[5].visible = false;
WT3DObj.commonFunc.changeCameraPosition(
{ x: 7193.942917022709, y: 1335.12023764365, z: 1186.3353004352634 }, { x: 6790.381940272481, y: 763.1919527866438, z: -44.54061049048587 }, 500, function() { yaliji_1126_A1(function () {
isDoAction = false;
}, 0)
});
break;
3.5、机械臂喷雾
这里实现比较简单,本可以用粒子方案,后来为了省事,直接用流体方案实现
case "4":
case "qbjqbcp"://喷雾
isDoAction = true;
var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3");
jxb_zz_6_3.visible = false;
var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1");
jxb_zz_6_3_1.visible = true;
jxb_zz_6_3_1.children[4].children[2].children[4].children[10].children[2].children[5].visible = false;
WT3DObj.commonFunc.changeCameraPosition(
{ x: 6992.126352231225, y: 548.5464812898373, z: 1331.9129698522017 }, { x: 6795.575361553676, y: 631.1769732337358, z: -557.178527158633 }, 500, function() {
pqj_6_1266A2(function() {
WT3DObj.commonFunc.findObject("flowtube_1368").visible = true; setTimeout(function(){ WT3DObj.commonFunc.findObject("flowtube_1368").visible = false;
pqj_6_1266A3(function() {
isDoAction = false;
});
},3000); });
});
break;
3.6、机械臂取出锻件半成品
代码实现:
case "qcyljdj"://取出压力机锻件
WT3DObj.commonFunc.findObject("tiekuai_3").visible = false;
isDoAction = true;
var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3");
jxb_zz_6_3.visible = false;
var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1");
jxb_zz_6_3_1.visible = true;
jxb_zz_6_3_1.children[4].children[2].children[4].children[10].children[2].children[5].visible = false;
WT3DObj.commonFunc.changeCameraPosition(
{ x: 7131.978477911106, y: 2829.502314368439, z: 2197.1946670176567 }, { x: 6411.024615439089, y: 528.9277768783592, z: 856.9774806044239 }, 500, function() {
//
jxb_zz_6_3_1A2(function () { WT3DObj.commonFunc.findObject("tiekuai_1").visible = false;
WT3DObj.commonFunc.findObject("tiekuai_1_1").visible = false;
jxb_zz_6_3_1A3(true,function () {
isDoAction = false;
})
})
});
break;
case "6":
case "fxyljdj"://放下压力机锻件
WT3DObj.commonFunc.findObject("tiekuai_3").visible = false;
isDoAction = true;
var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3");
jxb_zz_6_3.visible = false;
var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1");
jxb_zz_6_3_1.visible = true;
jxb_zz_6_3_1A4(function () {
isDoAction = false;
WT3DObj.commonFunc.findObject("tiekuai_3").visible = true;
jxb_zz_6_3_1A1(function () {
isDoAction = false;
})
})
break;
3.7、机械臂将锻件放置到传送带上
代码实现:
case "7":
case "yd"://移动 var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3");
jxb_zz_6_3.visible = true;
var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1");
jxb_zz_6_3_1.visible = false;
/*
else if (data.conveyorToCut==1) {//传送到切边机
state = "7";
}
*/
isDoAction = true;
WT3DObj.commonFunc.findObject("tiekuai_3").visible = true;
WT3DObj.commonFunc.changeCameraPosition(
{ x: 3088.224325931938, y: 2460.282161815149, z: 3740.1275634657304 }, { x: 4081.729182608692, y: 203.35568280176042, z: 654.5133357334003 }, 500, function() {
tiekuai3_A1(function () {
isDoAction = false;
});
}); break;
3.8、传送带,传送锻件至切边机一侧
case "7":
case "yd"://移动 var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3");
jxb_zz_6_3.visible = true;
var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1");
jxb_zz_6_3_1.visible = false;
/*
else if (data.conveyorToCut==1) {//传送到切边机
state = "7";
}
*/
isDoAction = true;
WT3DObj.commonFunc.findObject("tiekuai_3").visible = true;
WT3DObj.commonFunc.changeCameraPosition(
{ x: 3088.224325931938, y: 2460.282161815149, z: 3740.1275634657304 }, { x: 4081.729182608692, y: 203.35568280176042, z: 654.5133357334003 }, 500, function() {
tiekuai3_A1(function () {
isDoAction = false;
});
}); break;
3.9、机械臂取出锻件,放置到切边机上
case "8":
case "qbjqj"://切边机机取料
/*
else if (data.conveyorToPress == 1 || data.r2ConveyorCatch == 1) {//从传送带抓料子并复原传送带
state = "8";
}
*/
WT3DObj.commonFunc.changeCameraPosition(
{ x: 1176.799334050281, y: 2261.502847148386, z: -3176.64624829932 }, { x: 2172.7062907541617, y: -1082.7207373607675, z: 549.2316313972628 }, 500, function() { jxb_zz_6_795A4(function () {
jxb_zz_6_795A1(function () {
csddzsbbf_1212A2();//复原传送带
isDoAction = false;
});
});
});
break;
case "9":
case "qbjfl"://切边机机放料
/*
if (data.r2SendCut == 1) {//机械臂往切边机送料
state = "9";
} else if (data.cutStrike == 1) {//切边
state = "10";
} else if (data.r2CutCatch == 1) {//取料
state = "11";
} else if (data.r2CutOverlap == 1) {//取飞边
state = "12";
}
*/
WT3DObj.commonFunc.findObject("tiekuai_2").visible = false;
WT3DObj.commonFunc.findObject("tiekuai_2_1").visible = false;
isDoAction = true;
WT3DObj.commonFunc.changeCameraPosition(
{ x: 1176.799334050281, y: 2261.502847148386, z: -3176.64624829932 }, { x: 2172.7062907541617, y: -1082.7207373607675, z: 549.2316313972628 }, 500, function() {
jxb_zz_6_795A2(function () {
WT3DObj.commonFunc.findObject("tiekuai_2").visible = true;
WT3DObj.commonFunc.findObject("tiekuai_2_1").visible = true;
jxb_zz_6_795A3(function() {
isDoAction = false; });
});
});
break;
3.10、切边机,切边
case "10":
case "qbjqb"://切边机切边
isDoAction = true;
WT3DObj.commonFunc.changeCameraPosition(
{ x: 1268.7356763452408, y: 1568.1044843402083, z: -2963.5457047272607 }, { x: 1348.071262611549, y: 377.4064330677588, z: 594.0594238388968 }, 500, function() {
qiebianji_1293_A1(function() {
isDoAction = false; });
});
break;
3.11、取出切好的锻件,放到观测台上观测
case "11":
case "qbjqbcp"://取出成品
WT3DObj.commonFunc.findObject("duanjian_1_2355").visible = false;
isDoAction = true;
WT3DObj.commonFunc.changeCameraPosition(
{ x: 1242.5999280327703, y: 3110.0888878135233, z: -6003.8189588224295 }, { x: 127.35800599694372, y: -857.7840251121656, z: -414.9639298471293 }, 500, function () {
WT3DObj.commonFunc.findObject("tiekuai_2").visible = false;
jxb_zz_6_795A6(function () {
WT3DObj.commonFunc.findObject("duanjian_1_2355").visible = true;
var duanjian_1_2355 = WT3DObj.commonFunc.findObject("duanjian_1_2355");
//duanjian_1_2355.position.y = 577.047;
//duanjian_1_2355.position.x = 1109.776;
duanjian_1_2355.visible = true;
setTimeout(function () {
jxb_zz_6_795A3();
setTimeout(function () {
isDoAction = false;
}, 1000);
}, 1000);
//new TWEEN.Tween(duanjian_1_2355.position).to({
// x: -522.392,
//}, 1500).onUpdate(function () {
//}).onComplete(function () {
// jxb_zz_6_795A3();
// new TWEEN.Tween(duanjian_1_2355.position).to({
// x: -691.733,
// y: 33.214,
// }, 1500).onUpdate(function () {
// }).onComplete(function() {
// isDoAction = false;
// }).start();
//}).start();
});
});
break;
3.12、取出飞边毛料,放到对应的框中
case "12":
case "qbjqbfb"://取出飞边
isDoAction = true; WT3DObj.commonFunc.findObject("tiekuai_2_1").visible = false;
WT3DObj.commonFunc.findObject("tiekuai_2_123").visible = false;
WT3DObj.commonFunc.changeCameraPosition(
{ x: 1242.5999280327703, y: 3110.0888878135233, z: -6003.8189588224295 }, { x: 127.35800599694372, y: -857.7840251121656, z: -414.9639298471293 }, 500, function() { jxb_zz_6_795A5(function() {
isDoAction = false;
WT3DObj.commonFunc.findObject("tiekuai_2_123").visible = true;
jxb_zz_6_795A3();
});
});
break;
技术交流 1203193731@qq.com
交流微信:
如果你有什么要交流的心得 可邮件我
其它相关文章:
使用webgl(three.js)创建3D机房,3D机房微模块详细介绍(升级版二)
如何用webgl(three.js)搭建一个3D库房-第一课
如何用webgl(three.js)搭建一个3D库房,3D密集架,3D档案室,-第二课
使用webgl(three.js)搭建一个3D建筑,3D消防模拟——第三课
使用webgl(three.js)搭建一个3D智慧园区、3D建筑,3D消防模拟,web版3D,bim管理系统——第四课
如何用webgl(three.js)搭建不规则建筑模型,客流量热力图模拟
使用webgl(three.js)搭建一个3D智慧园区、3D建筑,3D消防模拟,web版3D,bim管理系统——第四课(炫酷版一)
使用webgl(three.js)搭建3D智慧园区、3D大屏,3D楼宇,智慧灯杆三维展示,3D灯杆,web版3D,bim管理系统——第六课
如何用webgl(three.js)搭建处理3D园区、3D楼层、3D机房管线问题(机房升级版)-第九课(一)
如何用three.js实现数字孪生、3D工厂、3D工业园区、智慧制造、智慧工业、智慧工厂-第十课的更多相关文章
- 如何用webgl(three.js)搭建一个3D库房,3D仓库,3D码头,3D集装箱可视化孪生系统——第十五课
序 又是快两个月没写随笔了,长时间不总结项目,不锻炼文笔,一开篇,多少都会有些生疏,不知道如何开篇,如何写下去.有点江郎才尽,黔驴技穷的感觉. 写随笔,通常三步走,第一步,搭建框架,先把你要写的内容框 ...
- 如何用webgl(three.js)搭建一个3D库房,3D仓库3D码头,3D集装箱,车辆定位,叉车定位可视化孪生系统——第十五课
序 又是快两个月没写随笔了,长时间不总结项目,不锻炼文笔,一开篇,多少都会有些生疏,不知道如何开篇,如何写下去.有点江郎才尽,黔驴技穷的感觉. 写随笔,通常三步走,第一步,搭建框架,先把你要写的内容框 ...
- 如何用three.js(webgl)搭建3D粮仓、3D仓库、3D物联网设备监控-第十二课
序: 最近因为疫情,居家办公,索性翻翻之前的项目案例,总结总结. 这次疫情,深圳停摆,群众也挺恐慌的,封闭前一天,超市被抢购一空,虽然官方媒体一再强调,材米油盐蔬菜肉类管够,但是任然挡不住群众们的抢购 ...
- 使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课
老子云:有道无术,术尚可求,有术无道,止于术. 咱开篇引用老子的话术,也没其它意思,只是最近学习中忽有感悟,索性就写了上来. 这句话用现代辩证思维理解,这里的"道" 大抵是指方法论 ...
- webgl(three.js)实现室内三维定位,3D定位,3D楼宇bim、实时定位三维可视化解决方案——第十四课(定位升级版)
序: 还是要抽出时间看书的,迷上了豆豆的作品,最近在看<天幕红尘>,书中主人公的人生价值观以及修为都是让我惊为叹止.很想成为那样的人,但是再看看自己每天干的事,与时间的支配情况,真是十分的 ...
- webgl(three.js)3D光伏,3D太阳能能源,3D智慧光伏、光伏发电、清洁能源三维可视化解决方案——第十六课
序: 能源是文明和发展的重要保障,人类命运不可避开的话题,无论是战争还是发展,都有它存在的身影.从石器时代到现代文明,人类的能源应用在进步,也在面临能源枯竭的危机与恐惧,而开发与应用可再生能源才是解决 ...
- 如何使用webgl(three.js)实现3D储能,3D储能站,3D智慧储能、储能柜的三维可视化解决方案——第十七课
前言 上节课我们讲了<3D光伏发电>,与之配套的就是能量存储 这节课我们主要讲讲储能,储能站,在分布式能源系统中起到调节用对电的尖峰平谷进行削峰填谷的作用.特别是小型储能站,更加灵活,因地 ...
- 数字孪生 3D 科技馆的科学传播新模式
前言 科技馆是一种参与型体验型的博物馆,以传播科学知识.培养公众的科学创新技术为宗旨,并以其生动的展现方式得到公众的广泛欢迎.一直以来,我国科技馆的发展受到各种因素的制约和影响,发展缓慢.如今在我国经 ...
- 如何用webgl(three.js)搭建一个3D库房,3D密集架,3D档案室(升级版)
很长一段时间没有写3D库房,3D密集架相关的效果文章了,刚好最近有相关项目落地,索性总结一下 与之前我写的3D库房密集架文章<如何用webgl(three.js)搭建一个3D库房,3D密集架,3 ...
随机推荐
- Git知识总结
Git知识总结 Git安装 windows 在git官网中下载安装程序,然后按默认选项安装即可 安装完成后,在开始菜单里找到"Git"->"Git Bash&quo ...
- [loj3525]喷泉公园
先将整张图$x$和$y$都缩小一半,即"道路"长度变为1,"长椅"变为放在格子中心 如果在没有长椅的限制下也无解(直接dfs即可判定),显然原问题也无解 否则 ...
- 收集的常用的CTF学习资源网站
http://www.sec-wiki.com/skill/ 安全技能学习路线(迷茫就看它) https://wiki.x10sec.org/ 介绍了CTF各个方向的基础知识 ...
- Identity Server 4 从入门到落地(一)—— 从IdentityServer4.Admin开始
最近项目中需要使用Identity Server 4,以前对这个技术只是有些了解,没有系统研究过,网上相关的资料不少,大多是从编写一个简单的认证服务开始,离能够落地使用有相当的距离,理论学习如何不结合 ...
- .net core 3.1 WebAPi 使用 AutoMapper 9.0、10.0
AutoMapper 可以很方便完成数据对象之间的转换. Dto -> Entity Entity -> ViewModel Step 1:通过 NuGet 安装 AutoMapper 的 ...
- 测试平台系列(85) 把redis运用到实战中
大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们让支持了前置条件 ...
- 洛谷 P4135 作诗(分块)
题目链接 题意:\(n\) 个数,每个数都在 \([1,c]\) 中,\(m\) 次询问,每次问在 \([l,r]\) 中有多少个数出现偶数次.强制在线. \(1 \leq n,m,c \leq 10 ...
- SAM 感性瞎扯
SAM 做题笔记. 这里是 SAM 感性瞎扯. 最近学了后缀自动机(Suffix_Automaton,SAM),深感其巧妙之处,故写文以记之. 部分文字与图片来源于 OI-Wiki,hihoCoder ...
- 【GWAS】如何计算显著关联位点的表型解释率PVE(phenotypic variation explained)?
我已经通过Gemma得到了关联分析的结果,如下. prefix.log.txt 中包含了一个总的PVE,这不是我们想要的. 那么,如何计算这些位点的表型解释率? 据了解,有些关联分析软件是可以同时得到 ...
- Hermite WENO 重构格式
Hermite WENO 单元重构 本文主要介绍采用 Hermite WENO 重构方法作为斜率限制器应用于二维或高维单元中. 1.简介[1] ENO格式最早由 Harten 等[2]提出,ENO格式 ...