国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

AR室內(nèi)導(dǎo)航-Three.js

這篇具有很好參考價值的文章主要介紹了AR室內(nèi)導(dǎo)航-Three.js。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

概述

如有不明白的可以加QQ:2354528292;wx: aichitudousien
更多教學(xué)視頻請訪問:https://space.bilibili.com/236087412
源碼獲?。篽ttps://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.3c3a645ebB8H6o&ft=t&id=714574529746

這一次的AR室內(nèi)導(dǎo)航是使用蜂鳥云地圖加上three.js做的,具備室內(nèi)樓層切換,2D/3D模型切換,指北針控件,AR開啟/關(guān)閉。模擬室內(nèi)導(dǎo)航的功能,先來看看視頻效果

AR室內(nèi)導(dǎo)航

初始化室內(nèi)地圖

初始化蜂鳥云室內(nèi)地圖很簡單,使用的也是蜂鳥云自帶的地圖數(shù)據(jù)
vue文件中調(diào)用mapCreate創(chuàng)建地圖

this.$nextTick(() => {
        this.mapCreate();
});

地圖配置參數(shù),需要自己去創(chuàng)建key值

options: {
          appName: '蜂鳥研發(fā)SDK_2_0',
          key: '',
          mapID: '1321274646113083394',
          // 縮放級別
          mapZoom: 20,
          // 顯示樓層
          visibleLevels: [1, 2, 3, 4, 5],
          // 默認顯示幾樓
          level: 3
        }

window.map = new fengmap.FMMap(this.options);

此時地圖創(chuàng)建顯示成功
AR室內(nèi)導(dǎo)航-Three.js

創(chuàng)建樓層控件

地圖創(chuàng)建完成后生成樓層控件,指北針,導(dǎo)航控件

//監(jiān)聽地圖加載完成
        map.on('loaded', () => {
          //創(chuàng)建導(dǎo)航對象
          this.creatNavigation();
          //創(chuàng)建樓層控件
          this.creatFloorControl();
          //創(chuàng)建指北針控件
          this.creatCompassControl();
        });

樓層控件

creatFloorControl() {
        let toolbar = new fengmap.FMToolbar({
          //默認在右上角
          position: fengmap.FMControlPosition.RIGHT_TOP,
          //初始是否是多層顯示,默認單層顯示
          allLayer: false,
          //是否顯示多層/單層切換按鈕
          needAllLayerBtn: true,
          //控件位置x,y的偏移量
          offset: {
            x: -10,
            y: 320
          }
        });
        toolbar.addTo(map);
      },

指北針

let compass = new fengmap.FMCompass({
          position: fengmap.FMControlPosition.LEFT_TOP,
          width: 40,
          height: 40,
          offset: {
            x: 12,
            y: 460
          }
        });
        compass.addTo(map);
        compass.on('click', function() {
          map.setRotation({
            rotation: 0,
            animate: true,
            duration: 0.3
          });
        });

導(dǎo)航控件

// FMNaviAnalyser 是可分析最短路徑、最快路徑并返回分析結(jié)果的路徑類。可獨立于地圖工作,支持Web Worker 和 Node
        let analyser = new fengmap.FMNaviAnalyser(
          this.options,
          function() {
            // FMNavigation 是導(dǎo)航相關(guān)的功能類, 可用于模擬導(dǎo)航和真實導(dǎo)航使用
            window.navi = new fengmap.FMNavigation({
              map: map,
              analyser: analyser,
              locationMarkerUrl: './img/導(dǎo)航.png',
              locationMarkerSize: 32
            });
          },
          (error) => {
            console.log(error);
          }
        );

AR室內(nèi)導(dǎo)航-Three.js
此時就可以切換樓層顯示和控制2D/3D轉(zhuǎn)換

導(dǎo)航

一個輸入開始地址和結(jié)束地點的UI,隨便寫寫就ok
AR室內(nèi)導(dǎo)航-Three.js
然后需在地圖點擊時輸入起始點和終點,需要在地圖上綁定點擊事件
isNavBoxShow 為組件顯示狀態(tài),startPointSelect 為起始點狀態(tài),endPointSelect 為結(jié)束點狀態(tài)

