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

Cesium設(shè)置模型朝向速度矢量方向

這篇具有很好參考價(jià)值的文章主要介紹了Cesium設(shè)置模型朝向速度矢量方向。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

Cesium設(shè)置模型朝向速度矢量方向

1. 需求場(chǎng)景

現(xiàn)有一段飛機(jī)起飛、爬升的軌跡數(shù)據(jù),需要在Cesium中模擬出飛行過程動(dòng)畫,要求飛機(jī)模型的姿態(tài)隨著速度矢量方向變化,而不是一直保持飛機(jī)模型的原始狀態(tài)。

2. 技術(shù)路線

Cesium.Entity類中有屬性orientation 可以用來控制實(shí)體模型model的朝向,當(dāng)不設(shè)置該屬性時(shí),模型就保持原始狀態(tài)。如下圖所示:

cesium調(diào)整模型方向,Cesium,前端

根據(jù)需求,飛機(jī)模型應(yīng)該向上仰起來,有兩種方式可以達(dá)到目標(biāo)。

2.1 VelocityOrientationProperty

Cesium提供了VelocityOrientationProperty類,通過該類可以直接設(shè)置實(shí)體的orientation屬性,其內(nèi)部會(huì)自動(dòng)計(jì)算速度矢量,設(shè)置后飛機(jī)模型就會(huì)沿著速度矢量的方向,官方文檔示例代碼:

// Create an entity with position and orientation.
var position = new Cesium.SampledProperty();
position.addSamples(...);
var entity = viewer.entities.add({
  position : position,
  orientation : new Cesium.VelocityOrientationProperty(position)
}));

實(shí)際應(yīng)用時(shí)示例代碼:

entity.orientation = new Cesium.VelocityOrientationProperty(entity.position);

效果如下圖:

cesium調(diào)整模型方向,Cesium,前端

2.2 VelocityVectorProperty

第一種方式基本就可以解決問題,但是有一種情況:三維模型本身有問題,有些三維模型從其他格式轉(zhuǎn)換過來,在導(dǎo)入到Cesium后會(huì)發(fā)現(xiàn)有翻轉(zhuǎn)、角度偏移等現(xiàn)象,需要在上一步的基礎(chǔ)上(先將模型變換到速度矢量方向),再進(jìn)行一些模型旋轉(zhuǎn)變換。

通過VelocityVectorProperty可以計(jì)算出速度矢量,通過速度矢量、要沿參考軸旋轉(zhuǎn)的角度(heading、pitch、rool)就可以計(jì)算出最終的朝向四元數(shù)(quaternion),將該四元數(shù)設(shè)置給實(shí)體的orientation屬性即可。

