前言

由于项目业务需要,所以实现了这四个api的碰撞检测效果。
核心是通过ray射线来做碰撞检测。

代码目录结构

核心代码

<ul class="btn-list"><li onclick="moveHandler('moveLeft')">moveLeft</li><li onclick="moveHandler('moveRight')">moveRight</li><li onclick="moveHandler('moveForward')">moveForward</li><li onclick="moveHandler('moveBackward')">moveBackword</li></ul>
function moveHandler (id) {const rate = 0.6const pos = getMoveTargetPosHandler(id, rate)setCameraViewerByDistanceHandler(id, rate, pos)}// 两点确定射线 并返回射线方向上的模型对象function getDirectionObj (pos) {const Cesium = window.Cesiumconst viewer = window.viewerconst start = viewer.camera.positionWCconst end = posconst direction = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(end, start, new Cesium.Cartesian3()), new Cesium.Cartesian3())const ray = new Cesium.Ray(start, direction)return viewer.scene.pickFromRay(ray)}// 获取两个坐标点间的距离function getDistanceHandler (obj, positionWC) {const dx = obj.x - positionWC.xconst dy = obj.y - positionWC.yconst dz = obj.z - positionWC.zreturn Math.sqrt(dx * dx + dy * dy + dz * dz)}// 根据碰撞到的物体和当前视角的距离判断是否进行视角movefunction setCameraViewerByDistanceHandler (id, rate, pos) {const obj = this.getDirectionObj(pos)if (obj) {const distance = this.getDistanceHandler(obj.position, window.viewer.camera.positionWC)console.log(distance);if (distance < 3) { // 视角和射线模型间的距离小于3时 认为碰撞到了 否则没有碰撞console.log('碰到了')} else {console.log('没碰到-----------')window.viewer.camera[id](rate)}} else {console.log('没碰到-----------')window.viewer.camera[id](rate)}}// 在相机实际移动之前获取到目标点位function getMoveTargetPosHandler (id, rate) {const Cesium = window.Cesiumconst Cartesian3 = Cesium.Cartesian3const viewer = window.viewerconst cameraPosition = viewer.camera.positionWCconst moveScratch = new Cartesian3()let amount = ratelet direction2 = viewer.camera.rightif (id === 'moveLeft') {amount = -ratedirection2 = viewer.camera.right} else if (id === 'moveRight') {amount = ratedirection2 = viewer.camera.right} else if (id === 'moveForward') {amount = ratedirection2 = viewer.camera.direction} else if (id === 'moveBackward') {amount = -ratedirection2 = viewer.camera.direction}moveScratch.x = direction2.x * amountmoveScratch.y = direction2.y * amountmoveScratch.z = direction2.z * amountconst pos = { x: 0, y: 0, z: 0 }pos.x = cameraPosition.x + moveScratch.xpos.y = cameraPosition.y + moveScratch.ypos.z = cameraPosition.z + moveScratch.zreturn pos}

