当前位置: 首页 > article >正文

Cesium教程04_旋转模型

基于 Vue 和 Cesium 的三维地形高度和旋转调节器

引言

本文将介绍如何使用 Vue 和 Cesium 实现一个可调节三维地形模型高度与旋转角度的工具。项目展示了如何通过滑块实时调整地形高度以及模型在 X、Y、Z 轴上的旋转角度,同时实现直观的用户交互。

目录

  • 功能演示
  • 代码实现
    • 模板部分
    • 逻辑部分
    • 样式部分
  • 代码解析
    • Cesium 初始化
    • 高度调节实现
    • 旋转调节实现
  • 总结
  • 参考资源

功能演示

该工具允许用户通过滑块调整三维模型的以下参数:

  • 高度:改变模型在 Z 轴上的位置。
  • 旋转角度:分别对 X、Y、Z 轴上的旋转进行调节。

如下为核心交互界面:

  1. 高度调节:通过滑块控制模型的垂直位置。
  2. 旋转控制:实时调整模型的旋转角度,并在 Cesium 场景中渲染效果。

代码实现

使用 Vue 的模板语法构建交互界面,包括一个 Cesium 容器和工具栏。工具栏提供高度和旋转角度的调节功能。

<template>
  <div>
    <!-- Cesium 容器 -->
    <div ref="cesiumContainer" class="cesium-container"></div>
    <!-- 工具栏 -->
    <div class="toolbar">
      <!-- 高度调节滑块 -->
      <label for="heightSlider">Adjust Height:</label>
      <input
          id="heightSlider"
          type="range"
          min="0"
          max="100"
          v-model="height"
      />
      <span>{{ height }} meters</span>

      <!-- 旋转调节滑块 -->
      <div>
        <label for="rotateXSlider">Rotate X:</label>
        <input
            id="rotateXSlider"
            type="range"
            min="0"
            max="360"
            v-model="rotateX"
        />
        <span>{{ rotateX }}°</span>
      </div>

      <div>
        <label for="rotateYSlider">Rotate Y:</label>
        <input
            id="rotateYSlider"
            type="range"
            min="0"
            max="360"
            v-model="rotateY"
        />
        <span>{{ rotateY }}°</span>
      </div>

      <div>
        <label for="rotateZSlider">Rotate Z:</label>
        <input
            id="rotateZSlider"
            type="range"
            min="0"
            max="360"
            v-model="rotateZ"
        />
        <span>{{ rotateZ }}°</span>
      </div>
    </div>
  </div>
</template>
<script>
import { defineComponent, ref, onMounted, watch } from "vue";
import {
  Viewer,
  Cartesian3,
  Cartographic,
  Matrix4,
  Cesium3DTileset,
  Math as CesiumMath,
  Matrix3,
  Terrain,
} from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";