核心代碼如下:

    /**
     * 計(jì)算朝向四元數(shù)
     * X軸正向指向運(yùn)動(dòng)方向;Y軸在水平面內(nèi)垂直于X軸,正向指向右側(cè);Z軸通過右手法則確定
     * @param {Cartesian3} position 位置
     * @param {Cartesian3} velocity 速度向量
     * @param {*} rotateX 繞X軸旋轉(zhuǎn)的角度(roll)
     * @param {*} rotateY 繞Y軸旋轉(zhuǎn)的角度(pitch)
     * @param {*} rotateZ 繞Z軸旋轉(zhuǎn)的角度(heading)
     * @returns 
     */
    function getQuaternion(position, velocity, rotateX, rotateY, rotateZ) {
      // 1、計(jì)算站心到模型坐標(biāo)系的旋轉(zhuǎn)平移矩陣
      // 速度歸一化
      let normal = Cesium.Cartesian3.normalize(velocity, new Cesium.Cartesian3());
      // 計(jì)算模型坐標(biāo)系的旋轉(zhuǎn)矩陣
      let satRotationMatrix = Cesium.Transforms.rotationMatrixFromPositionVelocity(position, normal, Cesium.Ellipsoid.WGS84);
      // 模型坐標(biāo)系到地固坐標(biāo)系旋轉(zhuǎn)平移矩陣
      let m = Cesium.Matrix4.fromRotationTranslation(satRotationMatrix, position);
      // 站心坐標(biāo)系(東北天坐標(biāo)系)到地固坐標(biāo)系旋轉(zhuǎn)平移矩陣
      var m1 = Cesium.Transforms.eastNorthUpToFixedFrame(position, Cesium.Ellipsoid.WGS84, new Cesium.Matrix4());
      // 站心到模型坐標(biāo)系的旋轉(zhuǎn)平移矩陣
      let m3 = Cesium.Matrix4.multiply(Cesium.Matrix4.inverse(m1, new Cesium.Matrix4()), m, new Cesium.Matrix4());

      // 2、模型姿態(tài)旋轉(zhuǎn)矩陣
      rotateX = rotateX || 0;
      rotateY = rotateY || 0;
      rotateZ = rotateZ || 0;
      let heading = rotateZ, pitch = rotateY, roll = rotateX;
      let postureHpr = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(heading), Cesium.Math.toRadians(pitch), Cesium.Math.toRadians(roll));
      let postureMatrix = Cesium.Matrix3.fromHeadingPitchRoll(postureHpr);

      // 3、最終的旋轉(zhuǎn)矩陣
      let mat3 = Cesium.Matrix4.getMatrix3(m3, new Cesium.Matrix3());
      let finalMatrix = Cesium.Matrix3.multiply(mat3, postureMatrix, new Cesium.Matrix3());
      let quaternion1 = Cesium.Quaternion.fromRotationMatrix(finalMatrix);
      let hpr = Cesium.HeadingPitchRoll.fromQuaternion(quaternion1);
      let q2 = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
      return q2;
    }

控制臺(tái)測(cè)試代碼:

        // 當(dāng)前時(shí)刻速度向量、位置
        let curVelocityVector = entity.velocityVector.getValue(viewer.clock.currentTime, new Cesium.Cartesian3());
        let curPosition = entity.position.getValue(viewer.clock.currentTime, new Cesium.Cartesian3());
        // 計(jì)算朝向四元數(shù)
        var quaternion = getQuaternion(curPosition, curVelocityVector);
        // 設(shè)置實(shí)體朝向,驗(yàn)證是否指向速度矢量方向
        entity.orientation = quaternion;

實(shí)際應(yīng)用代碼:

