cesium 3dtile ClippingPlanes 多边形挖洞ClippingPlaneCollection

news2024/11/30 12:31:04

原理就是3dtiles里面的属性clippingPlanes

采用ClippingPlaneCollection,构成多边形来挖洞。

其次就是xyz法向量挖洞

clippingPlanes: new this.ffCesium.Cesium.ClippingPlaneCollection({
  unionClippingRegions: true, // true 表示多个切割面能合并为一个有效的切割区域
  planes: [
    new this.ffCesium.Cesium.ClippingPlane(
      new this.ffCesium.Cesium.Cartesian3(0.0, 0.0, -1.0), // 法向量
      23.0 // 切割平面到原点的距离(高度)
    )
  ]
})

以下是多边形裁剪

import * as Cesium from 'cesium'
class tileSetClipByPolygon {
  constructor(options) {
    this.tileSet = options.tileSet || null  //3dtiles 
    this.originPositions = options.originPositions || []  //点
    this.unionClippingRegions = !options.unionClippingRegions ? options.unionClippingRegions : true
    this.enabled = !options.enabled ? options.enabled : true
    this.edgeColor = options.edgeColor || Cesium.Color.WHITE
    this.edgeWidth = options.edgeWidth || 0.0
  }
  isClockwise(polygon) {
    var area = 0
    var length = polygon.length
    for (var i = 0; i < length; i++) {
      var j = (i + 1) % length
      area += polygon[i][0] * polygon[j][1] - polygon[j][0] * polygon[i][1]
    }
    return area < 0
  }
  getInverseTransform() {
    let transform
    let tmp = this.tileSet.root.transform
    if ((tmp && tmp.equals(Cesium.Matrix4.IDENTITY)) || !tmp) {
      // 如果root.transform不存在,则3DTiles的原点变成了boundingSphere.center
      transform = Cesium.Transforms.eastNorthUpToFixedFrame(this.tileSet.boundingSphere.center)
    } else {
      transform = Cesium.Matrix4.fromArray(this.tileSet.root.transform)
    }
    return Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4())
  }
  clippingByPositions(clipping) {
    // debugger
    console.log('this.tileSet', this.tileSet)
    this.tileSet.clippingPlanes = null
    const Cartesian3 = Cesium.Cartesian3
    const pointsLength = clipping.length
    const clockwise = this.isClockwise(clipping)
    //所有的裁切面
    const clippingPlanes = []
    let positions
    if (clockwise) {
      //如果为逆,则需要对数组取反
      positions = clipping.reverse()
    } else {
      positions = clipping
    }
    positions = clipping
    const inverseTransform = this.getInverseTransform()
    for (let i = 0; i < pointsLength; ++i) {
      const nextIndex = (i + 1) % pointsLength
      const next = Cesium.Matrix4.multiplyByPoint(inverseTransform, Cesium.Cartesian3.fromDegrees(positions[nextIndex][0], positions[nextIndex][1]), new Cesium.Cartesian3())
      const now = Cesium.Matrix4.multiplyByPoint(inverseTransform, Cesium.Cartesian3.fromDegrees(positions[i][0], positions[i][1]), new Cesium.Cartesian3())
      // 定义一个垂直向上的向量up
      let up = new Cesium.Cartesian3(0, 0, 10)
      //得到指向下一个点的向量
      let right = Cartesian3.subtract(next, now, new Cartesian3())
      right = Cartesian3.normalize(right, right)

      let normal = Cartesian3.cross(right, up, new Cartesian3())
      Cartesian3.normalize(normal, normal)
      //将法向量进行反向
      if (this.unionClippingRegions) {
        Cartesian3.negate(normal, normal)
      }

      //由于已经获得了法向量和过平面的一点,因此可以直接构造Plane,并进一步构造ClippingPlane
      let planeTmp = Cesium.Plane.fromPointNormal(now, normal)
      const clipPlane = Cesium.ClippingPlane.fromPlane(planeTmp)
      clippingPlanes.push(clipPlane)
    }
    let the = this
    const clipPlanes = new Cesium.ClippingPlaneCollection({
      planes: clippingPlanes,
      edgeWidth: the.edgeColor,
      edgeColor: the.edgeColor,
      enabled: the.enabled,
      unionClippingRegions: the.unionClippingRegions
    })
    console.log('clipPlanes', clipPlanes)
    this.tileSet.clippingPlanes = clipPlanes
  }
  removeTilesetClip() {
    this.tileSet.clippingPlanes.enabled = false
  }
}
export default tileSetClipByPolygon

使用

