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

cesium键盘控制相机位置和姿态

       该类主要用于监听键盘事件并在用户按下不同按键时执行相应的相机操作,如改变相机的位置、偏航角、俯仰角和翻滚角,从而实现在三维场景中的漫游。
以下是代码的主要逻辑:
  1. 导入Cesium库,并定义一个flags对象,其中包含了所有可能触发的键盘漫游状态标志。
  2. keyboardRoam 类包含以下方法:
    • start(viewer, setStep): 初始化键盘监听事件,包括keydown和keyup事件,并在每一帧(clock onTick事件)中执行funcTick函数以更新相机状态。同时禁用默认的鼠标移动地图和平移相机的功能。
    • hprSetting(h, p, r): 设置相机的Heading、Pitch、Roll(即偏航角、俯仰角、翻滚角)。
    • getFlagFromKeyboard(k): 根据按下的键盘按键返回对应的按键名称。
  3. funcTick函数中,根据flags对象中的状态标志来更新相机的位置和姿态。
  4. quit()方法用于销毁键盘监听事件以及恢复鼠标移动地图和平移相机的功能。
通过实例化 keyboardRoam 类并调用 start 方法,可以启用键盘漫游功能;调用 quit 方法则停止漫游并恢复默认的相机控制方式。
      // 引入键盘漫游方法import keyboardRoam from "../utils/roam/keyboardRoam";// 键盘控制相机方法初始化keyboard = new keyboardRoam();// 键盘控制相机方法开始keyboard.start(window.viewer, 1)// 键盘控制相机方法结束keyboard.quit();
