序:
又是很久沒有更新文章了,這次索性將之前做的三維煤礦項目拿出來講講,一是回顧技術(shù),二是鍛煉一下文筆。
隨著科技的不斷發(fā)展,越來越多的人開始關(guān)注煤礦采集的安全和效率問題。為了更好地展示煤礦采集的過程和效率,可視化展示系統(tǒng)成為了一個非常重要的工具。
本文將介紹一種針對煤礦采集的3D可視化展示系統(tǒng)解決方案,以幫助煤礦企業(yè)更好地了解工程情況,提高效率和安全性。
采煤企業(yè)現(xiàn)在基本都要上三維定位系統(tǒng)。我也總結(jié)總結(jié)之前的項目經(jīng)驗,以便能對需要用到的看官起到一定的拋磚引玉的作用。
閑話少敘,我們切入正題。
前言:
首先我們要了解采煤的簡單知識,這里只做簡單介紹幾種:
掘進面:掘進面又稱掘進迎頭,是指在為回采工作面做準備時,首先開采一條巷道。這條巷道包含探煤、掘煤、探水、探氣等作用,具體說就是一個以掘進為主
縱采面:縱采面一般指全層開采工作面,煤礦中使用同一采煤機在同一煤層中沿煤層走向進行采煤的工作面。
采煤機:它是一種實現(xiàn)煤礦生產(chǎn)機械化的設備,可以從截煤機發(fā)展演變而來。
截煤機:截煤機是一種用來破煤和裝煤的機器,通常用于隧道施工、井下回采和地面選煤廠等場所。
液壓支架:液壓支架是一種用于支撐頂板、控制頂板下沉的設備,可以用來保護礦工的安全和提高生產(chǎn)效率。
破碎機:破碎機是一種用來將大塊煤炭破碎成小塊的設備,通常與輸送帶等配合使用?! ?/p>
輸送帶:輸送帶是一種用于將煤炭從采煤工作面輸送到選煤廠或其他地點的設備,可以根據(jù)需要進行調(diào)整和移動。
裝載機:裝載機是一種用來裝載和運輸煤炭的設備,通常與礦車、輸送帶等配合使用。
在這篇文章中,我們將介紹如何使用Three.js實現(xiàn)煤礦工人3D定位可視化技術(shù)
本次講解的解決方案主要包括以下幾個方面:
-
3D采集模型的建立:采用三維建模技術(shù),建立煤礦采集面的三維模型。模型應包括采集面的地貌、巖石結(jié)構(gòu)、煤炭賦存狀態(tài)等信息,以幫助企業(yè)更直觀地了解采集面的情況。
- 采集面可視化展示系統(tǒng)、
- 掘進面可視化展示系統(tǒng)
- 人員定位跟蹤系統(tǒng)
通過以上各部分的結(jié)合使用,可以形成一個完整的煤礦采集人員定位3D可視化系統(tǒng)。該系統(tǒng)不僅可以實現(xiàn)對采集面和掘進面的實時監(jiān)控和展示,還可以通過數(shù)據(jù)分析和處理,幫助相關(guān)人員更好地了解采集面和掘進面的情況,從而提高采集效率和安全性。
綜上所述,煤礦采集的3D可視化展示系統(tǒng)解決方案是一個完整的系統(tǒng)工程。只有充分整合和利用多種技術(shù)手段,才能為煤礦企業(yè)提供更全面、更準確、更實時的信息。
技術(shù)交流 1203193731@qq.com
交流微信:
如果你有什么要交流的心得 可郵件我
?一、縱采面效果展示
采集面可視化展示系統(tǒng),它通過3D可視化技術(shù),將采集面的情況呈現(xiàn)在虛擬空間中。在這個虛擬空間中,可以實時展示采集面的工作狀態(tài)、工作面長度、采煤機的位置和工作狀態(tài)等信息。這些信息可以通過大屏幕、投影儀等設備進行展示,也可以通過手機、平板電腦等移動設備進行實時查看。
1.1、三維縱拆面整體工作效果
在縱采面工作時,采煤機需要沿著煤層底板或頂板移動,對于煤層頂板需要及時支護,防止出現(xiàn)冒頂事故
?
這里涉及到了縱采機,液壓支架,傳輸帶等等多方位全自動采集系統(tǒng)可視化監(jiān)測。
1.2、縱采面人員定位
依據(jù)定位設備,實時采集人員信息與人員位置再采集面內(nèi)的具體情況。
?
?
?二、掘進面可視化三維效果
?
?2.1、掘進面工作情況模擬
掘進面可視化展示系統(tǒng)是在采集面可視化展示系統(tǒng)的基礎上,針對掘進面的特殊情況進行設計的。在這個虛擬空間中,可以實時展示掘進面的工作狀態(tài)、工作面長度、掘進機的位置和工作狀態(tài)等信息。
?2.2、掘進面人員定位可視化方案
掘進面的位置一般處于煤礦的地下深處,周圍環(huán)境比較復雜,有許多不利因素,如斷層、水體、火山噴發(fā)等,這些因素可能會對掘進面的安全和煤炭的采集造成威脅
為了保障工作進度與人員安全,在每臺機器設備上安裝了定位系統(tǒng),當人員靠近危險區(qū)域時,設備報警、自動啟停。
? 上圖中展示了工程車的安全區(qū)域范圍,不同顏色不同警示作用。
三、人員定位系統(tǒng)。
? 人員定位跟蹤系統(tǒng)則是對井下工作人員的安全負責,實時監(jiān)控人員位置。
? 3.1、整體礦區(qū)結(jié)構(gòu)布局三維展示
?
?3.2、整體實時查看各工作面進度情況
?
?3.3、實時定位人員位置,展示人員信息
?3.4、定位設備展示。
?
3.5、人員跟蹤與行動路徑回放
?四、技術(shù)架構(gòu)與實現(xiàn)
4.1、建模
首先對煤礦的各種設備、以及煤礦本身的布局進行建模,這里更注重成本與安全監(jiān)測,所以采用了L1示意模型
考慮到系統(tǒng)性能,對于煤礦布局,采用代碼模型生成。
例如掘進面環(huán)境模型就采用代碼模型的方式
{"show":true,"uuid":"","name":"wall_3","objType":"ExtrudeGeometry","position":{"x":2764.646,"y":0,"z":2000},"style":{"skinColor":16711680,"skin":{"skin_up":{"skinColor":16777215,"side":1,"opacity":1,"imgurl":"../img/3dImg/wall/mt.jpg","repeatx":true,"width":0.0002,"repeaty":true,"height":0.0002},"skin_down":{"skinColor":16711680,"side":1,"opacity":1},"skin_side":{"skinColor":16777215,"opacity":1,"imgurl":"../img/3dImg/wall/shuini2.jpg","repeatx":true,"width":0.002,"repeaty":true,"height":0.002}}},"scale":{"x":1,"y":1,"z":1},"shapeParm":{"points":[{"x":-55000,"y":0,"type":"nomal"},{"x":-55000,"y":10000,"type":"nomal"},{"x":55000,"y":10000,"type":"nomal"},{"x":55000,"y":0,"type":"nomal"}],"holes":[]},"extrudeSettings":{"amount":2000,"curveSegments":2,"steps":2,"bevelEnabled":true,"bevelThickness":1,"bevelSize":1,"bevelSegments":2,"extrudePathPoints":[]},"showSortNub":7,"customType1":"","customType2":"","animation":null,"dbclickEvents":null,"rotation":[{"direction":"x","degree":-1.5707963267948966},{"direction":"y","degree":0},{"direction":"z","degree":-1.5707963267948966}],"BindDevId":null,"BindDevName":null,"devInfo":null,"BindMeteId":null,"BindMeteName":null}
?
4.2、數(shù)據(jù)傳輸
這里更注重數(shù)據(jù)實時性,所以采用websoket長連接方式。
WebAPI.prototype.createWebsocket = function () { var myWebSocket = new WebSocket(webapi.wsurl); myWebSocket.onopen = function (openEvent) { var params = { action: "test", }; myWebSocket.send(JSON.stringify(params)); }; myWebSocket.onmessage = function (messageEvent) { console.log(messageEvent); if (messageEvent.data && messageEvent.data != "連接成功") { var alarmData = JSON.parse(messageEvent.data); webapi.handlerAlarms(alarmData.data, true); } }; myWebSocket.onerror = function (errorEvent) { }; myWebSocket.onclose = function (closeEvent) { } return myWebSocket; } WebAPI.prototype.startWebsocket = function () { if (window.WebSocket == null) { alert("not support WebSocket"); } else { wsSocket = webapi.createWebsocket(); /* CONNECTING (0) Default OPEN (1) CLOSING (2) CLOSED (3) */ setInterval(function () { if (wsSocket.readyState == 1) { wsSocket.send("heartbeat"); } else { wsSocket = webapi.createWebsocket(); } }, 10000); } }
?
? 4.3、業(yè)務邏輯
? 由于篇幅原因,這篇我們先簡單描述,后續(xù)篇幅再做詳細講述
4.3.1、?加載歷史軌跡經(jīng)過的分站
?
/* readers:[{ "cardreaderId":3,//分站號 "crname":"1號罐底3采方向",//分站名稱 "x":23097,//二維長 "y":16885,//二維寬 "z":0,//三維高 angle:45//三維角度 "ground":0,//0:地上設備;1地下設備 "areaName":null//所在區(qū)域名稱 "checkreader":3//3為F2分站,其他F1分站 },{...},...] */ var ReadersCacheData = null; function loadReaders(readers) { ReadersCacheData = readers; modelBussiness.LoadReader(readers); }
ModelBussiness.prototype.ReaderLogoNames=[]; ModelBussiness.prototype.LoadReader = function (data) { var _this = this; var timelong = 1; if (_this.ReaderLogoNames && _this.ReaderLogoNames.length > 0) { _this.cleanReaders(); timelong = 500; } setTimeout(function () { if (data && data.length > 0) { $.each(data, function (_index, _obj) { var position = transPositionFrom2To3(_obj.x, _obj.y); var img = config.DevTypes.reader.img; if (_obj.checkreader==3) { img = config.DevTypes.reader2.img; } _this.ReaderLogoNames.push("dev_reader_logo_" + _obj.cardreaderId); _this.commonFunc.addMark("dev_reader_logo_" + _obj.cardreaderId, position, img, config.DevTypes.reader.size, function (_modelObj) { _modelObj.dataValue = _obj; _modelObj.visible = (config.DevTypes.reader.img == img ? indexPage.showTypes.reader : indexPage.showTypes.reader2); modelBussiness.showMsgs(_modelObj); }); }); _this.loadReaderModels(data); } }, timelong); }
4.3.2、加載歷史行走軌跡記錄,人/車模型設置在初始位置
?
/* *positions:[{ startTime:"2020-01-15 18:00:00",//進入時間 endTime:"2020-01-15 19:10:00",//離開時間 stayTime:"1小時10分",//停留時間 Position:"(104)102輔運900米",//當前位置 distanceA:100, distanceB:350,//最大活動范圍:距A天線100米~距B天線350米 coors:[[x,y],...[x,y]]//數(shù)組中最后一個坐標點為當前記錄的目標點,前面坐標為拐點 hasLine,//true:按照coors行走,false:直接跳到coors },...] 加載歷史行走軌跡記錄,人/車模型設置在初始位置, 并設置起點標記,模型頭頂信息框顯示第一條記錄信息 */ var drawBackLogoObj = null;//人車logo var drawBackModelObj = null;//人車模型 var PositionCacheData = null; var moveSpeed = 5; var moveIndex = 0; function loadPositions(positions) { moveIndex = 0; if (drawBackLogoObj) { WT3DObj.destoryObj(drawBackLogoObj.name); drawBackLogoObj = null; } if (drawBackModelObj) { WT3DObj.destoryObj(drawBackModelObj.name); drawBackModelObj = null; } modelBussiness.removeAllMsgs(); PositionCacheData = positions; if (positions && positions.length > 0) { if (!drawBackLogoObj) { //創(chuàng)建LOGO對象 var type ="people"; if(positions[0]&&positions[0].cardType){ type = positions[0].cardType; } var workType = ""; if (positions[0] && positions[0].workType) { workType = positions[0].workType; } var position = transPositionFrom2To3(positions[0].coors[0][0], positions[0].coors[0][1]); modelBussiness.commonFunc.addMark("dev_card_" + type+"_logo_1", position, config.DevTypes[type].img2, config.DevTypes[type].size, function (_modelObj) { drawBackLogoObj = _modelObj; _modelObj.visible = true; new TWEEN.Tween(WT3DObj.controls.target).to({ x: drawBackLogoObj.position.x, y: drawBackLogoObj.position.y, z: drawBackLogoObj.position.z }, 200).onComplete(function () { new TWEEN.Tween(WT3DObj.camera.position).to({ x: drawBackLogoObj.position.x, y: drawBackLogoObj.position.y + 20000, z: drawBackLogoObj.position.z }, 200).onComplete(function () { modelBussiness.showCardMsg(_modelObj, positions[0]); }).start(); }).start(); }); //創(chuàng)建模型對象 //由于人物模型加載比較慢,這里判斷 用圖標來預判 { position.y = 500; if (modelBussiness.readersData["reader_" + ReadersCacheData[0].cardreaderId] && modelBussiness.readersData["reader_" + ReadersCacheData[0].cardreaderId].floor) { position.y = (modelBussiness.readersData["reader_" + ReadersCacheData[0].cardreaderId].floor - 1) * 500 + 10; } var model = createPeople("dev_card_" + type + "_Model_1", position, { x: 0, y: 0, z: 0 }, { x: 0.5, y: 0.5, z: 0.5 }, type); if (type == "car") { model = createCarModel("dev_card_" + type + "_Model_1", position, { x: 0, y: 0, z: 0 }, { x: 0.025, y: 0.025, z: 0.025 }, workType); } WT3DObj.commonFunc.loadModelsByJsons([model], { x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0 }, true, function () { drawBackModelObj = WT3DObj.commonFunc.findObject("dev_card_" + type + "_Model_1"); if (drawBackModelObj) { changePosition(drawBackModelObj); drawBackModelObj.visible = true; if (drawBackModelObj && drawBackModelObj.children && drawBackModelObj.children.length > 0) { drawBackModelObj.children[0].visible = false; } } setTimeout(function () { if (!drawBackModelObj) { drawBackModelObj = WT3DObj.commonFunc.findObject("dev_card_" + type + "_Model_1"); } if (drawBackModelObj) { changePosition(drawBackModelObj); drawBackModelObj.visible = true; } }, 1500); setTimeout(function () { if (!drawBackModelObj) { drawBackModelObj = WT3DObj.commonFunc.findObject("dev_card_" + type + "_Model_1"); } if (drawBackModelObj) { changePosition(drawBackModelObj); drawBackModelObj.visible = true; } }, 3000); setTimeout(function () { if (!drawBackModelObj) { drawBackModelObj = WT3DObj.commonFunc.findObject("dev_card_" + type + "_Model_1"); } if (drawBackModelObj) { changePosition(drawBackModelObj); drawBackModelObj.visible = true; } }, 5000); }); } } } }
4.2.3、回放
/* 開始回放:自動清除歷史回放軌跡、結(jié)束標記,人、車回到初始位置,設置起點標記, 模型頭頂?shù)谝粭l記錄信息,地圖放大到模型前,向下一條記錄行走,到達目的地后, 頭頂信息變?yōu)槟康男畔?,把此時的記錄index傳給回調(diào),停留1秒后, 繼續(xù)下一條記錄,如果到達最后一條記錄,設置終點標記,地圖縮小到全局。 */ var runState = 0; var pIndex = 0; var coorsinnerIndex = 0; var pCallBack = null; function registerReceived(callback){ pCallBack = callback; } function startReplay(callBack) { if (runState == 1) { return; } if (!PositionCacheData) { layer.msg("數(shù)據(jù)異常"); return; } //清理初始化 var position = transPositionFrom2To3(PositionCacheData[0].coors[0][0], PositionCacheData[0].coors[0][1]); if (drawBackLogoObj) { drawBackLogoObj.position.x = position.x; drawBackLogoObj.position.z = position.z; } if (drawBackModelObj) { drawBackModelObj.position.x = position.x; drawBackModelObj.position.z = position.z; } modelBussiness.colseDrawLine(); modelBussiness.removeAllMsgs(); modelBussiness.showCardMsg(drawBackModelObj, PositionCacheData[0]); runState = 1; pIndex = 0; doRunReplay(pCallBack); }
4.3.4、實時移動
//實時移動 /* 1)exactCardInfos下的卡顯示在相應坐標處, inexactCardInfos下的卡顯示(可設置隱藏)在分站的坐標處, locatorCardInfos下的卡顯示(可設置隱藏)在定位器的坐標處,不同的類型顯示不同的模型。 2)分站上顯示exactCardInfo+inexactCardInfos的人數(shù)(people+leader+visitor)車數(shù)(car), 定位器上顯示locatorCardInfos的人數(shù)(people+leader+visito)車數(shù)(car) */ var cacheData = null; var lastRedalarmModelsNames = null; var lastYellowalarmModelsNames = null; var hasNoLoadedReaders = true; function parser(data) { if (hasNoLoadedReaders) { return; } cacheData = data; var redalarmModelsNames = []; var yellowalarmModelsNames = []; if (data) { if (data.readerInfos) { var exCards = []; $.each(data.readerInfos, function (_index, _readerobj) { var carNubs = 0; var personNubs = 0; if (_readerobj.exactCardInfos && _readerobj.exactCardInfos.length > 0) { //精確定位卡list, $.each(_readerobj.exactCardInfos, function (_exindex, _exobj) { if (_exobj.cardType == "car") { carNubs++; } else { personNubs++; } }); exCards = exCards.concat(_readerobj.exactCardInfos); } if (_readerobj.inexactCardInfos && _readerobj.inexactCardInfos.length > 0) { //精確定位卡list, $.each(_readerobj.inexactCardInfos, function (_inexindex, _inexobj) { if (_inexobj.cardType == "car") { carNubs++; } else { personNubs++; } }); } $("#f_reader_" + _readerobj.deviceId + "_peopleNub").html(personNubs); $("#f_reader_" + _readerobj.deviceId + "_carNub").html(carNubs); //$("div[id^='reader_msg_']").hide(); var deviceType = null; if (modelBussiness.readerCache&&modelBussiness.readerCache["id_" + _readerobj.deviceId]) { deviceType = modelBussiness.readerCache["id_" + _readerobj.deviceId].checkreader; } if (deviceType && deviceType == 4) { if (indexPage.showTypes.reader3) { if ((personNubs > 0 || carNubs > 0) && (WT3DObj.camera.position.y > 5000)) { $("#reader_msg_" + _readerobj.deviceId).show(); } else { $("#reader_msg_" + _readerobj.deviceId).hide(); } } else { $("#reader_msg_" + _readerobj.deviceId).hide(); } } else if (deviceType && deviceType == 3) { if (indexPage.showTypes.reader2) { if ((personNubs > 0 || carNubs > 0) && (WT3DObj.camera.position.y > 5000)) { $("#reader_msg_" + _readerobj.deviceId).show(); } else { $("#reader_msg_" + _readerobj.deviceId).hide(); } } else { $("#reader_msg_" + _readerobj.deviceId).hide(); } } else { if (indexPage.showTypes.reader) { if ((personNubs > 0 || carNubs > 0) && (WT3DObj.camera.position.y > 5000)) { $("#reader_msg_" + _readerobj.deviceId).show(); } else { $("#reader_msg_" + _readerobj.deviceId).hide(); } } else { $("#reader_msg_" + _readerobj.deviceId).hide(); } } var alarmDid = _readerobj.deviceId; var LogoModelName = "dev_reader_logo_" + alarmDid; var ModelName = "dev_readerModel_" + alarmDid; //斷線 if (_readerobj.interrupt) { redalarmModelsNames.push(LogoModelName); redalarmModelsNames.push(ModelName); } //斷線 if (_readerobj.lowVolt) { yellowalarmModelsNames.push(LogoModelName); yellowalarmModelsNames.push(ModelName); } }); modelBussiness.AddCards(exCards); } if (data.locatorInfos) { $.each(data.locatorInfos, function (_index, _locatorobj) { var carNubs = 0; var personNubs = 0; if (_locatorobj.locatorCardInfos && _locatorobj.locatorCardInfos.length > 0) { //精確定位卡list, $.each(_locatorobj.locatorCardInfos, function (_locindex, _locobj) { if (_locobj.cardType == "car") { carNubs++; } else { personNubs++; } }); } $("#f_loc_" + _locatorobj.deviceId + "_peopleNub").html(personNubs); $("#f_loc_" + _locatorobj.deviceId + "_carNub").html(carNubs); // $("div[id^='locator_msg_']").hide(); if (indexPage.showTypes.locator) { if ((personNubs > 0 || carNubs > 0) && (WT3DObj.camera.position.y > 5000)) { $("#locator_msg_" + _locatorobj.deviceId).show(); } else { $("#locator_msg_" + _locatorobj.deviceId).hide(); } } else { $("#locator_msg_" + _locatorobj.deviceId).hide(); } }); } } var redfalshTime = 1; if (lastRedalarmModelsNames && lastRedalarmModelsNames.length > 0) { redfalshTime = 200; WT3DObj.commonFunc.flashObjsByName(lastRedalarmModelsNames, "redFlashAlarm", 0x000000, -1, 100, 0) } var yellowfalshTime = 1; if (lastYellowalarmModelsNames && lastYellowalarmModelsNames.length > 0) { WT3DObj.commonFunc.flashObjsByName(lastYellowalarmModelsNames, "yellowFlashAlarm", 0x000000, -1, 100, 0) yellowfalshTime =200; } setTimeout(function () { if (redalarmModelsNames && redalarmModelsNames.length > 0) { WT3DObj.commonFunc.flashObjsByName(redalarmModelsNames, "redFlashAlarm", 0xff0000, 3, 500, 0) } }, redfalshTime); setTimeout(function () { if (yellowalarmModelsNames && yellowalarmModelsNames.length > 0) { WT3DObj.commonFunc.flashObjsByName(yellowalarmModelsNames, "yellowFlashAlarm", 0xffff00, 3, 500, 0) } }, yellowfalshTime); lastRedalarmModelsNames=redalarmModelsNames; lastYellowalarmModelsNames=yellowalarmModelsNames; }
?
?由于篇幅原因,我們本節(jié)課先到這里,
技術(shù)交流 1203193731@qq.com
交流微信:
如果你有什么要交流的心得 可郵件我
其它相關(guān)文章:
webgl(three.js)3D光伏,3D太陽能能源,3D智慧光伏、光伏發(fā)電、清潔能源三維可視化解決方案——第十六課
如何用webgl(three.js)搭建一個3D庫房,3D倉庫3D碼頭,3D集裝箱,車輛定位,叉車定位可視化孿生系統(tǒng)——第十五課
webgl(three.js)實現(xiàn)室內(nèi)三維定位,3D定位,3D樓宇bim、實時定位三維可視化解決方案——第十四課(定位升級版)
使用three.js(webgl)搭建智慧樓宇、設備檢測、數(shù)字孿生——第十三課
如何用three.js(webgl)搭建3D糧倉、3D倉庫、3D物聯(lián)網(wǎng)設備監(jiān)控-第十二課
如何用webgl(three.js)搭建處理3D隧道、3D橋梁、3D物聯(lián)網(wǎng)設備、3D高速公路、三維隧道橋梁設備監(jiān)控-第十一課
如何用three.js實現(xiàn)數(shù)字孿生、3D工廠、3D工業(yè)園區(qū)、智慧制造、智慧工業(yè)、智慧工廠-第十課
使用webgl(three.js)創(chuàng)建3D機房,3D機房微模塊詳細介紹(升級版二)
如何用webgl(three.js)搭建一個3D庫房-第一課
如何用webgl(three.js)搭建一個3D庫房,3D密集架,3D檔案室,-第二課
使用webgl(three.js)搭建一個3D建筑,3D消防模擬——第三課
使用webgl(three.js)搭建一個3D智慧園區(qū)、3D建筑,3D消防模擬,web版3D,bim管理系統(tǒng)——第四課
如何用webgl(three.js)搭建不規(guī)則建筑模型,客流量熱力圖模擬
?使用webgl(three.js)搭建一個3D智慧園區(qū)、3D建筑,3D消防模擬,web版3D,bim管理系統(tǒng)——第四課(炫酷版一)
使用webgl(three.js)搭建3D智慧園區(qū)、3D大屏,3D樓宇,智慧燈桿三維展示,3D燈桿,web版3D,bim管理系統(tǒng)——第六課
如何用webgl(three.js)搭建處理3D園區(qū)、3D樓層、3D機房管線問題(機房升級版)-第九課(一)文章來源:http://www.zghlxwxcb.cn/news/detail-710541.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-710541.html
到了這里,關(guān)于如何使用webgl(three.js)實現(xiàn)煤礦隧道、井下人員定位、掘進面、縱采面可視化解決方案——第十九課(一)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!