this.CeiumPolygonClipA = new CeiumPolygonClip({
          tileSet: photographyTileset.value,
          originPositions: clipping,
          unionClippingRegions: false
        })
        this.CeiumPolygonClipA.clippingByPositions(clipping)

CesiumJS 中,ClippingPlaneClippingPlaneCollection 通常用于控制哪些部分的场景或模型是可见的。通过切割面(ClippingPlanes),你可以裁剪或隐藏指定区域的内容。clippingPlanes 主要应用于以下几种对象:

1. 3D Tiles

3D Tiles 是一种用于存储和传输大规模 3D 场景的格式,它可以通过 clippingPlanes 进行裁剪。这是一个非常常见的应用,尤其是在城市建模和大规模场景可视化中。

  • clippingPlanes 可以直接应用于 Cesium3DTileset 对象,以裁剪掉 3D Tiles 模型的一部分。

示例:

const tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
  url: 'path/to/your/3dtiles/tileset.json',
  clippingPlanes: new Cesium.ClippingPlaneCollection({
    planes: [
      new Cesium.ClippingPlane(Cesium.Cartesian3.UNIT_Z, 100.0)
    ]
  })
}));

在这个例子中,Cesium3DTileset 会被切割,只显示离 Z 轴 100 单位以内的区域。

2. Primitive(原始几何体)

clippingPlanes 也可以用于 Primitive 对象(如几何体、模型等),这是最基础的 3D 对象类型。通过将 ClippingPlaneCollection 赋值给 Primitive,可以在渲染时裁剪它的几何体。

  • 这种方法适用于自定义的几何体或其他静态几何体,例如:球体、立方体等。

示例:

const sphereGeometry = new Cesium.SphereGeometry({
  radius: 100.0
});

const sphere = new Cesium.Primitive({
  geometryInstances: new Cesium.GeometryInstance({
    geometry: sphereGeometry,
    modelMatrix: Cesium.Matrix4.fromTranslation(new Cesium.Cartesian3(0.0, 0.0, 0.0)),
  }),
  appearance: new Cesium.MaterialAppearance({
    material: Cesium.Material.fromType('Color', {
      color: Cesium.Color.RED
    })
  }),
  clippingPlanes: new Cesium.ClippingPlaneCollection({
    planes: [
      new Cesium.ClippingPlane(Cesium.Cartesian3.UNIT_Z, 50.0) // 裁剪半径为 50 的球体
    ]
  })
});

viewer.scene.primitives.add(sphere);

在这个例子中,创建了一个球体并将其裁剪,裁剪面距离原点 50 单位,隐藏球体超过该高度的部分。

3. Models(3D 模型)

ClippingPlanes 也可以应用于 3D 模型(如 glTF 模型)。在 Cesium.Model 中,clippingPlanes 可以用来裁剪模型的一部分。

示例:

const model = viewer.scene.primitives.add(Cesium.Model.fromGltf({
  url: 'path/to/your/model.glb',
  clippingPlanes: new Cesium.ClippingPlaneCollection({
    planes: [
      new Cesium.ClippingPlane(Cesium.Cartesian3.UNIT_Z, 50.0)
    ]
  })
}));

这段代码将对加载的 glTF 模型应用切割面,裁剪掉离 Z 轴 50 单位以上的部分。

4. Terrain(地形)

对于 Cesium 中的地形数据(例如使用 3D Tiles 数据源的地形),可以通过切割面进行裁剪。地形通常是通过 Cesium.CesiumTerrainProvider 加载的,而切割面可以用来限制地形的显示。

这种应用场景通常适用于大规模的地形可视化,用户可以通过切割面查看地形的特定部分,或从不同的切割角度进行分析。

5. Imagery(影像图层)

clippingPlanes 还可以用于影像图层,特别是当你想要切割或限制影像图层的显示时。通过使用 clippingPlanes,你可以将某些区域的影像数据裁剪掉,以使其他数据更加突出。

示例:

const imageryLayer = viewer.imageryLayers.addImageryProvider(new Cesium.UrlTemplateImageryProvider({
  url : 'https://your-imagery-url/{z}/{x}/{y}.png'
}));

imageryLayer.clippingPlanes = new Cesium.ClippingPlaneCollection({
  planes: [
    new Cesium.ClippingPlane(Cesium.Cartesian3.UNIT_Z, 100.0)
  ]
});

在这个例子中,影像图层会被切割,只显示离 Z 轴 100 单位以内的部分。