import * as Cesium from "cesium";
// 定义事件组
let flags = {// 相机位置moveForward: false,moveBackward: false,moveLeft: false,moveRight: false,moveUp: false,moveDown: false,translateFront: false,translateBehind: false,// 相机姿态picthUp: false,picthDown: false,rollLeft: false,rollRight: false,headingLeft: false,headingRight: false,
};
let cameraHeight;
let heading;
let pitch;
let roll;
let funcTick;
/*** 键盘漫游*/
class keyboardRoam {/*** 键盘漫游加载方法* @param: 使用键盘控制地图漫游,* @param {Cesium.Viewer} viewer -cesium地图容器* @param {Number} setStep -相机视角移动步长*/start(viewer, setStep) {let that = this;// 添加键盘监听事件document.addEventListener("keydown",(this.down = function (e) {let flagName = that.getFlagFromKeyboard(e);if (typeof flagName !== "undefined") {flags[flagName] = true;}}),false);// 相机将保持锁定在当前位置。此标志仅适用于2D和Columbus视图模式。viewer.scene.screenSpaceCameraController.enableTranslate = false;// 相机将锁定到当前标题。这个标志只适用于3D和哥伦布视图。viewer.scene.screenSpaceCameraController.enableTilt = false;document.addEventListener("keyup",(this.up = function (e) {let flagName = that.getFlagFromKeyboard(e);if (typeof flagName !== "undefined") {flags[flagName] = false;}}),false);console.log(funcTick, '0000');// 为每一帧添加监听事件let m = viewer.clock.onTick.addEventListener(  // 键盘按下事件funcTick = () => {let camera = viewer.camera;let ellipsoid = viewer.scene.globe.ellipsoid;cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;// 根据相机高度设置移动距离let moveRate = (cameraHeight / 150.0) * setStep;heading = viewer.camera.heading;pitch = viewer.camera.pitch;roll = viewer.camera.roll;// 根据事件调整相机// 相机的偏航角、翻滚角和俯仰角// 偏航角if (flags.headingLeft) {that.hprSetting(-0.005 * setStep, 0, 0);}if (flags.headingRight) {that.hprSetting(0.005 * setStep, 0, 0);}// 俯仰角if (flags.picthUp) {that.hprSetting(0, 0.01 * setStep, 0);}if (flags.picthDown) {that.hprSetting(0, -0.01 * setStep, 0);}// 翻滚角if (flags.rollLeft) {that.hprSetting(0, 0, 0.01 * setStep);}if (flags.rollRight) {that.hprSetting(0, 0, -0.01 * setStep);}// 向中心点靠近if (flags.moveForward) {camera.moveForward(moveRate);}// 从中心点远离if (flags.moveBackward) {camera.moveBackward(moveRate);}// 相机本身前后左右上下平移if (flags.moveUp) {camera.moveUp(moveRate);}if (flags.moveDown) {camera.moveDown(moveRate);}if (flags.moveLeft) {camera.moveLeft(moveRate);}if (flags.moveRight) {camera.moveRight(moveRate);}// 相机向前平移if (flags.translateFront) {camera.rotateDown(Math.PI / 3600000 * setStep)}// 相机向后平移if (flags.translateBehind) {camera.rotateUp(Math.PI / 3600000 * setStep)}});return m;}// 相机翻滚角设置方法hprSetting(h, p, r) {viewer.camera.setView({orientation: {heading: heading + h,pitch: pitch + p,roll: roll + r,},});}// 监听键盘按下和松开的状态getFlagFromKeyboard(k) {switch (k.key) {// 按字符的Unicode编码// 相机姿态case "ArrowUp":return "picthUp";case "ArrowDown":return "picthDown";case "ArrowLeft":return "headingLeft";case "ArrowRight":return "headingRight";case "j":return "rollRight";case "l":return "rollLeft";// 相机向屏幕中心点前进后退case "i":return "moveForward";case "k":return "moveBackward";// 相机前后左右上下平移case "w":return "translateFront";case "s":return "translateBehind";case "a":return "moveLeft";case "d":return "moveRight";case "q":return "moveUp";case "e":return "moveDown";default:return undefined;}}/*** 销毁键盘漫游事件*/quit() {document.removeEventListener("keydown", this.down, false);document.removeEventListener("keyup", this.up, false);viewer.clock.onTick.removeEventListener(funcTick);// 解除禁用鼠标移动地图事件viewer.scene.screenSpaceCameraController.enableTranslate = true;// 解除视图锁定事件。viewer.scene.screenSpaceCameraController.enableTilt = true;}
}
export default keyboardRoam;

相关文章:

cesium键盘控制相机位置和姿态

该类主要用于监听键盘事件并在用户按下不同按键时执行相应的相机操作,如改变相机的位置、偏航角、俯仰角和翻滚角,从而实现在三维场景中的漫游。 以下是代码的主要逻辑: 导入Cesium库,并定义一个flags对象,其中包含了…...

基于ArrayList实现简单洗牌

前言 在之前的那篇文章中,我们已经认识了顺序表—>http://t.csdnimg.cn/2I3fE 基于此,便好理解ArrayList和后面的洗牌游戏了。 什么是ArrayList? ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表&…...

Paddle实现人脸对比

人脸对比 人脸对比,顾名思义,就是对比两个人脸的相似度。本文将用Paddle实现这一功能。 PS:作者肝了整整3天才稍微搞明白实现方法 数据集准备 这里使用百度AI Studio的开源数据集: 人脸数据_数据集-飞桨AI Studio星河社区 (b…...

挖一挖:PostgreSQL Java里的double类型存储到varchar精度丢失问题

前言 大概故事是这样的,PostgreSQL数据库,表结构: create table t1(a varchar);然后使用标准的Java jdbc去插入数据,其基本代码如下: import java.sql.*; public class PgDoubleTest {public static void main(Stri…...

函数对象基本使用

一、函数对象概念 1.重载函数调用操作符的类,其对象常称为函数对象 2.函数对象使用重载的()时,行为类似函数调用,也叫仿函数 本质: 函数对象(仿函数)是一个类,不是一个函数 二、函数对象使用 特点: 函…...

浅谈HTTP

浅谈HTTP 要通过netty实现HTTP服务器(或者客户端),首先你要了解HTTP协议。 HTTP在客户端 - 服务器计算模型中用作请求 - 响应协议。 例如,web浏览器可以是客户端,并且在托管网站的计算机上运行的应用程序可以是服务器。 客户端向服务器提交…...

HarmonyOS NEXT应用开发之@Provide装饰器和\@Consume装饰器:与后代组件双向同步

Provide和Consume,应用于与后代组件的双向数据同步,应用于状态数据在多个层级之间传递的场景。不同于上文提到的父子组件之间通过命名参数机制传递,Provide和Consume摆脱参数传递机制的束缚,实现跨层级传递。 其中Provide装饰的变…...

Docker 安装 | 部署MySQL 8.x 初始设置

1、准备工作 如果不想看前面的废话请直接右边目录跳到 运行容器 处 默认你已经有 docker 环境。 Windows 推荐 Docker Desktop (下载地址)并基于 WSL2 运行 Docker 环境 mac 推荐 Orbstack (下载地址)(这个很节省资源&…...

linux三剑客之流编辑器sed

sed(stream editor)是Linux和Unix系统中一个非常强大的文本处理工具。它主要用于对文本数据进行过滤和转换。sed 可以在不打开文件的情况下,直接对输入流进行操作,并且可以将结果输出到标准输出或文件。 基本语法: s…...

【Android Studio】上位机-安卓系统手机-蓝牙调试助手

【Android Studio】上位机-安卓系统手机-蓝牙调试助手 文章目录 前言AS官网一、手机配置二、移植工程三、配置四、BUG五、Java语言总结 前言 提示:以下是本篇文章正文内容,下面案例可供参考 AS官网 AS官网 一、手机配置 Android Studio 下真机调试 …...

怎样把学浪购买的课程下载下来

如何把学浪已购买的课程下载下来?这里就教大家一个方法,利用一个工具轻轻松松把视频下载下来 这个工具我打包成压缩包了,有需要的自己取一下 链接:https://pan.baidu.com/s/1y7vcqILToULrYApxfEzj_Q?pwdkqvj 提取码:kqvj --来自百度网盘超级会员V1…...

SD-WAN如何解决更有性价比地跨境网络问题

云桥通SD-WAN利用智能路由和负载均衡技术,优化数据传输路径,提高网络性能和可靠性。这意味着数据在跨国传输时可以更快到达目的地,减少延迟和丢包率。跨境SD-WAN提高了网络连接速度和质量,使用户能够更快地访问跨国业务所需的资源…...

第15章 File类与IO流

一 java.io.File类的使用 1.1 概述 File类及本章下的各种流,都定义在java.io包下。一个File对象代表硬盘或网络中可能存在的一个文件或者文件目录(俗称文件夹),与平台无关。(体会万事万物皆对象)File 能新…...

C语言基础语法-教案16(从小白到劝退之结构体初阶)

最近给大家争取到一个 深夜福利 保证你在深夜手机刷到 嘎嘎香~ 那就是 大流量卡 缺点:月租太便宜 185GB~ 100分钟通话时长~ 长期套餐~ 畅想自由的气息 流量自由的同时还拥有超长通话,而且免费领取。 名额有限,咱们废话不多说直接上…...

Linux:ip和ip协议的初步认识

文章目录 ip协议基本认识ip协议的报头网段划分ip的类型划分 ip协议基本认识 前面对于TCP的内容已经基本结束了,那么这也就意味着在传输层也已经结束了,那么下一步要进入的是的是网络层,网络层中也有很多种协议,这里主要进行解析的…...

Android12 简单的共享内存驱动实现 参考Ashmem

Android12 共享内存驱动实现 SOC:RK3568 system:Android12 概述: 1. 概述 Ashmem(Anonymous Shared Memory,Android 匿名共享内存),它基于 mmap 系统调用,可以让不同进程将同一段…...

物理安全和逻辑安全在信息安全中的重要作用

在信息时代,信息安全已经成为企业和个人不可或缺的重要组成部分。物理安全和逻辑安全作为信息安全的两大支柱,发挥着至关重要的作用。 什么是物理安全和逻辑安全? 物理安全是指通过技术手段,对计算机设备、网络设备、数据中心等…...

每日一题 --- 滑动窗口最大值[力扣][Go]

滑动窗口最大值 题目:239. 滑动窗口最大值 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1&#xff1…...

TensorBoard可视化+Confustion Matrix Drawing

for later~ 代码阅读 1. 加载trainset import argparse import logging import os import numpy as npimport torch from torch import distributed from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterfrom backbones import get_…...

012——LED模块驱动开发(基于I.MX6uLL)

目录 一、 硬件原理图 二、 驱动程序 三、 应用程序 四、 Makefile 五、操作 一、 硬件原理图 又是非常经典的点灯环节 ,每次学新语言第一步都是hello world,拿到新板子或者学习新的操作系统,第一步就是点灯。 LED 的驱动方式&#xff0…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...

SpringTask-03.入门案例

一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率&#xff0c…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...