// //路徑規(guī)劃
        map.on('click', (event) => {
          if (this.$store.state.isNavBoxShow === true) {
            if (this.$store.state.startPointSelect === true) {
              window.routeOpiton.start = {
                x: event.coords.x,
                y: event.coords.y,
                level: event.targets[0].level,
                url: './img/start.png',
                height: 3
              };
              navi.setStartPoint(window.routeOpiton.start);
              if (event.targets[0].name) {
                document.getElementById('startInput').value = event.targets[0].name;
              } else {
                document.getElementById('startInput').value = '當(dāng)前起點位置';
              }
              this.$store.commit('startPointSelectFalse');
            } else if (this.$store.state.endPointSelect === true) {
              window.routeOpiton.end = {
                x: event.coords.x,
                y: event.coords.y,
                level: event.targets[0].level,
                url: './img/end.png',
                height: 3
              }
              navi.setDestPoint(window.routeOpiton.end);

              if (event.targets[0].name) {
                document.getElementById('endInput').value = event.targets[0].name;
              } else {
                document.getElementById('endInput').value = '當(dāng)前終點位置';
              }
              this.$store.commit('endPointSelectFalse');
            }
          }
        });

此時我們點擊地圖模塊就可以輸入起始點和結(jié)束點了
AR室內(nèi)導(dǎo)航-Three.js
點擊確定后調(diào)用路徑計算函數(shù)
window.routeOpiton 為起始點和結(jié)束點對象

navi.route(window.routeOpiton, function(result) {
          let line = navi.drawNaviLine();
          let coordinates = [];
          result.subs.forEach(item => {
            item.waypoint.points.forEach(point => {
              coordinates.push(point)
            })
          });
 })

AR室內(nèi)導(dǎo)航-Three.js

使用Three.js 生成AR模塊原理

說明一下生成步驟,第一步同樣是先驗證是否能打開攝像頭,然后初始化Three.js,然后將攝像頭的視頻流使用video貼圖map到three.js的背景中,這樣就可以呈現(xiàn)了,然后怎么在場景中顯示路徑呢,也不難,蜂鳥云的api會返回一條最短路徑的數(shù)組,通過這個最短路徑的數(shù)據(jù)我們就可以計算,首先判斷每一個點之間的距離是否大于1,如何計算兩點之間的距離呢,通過兩點的的平方開根就好了,計算出后大于1的就是存在有轉(zhuǎn)角的,這時我們就要計算角度了,角度通過反正切來計算,這里需要注意的是軸的旋轉(zhuǎn)方向,最后在監(jiān)聽陀螺儀來改變生成的點和線的角度就可以了,整體來說思路ok了接下來就是變成代碼就行了,實現(xiàn)代碼不難,主要是思路~

初始化Three

//初始參數(shù)
    canvas = document.getElementById('webGL3d')
    arWidth = canvas.offsetWidth
    arHeight = canvas.offsetHeight
    scene = new THREE.Scene()
    camera = new THREE.PerspectiveCamera(60, arWidth / arHeight, 0.0001, 7000)
    camera.position.set(0, -7, 5)
    // //renderer參數(shù)
    let renderParam = {
      antialias: true, // true/false表示是否開啟反鋸齒
      // alpha: true, // true/false 表示是否可以設(shè)置背景色透明
      precision: 'highp', // highp/mediump/lowp 表示著色精度選擇
      premultipliedAlpha: false, 
      maxLights: 3, 
      canvas: canvas 
    }
    renderer = new THREE.WebGLRenderer(renderParam)
    renderer.setSize(arWidth, arHeight)
    orbitControls = new OrbitControls(camera, renderer.domElement)

判斷是否支持攝像頭并返回視頻流,這里有一個小細節(jié),判斷是否是手機還是PC,手機強制使用后置攝像頭

let video = document.createElement('video');
  // navigator.mediaDevices.getUserMedia 提示用戶給予使用媒體輸入的許可,媒體輸入會產(chǎn)生一個MediaStream,里面包含了請求的媒體類型的軌道。

  const stream = await navigator.mediaDevices.getUserMedia({
    // 關(guān)閉音頻
    audio: false,
    video: {
      // 在移動設(shè)備上面,表示優(yōu)先使用前置攝像頭
      // facingMode: 'user',
      facingMode: isMobile() ? { exact: "environment" } : 'user',
      width: width,
      height: height
    }
  });

  video.srcObject = stream;
  video.play();
  video.width = width;
  video.height = height;

  return new Promise((resolve) => {
    // 在視頻的元數(shù)據(jù)加載后執(zhí)行 JavaScript
    video.onloadedmetadata = () => {
      resolve(video);
    };
  });