var viewer, entity;
    function startup(Cesium) {
      "use strict";
      //Sandcastle_Begin
      viewer = new Cesium.Viewer("cesiumContainer");
      var scene = viewer.scene;

      // Cesium查看器
      viewer.extend(Cesium.viewerCesiumInspectorMixin);

      // CZML中的orientation并不考慮速度矢量方向
      let dataSourcePromise = Cesium.CzmlDataSource.load("../../SampleData/CZML/Aircraft2.czml");
      dataSourcePromise.then(function (dataSource) {
        viewer.dataSources.add(dataSource);

        // 獲取實(shí)體
        entity = viewer.dataSources.getByName("1610994859816914946")[0].entities.getById("1610994859816914946");

        // 添加屬性:速度向量
        entity.velocityVector = new Cesium.VelocityVectorProperty(entity.position, true);

        /* // 當(dāng)前時(shí)刻速度向量、位置
        let curVelocityVector = entity.velocityVector.getValue(viewer.clock.currentTime, new Cesium.Cartesian3());
        let curPosition = entity.position.getValue(viewer.clock.currentTime, new Cesium.Cartesian3());
        // 計(jì)算朝向四元數(shù)
        var quaternion = getQuaternion(curPosition, curVelocityVector);
        // 設(shè)置實(shí)體朝向,驗(yàn)證是否指向速度矢量方向
        entity.orientation = quaternion; */


        let rotateX = 0;
        let rotateY = 0;
        let rotateZ = 0;
        var property = new Cesium.SampledProperty(Cesium.Quaternion);
        if (entity.position instanceof Cesium.CompositePositionProperty) {
          let intervals = entity.position.intervals;
          for (let i = 0; i < intervals.length; i++) {
            const interval = intervals.get(i);
            let positions = interval.data._property._values;
            interval.data._property._times.forEach((time, index) => {

              let curVelocityVector = entity.velocityVector.getValue(time, new Cesium.Cartesian3());
              let curPosition = entity.position.getValue(time, new Cesium.Cartesian3());
              // 計(jì)算朝向四元數(shù)
              var quaternion = getQuaternion(curPosition, curVelocityVector, rotateX, rotateY, rotateZ);
              // 添加采樣值
              property.addSample(time, quaternion);
            });
          }
        }

        // 將轉(zhuǎn)換后的四元數(shù)設(shè)置給實(shí)體
        entity.orientation = property;
      })


      Sandcastle.finishedLoading();
    }
    if (typeof Cesium !== "undefined") {
      window.startupCalled = true;
      startup(Cesium);
    }

    /**
     * 計(jì)算朝向四元數(shù)
     * X軸正向指向運(yùn)動(dòng)方向;Y軸在水平面內(nèi)垂直于X軸,正向指向右側(cè);Z軸通過右手法則確定
     * @param {Cartesian3} position 位置
     * @param {Cartesian3} velocity 速度向量
     * @param {*} rotateX 繞X軸旋轉(zhuǎn)的角度(roll)
     * @param {*} rotateY 繞Y軸旋轉(zhuǎn)的角度(pitch)
     * @param {*} rotateZ 繞Z軸旋轉(zhuǎn)的角度(heading)
     * @returns 
     */
    function getQuaternion(position, velocity, rotateX, rotateY, rotateZ) {
      // 1、計(jì)算站心到模型坐標(biāo)系的旋轉(zhuǎn)平移矩陣
      // 速度歸一化
      let normal = Cesium.Cartesian3.normalize(velocity, new Cesium.Cartesian3());
      // 計(jì)算模型坐標(biāo)系的旋轉(zhuǎn)矩陣
      let satRotationMatrix = Cesium.Transforms.rotationMatrixFromPositionVelocity(position, normal, Cesium.Ellipsoid.WGS84);
      // 模型坐標(biāo)系到地固坐標(biāo)系旋轉(zhuǎn)平移矩陣
      let m = Cesium.Matrix4.fromRotationTranslation(satRotationMatrix, position);
      // 站心坐標(biāo)系(東北天坐標(biāo)系)到地固坐標(biāo)系旋轉(zhuǎn)平移矩陣
      var m1 = Cesium.Transforms.eastNorthUpToFixedFrame(position, Cesium.Ellipsoid.WGS84, new Cesium.Matrix4());
      // 站心到模型坐標(biāo)系的旋轉(zhuǎn)平移矩陣
      let m3 = Cesium.Matrix4.multiply(Cesium.Matrix4.inverse(m1, new Cesium.Matrix4()), m, new Cesium.Matrix4());

      // 2、模型姿態(tài)旋轉(zhuǎn)矩陣
      rotateX = rotateX || 0;
      rotateY = rotateY || 0;
      rotateZ = rotateZ || 0;
      let heading = rotateZ, pitch = rotateY, roll = rotateX;
      let postureHpr = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(heading), Cesium.Math.toRadians(pitch), Cesium.Math.toRadians(roll));
      let postureMatrix = Cesium.Matrix3.fromHeadingPitchRoll(postureHpr);

      // 3、最終的旋轉(zhuǎn)矩陣
      let mat3 = Cesium.Matrix4.getMatrix3(m3, new Cesium.Matrix3());
      let finalMatrix = Cesium.Matrix3.multiply(mat3, postureMatrix, new Cesium.Matrix3());
      let quaternion1 = Cesium.Quaternion.fromRotationMatrix(finalMatrix);
      let hpr = Cesium.HeadingPitchRoll.fromQuaternion(quaternion1);
      let q2 = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
      return q2;
    }