完整代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>cesium实现碰撞检测</title><script src="./cesium/Cesium.js"></script><link href="./cesium/Widgets/widgets.css" rel="stylesheet" /><style>* {padding: 0;margin: 0;}html,body {width: 100%;height: 100%;}#cesium-container {width: 100%;height: 100%;}.btn-list {position: fixed;left: 100px;top: 100px;z-index: 10;list-style: none;}.btn-list li {padding: 4px 10px;width: 150px;height: 30px;background-color: #fff;border-radius: 4px;margin-bottom: 10px;cursor: pointer;display: flex;align-items: center;justify-content: center;}</style>
</head><body><div id="cesium-container" /><ul class="btn-list"><li onclick="moveHandler('moveLeft')">moveLeft</li><li onclick="moveHandler('moveRight')">moveRight</li><li onclick="moveHandler('moveForward')">moveForward</li><li onclick="moveHandler('moveBackward')">moveBackword</li></ul><script>window.onload = () => {initModelHandler()}// 初始化模型function initModelHandler () {Cesium.Ion.defaultAccessToken = '<YOUR KEY>'window.viewer = new Cesium.Viewer('cesium-container', {navigation: false, // 默认为true,是否显示导航罗盘控件。隐藏可在初始化场景时设置为falseanimation: false, // 是否创建动画小器件,左下角仪表baseLayerPicker: false, // 是否显示图层选择器,设置为true会报错:底图加载失败fullscreenButton: false, // 是否显示全屏按钮geocoder: false, // 是否显示geocoder搜索定位小器件,右上角查询按钮homeButton: false, // 是否显示Home按钮 回归到地球初始视角infoBox: false, // 是否显示信息框 一般点击模型图层的时候右上角出现的信息框的显隐sceneModePicker: false, // 是否显示3D/2D模式选择器selectionIndicator: true, // 是否显示选取指示器组件,例如点线面的点击聚焦等timeline: false, // 是否显示时间轴navigationHelpButton: false, // 是否显示右上角的帮助按钮contextOptions: {webgl: {alpha: true}}})initBaseMapHandler()}// 初始化生成基本底图function initBaseMapHandler () {viewEffectSet()setTdtMap()setFlyBuild()}function viewEffectSet () {const utc = Cesium.JulianDate.fromDate(new Date('2022/11/09 10:19:00'))// UTCconst viewer = window.viewerviewer.clock.currentTime = utc}function setTdtMap () {const viewer = window.viewerconst token = '<天地图token 自行获取>'viewer.imageryLayers.addImageryProvider(new Cesium.WebMapTileServiceImageryProvider({// 影像底图url: 'http://t{s}.tianditu.com/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=' + token,subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],layer: 'tdtImgLayer',style: 'default',format: 'image/jpeg',tileMatrixSetID: 'GoogleMapsCompatible', // 使用谷歌的瓦片切片方式maximumLevel: 18,show: true}))viewer.imageryLayers.addImageryProvider(new Cesium.WebMapTileServiceImageryProvider({url: 'http://t0.tianditu.gov.cn/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=' + token,layer: 'tdtCiaLayer',style: 'default',format: 'image/jpeg',tileMatrixSetID: 'GoogleMapsCompatible',maximumLevel: 18,show: true}))}function setFlyBuild () {const viewer = window.viewerwindow.allLayer = {}const dataString = ['tilesetData/1-1/tileset.json']const data = []dataString.forEach(item => {data.push(viewer.scene.primitives.add(new Cesium.Cesium3DTileset({url: item})).readyPromise)})Promise.all(data).then(res => {// 终止图层加载res.forEach(item => {const name = item._url.split('/')[1]window.allLayer[name] = item})setPositonByParams({"x":120.53748437160127,"y":29.982328906436397,"z":3.327780264079696,"heading":1.9128323575101343,"pitch":-0.08794655996484324,"roll":6.283185036694795})})}function setPositonByParams ({ x, y, z, heading, pitch, roll }) {const viewer = window.viewerviewer.camera.setView({destination: new Cesium.Cartesian3.fromDegrees(x, y, z),orientation: {heading,pitch,roll}})}function moveHandler (id) {const rate = 0.6const pos = getMoveTargetPosHandler(id, rate)setCameraViewerByDistanceHandler(id, rate, pos)}function getDirectionObj (pos) {const Cesium = window.Cesiumconst viewer = window.viewer// const camPos = getCurrentPosition() // 经纬度坐标// const start = Cesium.Cartesian3.fromDegrees(camPos.x, camPos.y, camPos.z)// const end = Cesium.Cartesian3.fromDegrees(pos.x, pos.y, pos.z)const start = viewer.camera.positionWCconst end = posconst direction = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(end, start, new Cesium.Cartesian3()), new Cesium.Cartesian3())const ray = new Cesium.Ray(start, direction)return viewer.scene.pickFromRay(ray)}// 获取两个坐标点间的距离function getDistanceHandler (obj, positionWC) {const dx = obj.x - positionWC.xconst dy = obj.y - positionWC.yconst dz = obj.z - positionWC.zreturn Math.sqrt(dx * dx + dy * dy + dz * dz)}// 根据碰撞到的物体和当前视角的距离判断是否进行视角movefunction setCameraViewerByDistanceHandler (id, rate, pos) {const obj = this.getDirectionObj(pos)if (obj) {const distance = this.getDistanceHandler(obj.position, window.viewer.camera.positionWC)console.log(distance);if (distance < 3) {console.log('碰到了')} else {console.log('没碰到-----------')window.viewer.camera[id](rate)}} else {console.log('没碰到-----------')window.viewer.camera[id](rate)}}// 在相机实际移动之前获取到目标点位function getMoveTargetPosHandler (id, rate) {const Cesium = window.Cesiumconst Cartesian3 = Cesium.Cartesian3const viewer = window.viewerconst cameraPosition = viewer.camera.positionWCconst moveScratch = new Cartesian3()let amount = ratelet direction2 = viewer.camera.rightif (id === 'moveLeft') {amount = -ratedirection2 = viewer.camera.right} else if (id === 'moveRight') {amount = ratedirection2 = viewer.camera.right} else if (id === 'moveForward') {amount = ratedirection2 = viewer.camera.direction} else if (id === 'moveBackward') {amount = -ratedirection2 = viewer.camera.direction}moveScratch.x = direction2.x * amountmoveScratch.y = direction2.y * amountmoveScratch.z = direction2.z * amountconst pos = { x: 0, y: 0, z: 0 }pos.x = cameraPosition.x + moveScratch.xpos.y = cameraPosition.y + moveScratch.ypos.z = cameraPosition.z + moveScratch.zreturn pos}</script>
</body></html>