function isMobile() {
  const isAndroid = /Android/i.test(navigator.userAgent);
  const isiOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
  return isAndroid || isiOS;
}

獲取到視頻流后將視頻貼到three.js的背景中

let video = await openCamera(arWidth, arHeight);
    console.log(video);
    videoTexture = new THREE.Texture(video);
    videoTexture.minFilter = THREE.LinearFilter;
    scene.background = videoTexture;

這里我們就可以在看到視頻了
接著我們創(chuàng)建一個起始點標(biāo)記

let plane = new THREE.PlaneGeometry(1, 1)
    let map = new THREE.TextureLoader().load(require('@/assets/img/WechatIMG1129.png'))
    let material = new THREE.MeshBasicMaterial({
      map: map,
      alphaTest: 0.1,
      color: 0xffffff,
      side: THREE.DoubleSide,
    })
    nowPosPic = new THREE.Mesh(plane, material)
    nowPosPic.position.set(0, offsetY, 0)
    scene.add(nowPosPic)
    //添加坐標(biāo)軸
    let axes = new THREE.AxesHelper(500)
    scene.add(axes)

AR室內(nèi)導(dǎo)航-Three.js
繪制導(dǎo)航線

if (coordinates.length !== 0) {
      group = new THREE.Group()
      let starPoint = {
        x: 0,
        y: 0
      }
      for (let i = 1; i < coordinates.length; i++) {
        let x = coordinates[i].x - coordinates[0].x
        let y = coordinates[i].y - coordinates[0].y
        // 計算兩點的距離
        let distance = Math.sqrt(Math.pow(x - starPoint.x, 2) + Math.pow(y - starPoint.y, 2))
        if (distance >= 1) {
        // 計算弧度
          let angle = calAngleX(x - starPoint.x, y - starPoint.y)
          // 生成線
          createLine(starPoint, distance, angle)
          starPoint.x = x
          starPoint.y = y
        }
      }
      scene.add(group)
      group.position.y = offsetY
      group.rotation.z = -alpha * Math.PI / 180
    }

計算弧度代碼

//計算偏轉(zhuǎn)角度(X逆時針)
  function calAngleX(x, y) {
    let angle = Math.atan(Math.abs(y) / Math.abs(x))
    if (x >= 0 && y >= 0) {

    } else if (x <= 0 && y >= 0) {
      angle = Math.PI - angle
    } else if (x <= 0 && y <= 0) {
      angle = Math.PI + angle
    } else {
      angle = Math.PI * 2 - angle
    }
    return angle
  }

生成線

let plane = new THREE.PlaneGeometry(1, 1)
    let map = new THREE.TextureLoader().load(require('@/assets/img/WechatIMG1123.png'))
    let material = new THREE.MeshBasicMaterial({
      map: map,
      alphaTest: 0.1,
      color: 0xffffff,
      side: THREE.DoubleSide,
    })
    for (let i = 0.6; i <= length; i++) {
      let mesh = new THREE.Mesh(plane, material)
      let x = starPoint.x + i * Math.cos(angle)
      let y = starPoint.y + i * Math.sin(angle)
      mesh.position.set(x, y, 0)
      let obj = {
        x: x + coordinates[0].x,
        y: y + coordinates[0].y
      }
      lingMeshArray.push(obj)
      mesh.rotation.z = angle - Math.PI / 2
      group.add(mesh)
    }