3. 參考鏈接

[1]. 【Cesium】計(jì)算模型的朝向四元數(shù),實(shí)現(xiàn)模型運(yùn)動(dòng)中調(diào)整朝向文章來源地址http://www.zghlxwxcb.cn/news/detail-684919.html

到了這里,關(guān)于Cesium設(shè)置模型朝向速度矢量方向的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • Cesium模型漫游過程中姿態(tài)動(dòng)態(tài)調(diào)整

    Cesium模型漫游過程中姿態(tài)動(dòng)態(tài)調(diào)整

    一、功能設(shè)計(jì) 模型漫游過程中姿態(tài)動(dòng)態(tài)調(diào)整有兩種情況: 1)速度沿默認(rèn)方向-運(yùn)動(dòng)過程中的姿態(tài)動(dòng)態(tài)調(diào)節(jié) 2)沿速度矢量方向-運(yùn)動(dòng)過程中姿態(tài)的動(dòng)態(tài)調(diào)節(jié) 二、對(duì)數(shù)據(jù)和服務(wù)的要求 gltf數(shù)據(jù) 三、接口設(shè)計(jì) 通過修改AnimationTool上的modelHeading,modelPitch,modelRoll來進(jìn)行姿態(tài)動(dòng)態(tài)調(diào)節(jié)

    2024年02月13日
    瀏覽(17)
  • Cesium示例程序?qū)W習(xí)和講解(4)-調(diào)整3DTiles模型高度

    本節(jié)主要講解的內(nèi)容? 在三維場(chǎng)景中如何加載3dtiles模型,如何調(diào)整模型在場(chǎng)景中的高度 涉及的主要接口有? Cesium3DTileset、HeadingPitchRange、Cartographic、Matrix4 介紹下HeadingPitchRange接口接相關(guān)參數(shù)介紹? 當(dāng)使用Cesium框架進(jìn)行三維場(chǎng)景渲染時(shí),常常需要在場(chǎng)景中創(chuàng)建相機(jī)視圖。而

    2024年02月10日
    瀏覽(18)
  • Cesium 實(shí)戰(zhàn) - Blender調(diào)整模型組件原點(diǎn),實(shí)現(xiàn)直升機(jī)尾翼旋轉(zhuǎn)

    某個(gè)項(xiàng)目需求,在操作直升機(jī)模型的時(shí)候,希望直升機(jī)機(jī)翼和尾翼旋轉(zhuǎn)起來。 機(jī)翼旋轉(zhuǎn)比較容易,找到組件名稱,按照之前的 《Cesium 實(shí)戰(zhàn) - AGI_articulations 擴(kuò)展:模型自定義關(guān)節(jié)動(dòng)作》設(shè)置即可實(shí)現(xiàn)。 但是在設(shè)置尾翼的時(shí)候,出現(xiàn)問題,這里記錄一下問題以及解決方法。 本

    2024年02月15日
    瀏覽(35)
  • Cesium加載ArcGIS的PBF矢量切片服務(wù)

    Cesium加載ArcGIS的PBF矢量切片服務(wù)

    在 Cesium 中,我們使用的地圖服務(wù)均為傳統(tǒng)的柵格切片服務(wù) 。即在服務(wù)端渲染好圖片并進(jìn)行切片,客戶端請(qǐng)求獲取圖片后直接顯示。 而矢量切片則有別于傳統(tǒng)的柵格切片,它在服務(wù)端切片存儲(chǔ)的是矢量數(shù)據(jù)的描述文件,最終的渲染在客戶端完成。 事實(shí)上矢量切片技術(shù)目前已

    2024年02月05日
    瀏覽(32)
  • Cesium 3Dtiles偏移調(diào)整

    Cesium 3Dtiles偏移調(diào)整可以通過以下步驟進(jìn)行: 根據(jù)前后經(jīng)緯度和高度計(jì)算變換矩陣-平移矩陣: step1: 根據(jù)tileset的邊界球體中心點(diǎn)的笛卡爾坐標(biāo)得到經(jīng)緯度坐標(biāo)。 step2: 根據(jù)經(jīng)緯度和高度0,得到地面笛卡爾坐標(biāo)。 step3: 根據(jù)經(jīng)緯度和需要的高度,得到偏移后的笛卡爾坐標(biāo)。 st

    2024年01月25日
    瀏覽(21)
  • Cesium 實(shí)戰(zhàn)教程 - 調(diào)整 3dtiles 傾斜攝影大小

    Cesium 實(shí)戰(zhàn)教程 - 調(diào)整 3dtiles 傾斜攝影大小

    之前由于誤解遇到一個(gè)特殊的需求: 想要把三維球上疊加傾斜攝影進(jìn)行自由放大縮小,跟隨地圖的縮放進(jìn)行縮放。 后來經(jīng)過搜索、嘗試,終于實(shí)現(xiàn)了需求。 但是,后來發(fā)現(xiàn)是誤解需求了,甲方只是需要放大縮小地圖,不需要改變傾斜攝影的比例。 不過也算是學(xué)習(xí)了一個(gè)功能

    2024年02月12日
    瀏覽(22)
  • 【Cesium】調(diào)整3DTile/tileset的位置到某個(gè)經(jīng)緯度/某個(gè)地點(diǎn)/城市

    前提: 模型本身有地理位置信息,模型本身就能顯示在地球表面了(而不是在地表下的球心或其他奇奇怪怪的位置) 以下是將tileset的位置調(diào)整到北京(在WGS84坐標(biāo)系下)的正確代碼: 在以上代碼中,我們首先獲取tileset的中心點(diǎn)坐標(biāo),并將其轉(zhuǎn)換為WGS84坐標(biāo)系下的經(jīng)緯度。然后,我

    2024年02月12日
    瀏覽(53)
  • 【Cesium學(xué)習(xí)(六)】Cesium加載3D模型(3D tiles和glTF模型)

    【Cesium學(xué)習(xí)(六)】Cesium加載3D模型(3D tiles和glTF模型)

    前面我們學(xué)習(xí)到了繪制基本的形狀,但是Cesium還可以加載3D模型,因?yàn)橄窀叩碌貓D這種的技術(shù)來加載大型復(fù)雜的建筑模型性能不加,所有只能想Cesium這種專門做3D地圖的技術(shù)。接下來就學(xué)習(xí)一下如何加載模型。 Cesium目前支持兩種模型方案,一個(gè)是使用3D tiles, 另一個(gè)是加載g

    2024年02月07日
    瀏覽(27)
  • 056:cesium 七種方法設(shè)置顏色

    056:cesium 七種方法設(shè)置顏色

    第056個(gè) 點(diǎn)擊查看專欄目錄 本示例的目的是介紹如何在vue+cesium中設(shè)置顏色,這里用到了7種方法,查看API,還有很多種方法 直接復(fù)制下面的 vue+cesium源代碼,操作2分鐘即可運(yùn)行實(shí)現(xiàn)效果. 示例效果

    2024年02月05日
    瀏覽(15)
  • cesium中3dtiles貼地問題設(shè)置

    cesium中3dtiles貼地問題設(shè)置

    當(dāng)我們轉(zhuǎn)換得到3dtiles格式數(shù)據(jù)后,將數(shù)據(jù)添加到cesium中:? ?模型可能出現(xiàn)以下不貼地的情況: 對(duì)于此類問題,解決辦法參考如下: 模型定位: 修改后,模型貼地顯示如下(設(shè)置不同的偏移量可以獲得不同高度的模型):?

    2024年02月11日
    瀏覽(13)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包