【超图+CESIUM】【基础API使用示例】50、超图|CESIUM - moveLeft\moveRight\moveForward\moveBackward实现运动中的碰撞检测效果相关推荐

  1. 【超图+CESIUM】【基础API使用示例】04、超图|CESIUM - 设置地图风格样式

    前言 缺少前置学习使用资料,请自行查阅:[https://blog.csdn.net/weixin_44402694/article/details/123110136](https://blog.c ...

  2. 【超图+CESIUM】【基础API使用示例】10、超图|CESIUM - 场景出图、下载当前截图

    前言 缺少前置学习使用资料,请自行查阅:[https://blog.csdn.net/weixin_44402694/article/details/123110136](https://blog.c ...

  3. 【超图+CESIUM】【基础API使用示例】42、超图|CESIUM - 绘制编辑线段|读取kml文件绘制编辑|导出kml线段数据

    前言 缺少前置学习使用资料,请自行查阅:[https://blog.csdn.net/weixin_44402694/article/details/123110136](https://blog.c ...

  4. 【超图+CESIUM】【基础API使用示例】38、超图|CESIUM - 特效-云层设置

    前言 缺少前置学习使用资料,请自行查阅:[https://blog.csdn.net/weixin_44402694/article/details/123110136](https://blog.c ...

  5. 【超图+CESIUM】【基础API使用示例】41、超图|CESIUM - 特效-雪景设置

    前言 缺少前置学习使用资料,请自行查阅:[https://blog.csdn.net/weixin_44402694/article/details/123110136](https://blog.c ...

  6. 【超图+CESIUM】【基础API使用示例】43、超图|CESIUM - 绘制编辑面|读取kml文件绘制编辑|导出kml面数据

    前言 缺少前置学习使用资料,请自行查阅:[https://blog.csdn.net/weixin_44402694/article/details/123110136](https://blog.c ...

  7. 【超图+CESIUM】【基础API使用示例】22、超图|CESIUM - 标绘面:Cesium.DrawHandler绘制面Cesium.DrawMode.Polygon

    前言 缺少前置学习使用资料,请自行查阅:[https://blog.csdn.net/weixin_44402694/article/details/123110136](https://blog.c ...

  8. 【超图+CESIUM】【基础API使用示例】16、超图|CESIUM -设置地球模式:椭球模式、圆球模式

    前言 缺少前置学习使用资料,请自行查阅:[https://blog.csdn.net/weixin_44402694/article/details/123110136](https://blog.c ...

  9. HTML5 Canvas 基础API和实例

    开发HTML代码是一件简单的事情,一个文字编辑器,然后一个支持HTML5的浏览器即可(本人的浏览器是Firefox8.0.1).了解HTML的朋友应该知道,HTML5中最让人兴奋的API是canvas ...

最新文章

  1. 如何在bash脚本中提示用户进行确认? [重复]
  2. Android系统的架构
  3. 安卓4.4.4安装哪个微信版本_微信一个开关,速度立马提升一倍
  4. D. Mahmoud and Ehab and the binary string Codeforces Round #435 (Div. 2)
  5. fedora17的gnome3桌面美化
  6. ubuntu部署tomcat
  7. roundcube邮箱手机端_求一款能够云备份的安卓手机便签记事本?
  8. ArrayList理解(5)与vector区别
  9. 油漆面积 java_第八屆藍橋杯省賽 JavaA組 第十題 標題:油漆面積
  10. zookeeper学习之环境搭建
  11. Protel 99SE详细安装教程(附安装包)
  12. Cortex-M3 (NXP LPC1788)之IIS控制器
  13. 上海理工大计算机学研究生怎么样,上海理工大学(专业学位)计算机技术考研难吗...
  14. Java实现:挖金矿问题
  15. Work breakdown structure 简介
  16. fastlane实现Android自动化打包
  17. 数据结构bf算法步骤完整代码C语言,C语言实现BF算法
  18. 打开idea注释doc的rendered view模式
  19. 【思维导图】redis详解
  20. 电脑查询域名对应IP的过程

热门文章

  1. 手机访问网页,QQ咨询链接如何连接到自己的手机QQ
  2. 解决WES 7 中Composite Bus找不到驱动的bug
  3. C# 颜色和英文释义名称对照表
  4. Delphi 7连接MySql 5.5.15
  5. CASS或BMF软件命令栏不见了如何调出
  6. CenterOS 处理php环境
  7. 一个人该怎样找到自己真正热爱和擅长的事,并以此规划自己的人生?
  8. 带节日和农历的js日历 带农历的脚本:
  9. Activiti7工作流入门和基本使用-工作流引擎介绍
  10. 三菱PLC与第三方设备TCP通讯_不用在PLC内编程,快速实现西门子与欧姆龙、三菱等品牌的PLC之间实时通讯...