其他可能的应用场景:

  1. Skybox(天空盒) clippingPlanes 也可用于裁剪 天空盒,这在某些需要动态裁剪天空内容的应用中有用。

  2. Custom Primitives(自定义原始几何体) 如果你自己创建了自定义几何体,可以通过 clippingPlanes 使其进行裁剪,减少计算负担或者实现特定的可视化效果。

  3. Ground Clipping (地面裁剪) 对于需要动态控制地面显示的场景,clippingPlanes 可以用来裁剪地面,或者将其与其他场景元素进行交互。


总结

ClippingPlanesCesium 中是一个非常灵活的工具,可以应用于以下对象:

  • 3D Tiles(如城市模型)
  • Primitives(如几何体)
  • Models(如 glTF 模型)
  • Terrain(地形)
  • Imagery(影像图层)
  • Skybox(天空盒)
  • Custom Primitives(自定义几何体)

这些对象可以通过 ClippingPlaneCollection 结合多个切割面来实现不同的裁剪效果,从而动态地控制场景中的可见部分。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2250424.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AMD的AI芯片Instinct系列介绍

AMD最强AI芯片发布&#xff01; 在旧金山举行的Advancing AI 2024大会上&#xff0c;AMD推出Instinct MI325X AI加速器&#xff08;以下简称MI325X&#xff09;&#xff0c;直接与英伟达的Blackwell芯片正面交锋。 现场展示的数据显示&#xff0c;与英伟达H200的集成平台H200 …

【大数据学习 | Spark调优篇】Spark之内存调优

1. 内存的花费 1&#xff09;每个Java对象&#xff0c;都有一个对象头&#xff0c;会占用16个字节&#xff0c;主要是包括了一些对象的元信息&#xff0c;比如指向它的类的指针。如果一个对象本身很小&#xff0c;比如就包括了一个int类型的field&#xff0c;那么它的对象头实…

基于深度学习的卷积神经网络十二生肖图像识别系统(PyQt5界面+数据集+训练代码)

本研究提出了一种基于深度学习的十二生肖图像识别系统&#xff0c;旨在利用卷积神经网络&#xff08;CNN&#xff09;进行图像分类&#xff0c;特别是十二生肖图像的自动识别。系统的核心采用了两种经典的深度学习模型&#xff1a;ResNet50和VGG16&#xff0c;进行图像的特征提…

kali linux 装 virtual box 增强工具 Guest Addition

kali linux 装 virtual box 增强工具 Guest Addition install Virtual Box Guest Addition in kali linux 搞了一下午&#xff0c;最终发现是白折腾。 kali linux 自带 virtual box 的增强工具。 kali linux 2021.3 之后的版本都是自带virtual box 增强工具 解决方法 直接…

vue3请求接口报错:Cannot read properties of undefined (reading ‘data‘)

文章目录 报错内容解决方案 报错内容 Cannot read properties of undefined (reading ‘data’) 解决方案 响应未按预期返回 确保服务器返回的数据结构符合预期。例如&#xff0c;服务器可能返回了一个错误响应&#xff0c;而不是预期的 JSON 数据。 检查响应 在 response 拦…

RocketMQ rocketmq-tools管理主题

RocketMQ rocketmq-tools管理主题 环境和软件版本增删改查 环境和软件版本 Win10、IDEA、Jdk1.8、rocketmq 5.1.3、rocketmq-tools 5.1.3 引入依赖 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-tools</artifactId&g…

《datawhale2411组队学习 模型压缩技术7:NNI剪枝》

文章目录 一、NNI简介二、 NNI剪枝快速入门2.1 加载并训练模型2.2 模型剪枝2.3 模型加速&#xff08;剪枝永久化&#xff09;2.4 微调压缩模型2.5 Slim Pruner测试 三、 使用NNI3.0进行Bert压缩&#xff08;剪枝、蒸馏)3.1 数据预处理3.2 训练模型3.3 设置模型蒸馏函数3.4 修剪…

C#学写了一个程序记录日志的方法(Log类)

1.错误和警告信息单独生产文本进行记录&#xff1b; 2.日志到一定内存阈值可以打包压缩&#xff0c;单独存储起来&#xff0c;修改字段MaxLogFileSizeForCompress的值即可&#xff1b; 3.Log类调用举例&#xff1a;Log.Txt(JB.信息,“日志记录内容”,"通道1"); usi…

Java设计模式——职责链模式:解锁高效灵活的请求处理之道

嘿&#xff0c;各位 Java 编程大神和爱好者们&#xff01;今天咱们要一同深入探索一种超厉害的设计模式——职责链模式。它就像一条神奇的“处理链”&#xff0c;能让请求在多个对象之间有条不紊地传递&#xff0c;直到找到最合适的“处理者”。准备好跟我一起揭开它神秘的面纱…