到這里就可以看到生成的線了
AR室內(nèi)導(dǎo)航-Three.js
監(jiān)聽陀螺儀window.DeviceOrientationEvent
window.DeviceOrientationEvent說明
DeviceOrientationEvent.absolute 只讀
用來說明設(shè)備是提供的旋轉(zhuǎn)數(shù)據(jù)是否是絕對定位的布爾值。
DeviceOrientationEvent.alpha 只讀
一個表示設(shè)備繞z軸旋轉(zhuǎn)的角度(范圍在0-360之間)的數(shù)字
DeviceOrientationEvent.beta 只讀
一個表示設(shè)備繞x軸旋轉(zhuǎn)(范圍在-180到180之間)的數(shù)字,從前到后的方向為正方向。
DeviceOrientationEvent.gamma 只讀
一個表示設(shè)備繞y軸旋轉(zhuǎn)(范圍在-90到90之間)的數(shù)字,從左向右為正方向。
throttle只是節(jié)流函數(shù)

if (window.DeviceOrientationEvent) {
      window.addEventListener('deviceorientation', throttle(setMeshCamera, 100), false)
    } else {
      console.log('你的瀏覽器不支持陀螺儀')
    }

最后根據(jù)陀螺儀計算起始點和線的旋轉(zhuǎn)角度就可以了文章來源地址http://www.zghlxwxcb.cn/news/detail-400003.html