export default defineComponent({
  name: "CesiumViewer",
  setup() {
    const cesiumContainer = ref(null);
    const viewer = ref(null);
    const tileset = ref(null);
    const height = ref(0);
    const rotateX = ref(0);
    const rotateY = ref(0);
    const rotateZ = ref(0);
    let rootTransform = null;

    const initCesium = async () => {
      if (!cesiumContainer.value) {
        console.error("Cesium container not found!");
        return;
      }

      try {
        viewer.value = new Viewer(cesiumContainer.value, {
          terrain: Terrain.fromWorldTerrain(),
        });

        tileset.value = await Cesium3DTileset.fromIonAssetId(40866);
        viewer.value.scene.primitives.add(tileset.value);
        viewer.value.zoomTo(tileset.value);

        rootTransform = Matrix4.clone(tileset.value.root.transform);
        tileset.value.modelMatrix = Matrix4.clone(rootTransform);
        tileset.value.root.transform = Matrix4.clone(Matrix4.IDENTITY);
      } catch (error) {
        console.error("Error initializing Cesium:", error);
      }
    };

    const updateHeight = (newHeight) => {
      if (!tileset.value) return;

      const numericHeight = Number(newHeight);
      const boundingSphere = tileset.value.boundingSphere;
      const cartographic = Cartographic.fromCartesian(boundingSphere.center);
      const surface = Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0);
      const offset = Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, numericHeight);
      const translation = Cartesian3.subtract(offset, surface, new Cartesian3());
      const newModelMatrix = Matrix4.fromTranslation(translation);
      tileset.value.modelMatrix = Matrix4.multiply(rootTransform, newModelMatrix, new Matrix4());
    };

    const updateRotation = (tileset, rotateX, rotateY, rotateZ) => {
      if (!tileset) return;

      const rotationX = Matrix3.fromRotationX(CesiumMath.toRadians(rotateX));
      const rotationY = Matrix3.fromRotationY(CesiumMath.toRadians(rotateY));
      const rotationZ = Matrix3.fromRotationZ(CesiumMath.toRadians(rotateZ));
      const combinedRotation = Matrix3.multiply(rotationZ, rotationY, new Matrix3());
      Matrix3.multiply(combinedRotation, rotationX, combinedRotation);

      const rotationMatrix = Matrix4.fromRotationTranslation(combinedRotation, Cartesian3.ZERO);
      const modelMatrix = Matrix4.clone(tileset.modelMatrix);
      const newModelMatrix = Matrix4.multiply(modelMatrix, rotationMatrix, new Matrix4());
      tileset.modelMatrix = newModelMatrix;
    };

    watch(height, (newHeight) => {
      updateHeight(newHeight);
    });

    watch([rotateX, rotateY, rotateZ], ([newRotateX, newRotateY, newRotateZ]) => {
      updateRotation(tileset.value, newRotateX, newRotateY, newRotateZ);
    });

    onMounted(() => {
      initCesium();
    });

    return {
      cesiumContainer,
      height,
      rotateX,
      rotateY,
      rotateZ,
    };
  },
});
</script>

代码解析

###Cesium 初始化
初始化 Cesium Viewer,并加载来自 Ion 平台的 3D 瓦片资源。

###高度调节实现
通过 updateHeight 方法,根据用户输入动态调整模型高度。

旋转调节实现

通过 updateRotation 方法结合矩阵运算实现三维旋转控制。
在这里插入图片描述

总结

本项目展示了如何使用 Vue 与 Cesium 构建一个三维地形交互工具,涵盖了模型加载、高度调节与旋转功能的实现。未来可扩展添加更多交互功能,如缩放、模型选择等。

参考资源

Cesium 官方文档
Vue 官方文档


http://www.kler.cn/a/411975.html

相关文章:

  • 概率论中交并集的公式
  • 路由传参、搜索、多选框勾选、新增/编辑表单复用
  • goframe开发一个企业网站 在vue-next-admin 显示验证码 19
  • hive的存储格式
  • webrtc支持h265
  • vulnhub靶场之corrosion靶场1
  • 每日刷题之优选算法(滑动窗口)
  • kali安装及使用docker和docker-compose
  • Go语言switch语句
  • 设计理念与数据反馈:面向火星熔岩管探索的跳跃机器人
  • Nodemailer使用教程:在Node.js中发送电子邮件
  • anaconda pycharm 使用问题
  • Python脚本检测网站是否开启浏览器缓存配置
  • FastDFS基础概述与系统架构详解
  • GitLab CI 配置
  • 深入浅出 WebSocket:构建实时数据大屏的高级实践
  • AdaPipe:通过自适应重新计算和细粒度的计算单元划分
  • Linux KASLR
  • DAMODEL丹摩|丹摩平台:AI时代的开发者福音
  • 微信小程序+Vant-自定义选择器组件(多选
  • 【Zookeeper 和 Kafka】为什么 Zookeeper 不用域名?
  • 权限的相关内容
  • 昇思MindSpore第六课---Roberta Prompt Turning
  • c#异步编程(async/await)
  • 阿里云多账号统一认证
  • 玛哈特矫平机:精密制造中的平整大师