安装SQL Server 2022提示需要Microsoft .NET Framework 4.7.2 或更高版本

安装SQL Server 2022提示需要Microsoft .NET Framework 4.7.2 或更高版本。 原因是&#xff1a;当前操作系统版本为Windows Server 2016 Standard版本&#xff0c;其自带的Microsoft .NET Framework 版本为4.6太低&#xff0c;不满足要求。 根据报错的提示&#xff0c;点击链接…

高德地图 Readme GT 定制版 10.25.0.3249 | 极致简洁

这款定制版高德地图去除了广告&#xff0c;运行速度更快。虽然没有车道级导航、打车功能和红绿灯倒计时等功能&#xff0c;但支持正常登录和收藏功能。检测更新始终为最新版本。 大小&#xff1a;82.5M 下载地址&#xff1a; 百度网盘&#xff1a;https://pan.baidu.com/s/1Y…

Admin.NET框架使用宝塔面板部署步骤

文章目录 Admin.NET框架使用宝塔面板部署步骤&#x1f381;框架介绍部署步骤1.Centos7 部署宝塔面板2.部署Admin.NET后端3.部署前端Web4.访问前端页面 Admin.NET框架使用宝塔面板部署步骤 &#x1f381;框架介绍 Admin.NET 是基于 .NET6 (Furion/SqlSugar) 实现的通用权限开发…

Excel中根据某列内容拆分为工作簿

简介&#xff1a;根据A列的内容进行筛选&#xff0c;将筛选出来的数据生成一个新的工作簿(可以放到指定文件夹下)&#xff0c;且工作簿名为筛选内容。 举例&#xff1a; 将上面的内容使用VBA会在当前test1下生成5个工作簿&#xff0c;工作簿名分别为TEST1.xls TEST2.xls TEST3…

JavaWeb实战(1)(重点:分页查询、jstl标签与jsp、EL表达式、Bootstrap组件搭建页面、jdbc)

目录 一、jstl标签。 &#xff08;1&#xff09;基本概念。 &#xff08;2&#xff09;使用前提。 &#xff08;3&#xff09;"<%...%>"与"<%%>"。 &#xff08;4&#xff09;使用jstl标签的步骤。 1、导入对应jar包。 2、引入核心标签库。&am…

Linux:makefile的使用

makefile小结&#xff1a; makefile的应用&#xff1a; 一个简单的 Makefile 文件包含一系列的“规则”&#xff0c;其样式如下&#xff1a; 目标(target)…: 依赖(prerequiries)… 命令(command) 目标(target)通常是要生成的文件的名称&#xff0c;可以是可执行文件或OBJ文件…

springboot中使用mongodb完成评论功能

pom文件中引入 <!-- mongodb --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> yml中配置连接 data:mongodb:uri: mongodb://admin:1234561…

TCGA 编码格式解读 | 怎么区分是不是肿瘤样品?

最权威参考资料 https://docs.gdc.cancer.gov/Encyclopedia/pages/TCGA_Barcode/ "-"分割符的第四位是Sample type&#xff1a; Tumor types range from 01 - 09,normal types from 10 - 19and control samples from 20 - 29. See Code Tables Report for a compl…

百度 文心一言 vs 阿里 通义千问 哪个好?

背景介绍&#xff1a; 在当前的人工智能领域&#xff0c;随着大模型技术的快速发展&#xff0c;市场上涌现出了众多的大规模语言模型。然而&#xff0c;由于缺乏统一且权威的评估标准&#xff0c;很多关于这些模型能力的文章往往基于主观测试或自行设定的排行榜来评价模型性能…

【linux学习指南】Linux进程信号产生(二)软件中断

文章目录 &#x1f4dd; 由软件条件产⽣信号&#x1f320; 基本alarm验证-体会IO效率问题&#x1f309;设置重复闹钟 &#x1f320;如何理解软件条件&#x1f309;如何简单快速理解系统闹钟 &#x1f6a9;总结 &#x1f4dd; 由软件条件产⽣信号 SIGPIPE 是⼀种由软件条件产⽣…

蓝桥杯每日真题 - 第24天

题目&#xff1a;&#xff08;货物摆放&#xff09; 题目描述&#xff08;12届 C&C B组D题&#xff09; 解题思路&#xff1a; 这道题的核心是求因数以及枚举验证。具体步骤如下&#xff1a; 因数分解&#xff1a; 通过逐一尝试小于等于的数&#xff0c;找到 n 的所有因数…