到了這里,關(guān)于AR室內(nèi)導(dǎo)航-Three.js的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 基于視覺重定位的室內(nèi)AR導(dǎo)航APP的大創(chuàng)項目思路(1):最初的項目思路(SLAM)

    前情提要: 是第一次做項目的小白,文章內(nèi)的資料介紹如有錯誤,請多包含! 由于我們在日常生活中,大多會在手機端上使用到地圖導(dǎo)航這一功能,所以在大創(chuàng)項目的開始, 我將手機確定為應(yīng)用設(shè)備,傳感器確定為相機 。 但是因為知識儲備較為稀少,對SLAM不夠了解,在頭

    2024年02月09日
    瀏覽(32)
  • 基于視覺重定位的室內(nèi)AR導(dǎo)航項目思路(2):改進的建圖和定位分離的項目思路

    基于視覺重定位的室內(nèi)AR導(dǎo)航項目思路(2):改進的建圖和定位分離的項目思路

    前情提要: 是第一次做項目的小白,文章內(nèi)的資料介紹如有錯誤,請多包含! 不知道在線建圖是否有其他方法,但是我只嘗試過使用ORB-SLAM3進行在線建圖,這或許是一個可以再進行思考的要點。 可以采用以下兩種想法進行建圖: 1、在 電腦端 運行ORB-SLAM3實時調(diào)用手機攝像頭

    2024年02月09日
    瀏覽(15)
  • three.js實現(xiàn)3D室內(nèi)全景看房

    three.js實現(xiàn)3D室內(nèi)全景看房

    首先我們先搭建一個項目,我選擇使用vite來進行項目的搭建,執(zhí)行命令如下: 這樣一個基本的項目就搭建成功了,目錄如下所示 然后,下載一下three.js工具,執(zhí)行如下命令 頁面中引入 先搭建一個立體圖形,并畫出輔助線,如下所示 ?實現(xiàn)代碼如下: 接著,給我們的立體圖

    2024年02月12日
    瀏覽(27)
  • 基于視覺重定位的室內(nèi)AR導(dǎo)航APP的大創(chuàng)項目思路(3)手機相機內(nèi)參數(shù)據(jù)獲取和相機標(biāo)定

    基于視覺重定位的室內(nèi)AR導(dǎo)航APP的大創(chuàng)項目思路(3)手機相機內(nèi)參數(shù)據(jù)獲取和相機標(biāo)定

    前情提要: 是第一次做項目的小白,文章內(nèi)的資料介紹如有錯誤,請多包含! 相機內(nèi)參是本身的物理數(shù)據(jù),包括焦距f和縮放c,一般以矩陣K的形式存放和使用 1.相機的內(nèi)參數(shù)據(jù)在建圖的時候就需要使用,SLAM中需要根據(jù)相機內(nèi)參數(shù)據(jù)結(jié)合傳入的圖像數(shù)據(jù)等進行建圖,不然無法

    2024年02月09日
    瀏覽(22)
  • web 3d場景構(gòu)建+three.js+室內(nèi)圍墻,倉庫,樓梯,貨架模型等,第一人稱進入場景案例

    web 3d場景構(gòu)建+three.js+室內(nèi)圍墻,倉庫,樓梯,貨架模型等,第一人稱進入場景案例

    ? 翻到了之前的一個案例,基于three.js做的倉庫布局模擬,地圖元素除了大模型外,其他都是通過JSON數(shù)據(jù)解析動態(tài)生成的,例如墻體,柱子門口,地標(biāo)等,集成了第一人稱的插件可以第一人稱進入場景有需要的可以下載看看,對想入門的朋友應(yīng)該有一些參考價值。 /** ? ?*創(chuàng)

    2024年02月10日
    瀏覽(21)
  • 微信小程序3D,使用Three.js在微信小程序中展示gltf模型,使用VisionKit展示AR能力

    微信小程序3D,使用Three.js在微信小程序中展示gltf模型,使用VisionKit展示AR能力

    本倉庫只開源gltf模型展示技術(shù),技術(shù)好的朋友有這些代碼就能幫助你解決很多問題了 如需要完整項目(基于若依框架開發(fā)的后端,AR能力前端)需另外付費贊助, 聯(lián)系方式:QQ 790002517 微信公眾號:時不待我 https://github.com/zzy-life/Wechat3D Three.js Three.js is a JavaScript 3D library. thr

    2024年02月09日
    瀏覽(49)
  • 網(wǎng)站登錄界面制作(three.js 3D特效背景)+ boostrap導(dǎo)航欄實現(xiàn) + jQuery移動窗口【附加源代碼】

    網(wǎng)站登錄界面制作(three.js 3D特效背景)+ boostrap導(dǎo)航欄實現(xiàn) + jQuery移動窗口【附加源代碼】

    學(xué)過Web前端的許多小伙伴都會面對門戶網(wǎng)站制作的大作業(yè)報告,這里給大家分享一下我的前端大作業(yè)。后續(xù)還會繼續(xù)更新,喜歡的小伙伴可以點個贊。 注意上述為動態(tài)界面: 下面的是表單的JS源代碼: 下面是3D動態(tài)例子的源代碼: 注意中間的窗口是移動的; 下面是移動窗口

    2024年02月07日
    瀏覽(25)
  • 除了three.js,還有許多其他前端開發(fā)語言和庫可以用于創(chuàng)建3D可視化大屏

    除了three.js,還有許多其他前端開發(fā)語言和庫可以用于創(chuàng)建3D可視化大屏

    hello老鐵們...本人熟悉html5,vue對bootsrap,uniapp,layui,element,vite,antd,echarts,jq響應(yīng)式尤其擅長,ui設(shè)計等技能,如果ui前端工作中有遇到煩惱可私信關(guān)注評論我們共同交流進步!謝謝?? ? ? 隨著前端技術(shù)的飛速發(fā)展,3D可視化已經(jīng)成為許多應(yīng)用場景中不可或缺的一部分。在

    2024年03月15日
    瀏覽(97)
  • 揭秘藍牙定位技術(shù),實現(xiàn)精準室內(nèi)導(dǎo)航

    揭秘藍牙定位技術(shù),實現(xiàn)精準室內(nèi)導(dǎo)航

    提及定位,我們首先想到的是GPS定位系統(tǒng)。然而,GPS主要適用于室外環(huán)境,在室內(nèi)定位方面存在局限性,這主要歸結(jié)于兩個原因:首先,GPS信號功率極低,接收要求相當(dāng)高,只有在天線對空無遮擋物的情況下才能接收到衛(wèi)星信號并實現(xiàn)定位;其次,由于現(xiàn)代建筑材料的特性,

    2024年02月07日
    瀏覽(25)
  • AI:130-基于深度學(xué)習(xí)的室內(nèi)導(dǎo)航與定位

    AI:130-基于深度學(xué)習(xí)的室內(nèi)導(dǎo)航與定位

    ??點擊這里跳轉(zhuǎn)到本專欄,可查閱專欄頂置最新的指南寶典~ ?????? 你的技術(shù)旅程將在這里啟航! 從基礎(chǔ)到實踐,深入學(xué)習(xí)。無論你是初學(xué)者還是經(jīng)驗豐富的老手,對于本專欄案例和項目實踐都有參考學(xué)習(xí)意義。 ??? 每一個案例都附帶有在本地跑過的關(guān)鍵代碼,詳細講

    2024年02月20日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包