Cesium——平面裁切

关于平面裁切的例子,官网有两个,3D Tiles裁切地形裁切

1、ClippingPlaneCollection

要实现平面裁切,首先需要创建裁切平面集合,根据官网的例子我们创建一个裁切平面。我们在api文档中找到ClippingPlaneCollection,创建Cesium.ClippingPlaneCollection的options如下:

new Cesium.ClippingPlaneCollection(options)
名称默认值描述
planesClippingPlane用于在每个平面的外部选择性地禁用渲染 的对象数组。
enabledtrue确定剪切平面是否处于活动状态。
modelMatrix4x4变换矩阵,指定相对于剪裁平面原始坐标系的附加变换。
unionClippingRegionsfalse如果为true,则位于任何平面外部的区域将被剪裁,即取并集。否则,位于每个平面的外部区域才会被剪裁,即取交集
edgeColorColor.WHITE用于突出显示裁剪对象的边缘的颜色。
edgeWidth0剪裁对象的边缘的高光的宽度(以像素为单位)。

关于unionClippingRegions中“外部”的含义是指,平面法向反方向的区域。那么,平面的法向怎么定义呢?我们需要在planes中定义所需裁切平面,我们在api文档中找到ClippingPlane

外部区域

2、ClippingPlane
new Cesium.ClippingPlane(normal, distance)
名称默认值
normal平面的法线方向。
distance原点到平面的最短距离。距离符号决定了原点在平面的哪一侧。如果距离为正,则原点在法向的半空间中;如果距离为负,则原点在法向反方向的半空间中;如果距离为零,则平面通过原点。

平面法向所在坐标系是以正东方为x轴正方向,正北方为y轴正方向,正上面为z轴正方向的坐标系

3、创建裁切平面

创建裁切平面的代码如下,我们先以一个平面为例来说明

var clippingPlanes = new Cesium.ClippingPlaneCollection({
    planes : [
        new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 0.0, -1.0), 0.0)
    ],
    edgeColor : Cesium.Color.RED,
    edgeWidth : 1
});

代码的意思为:创建了一个法向为正下方、且经过原点的裁切平面,平面与裁切对象相交边缘显示为1像素的红色。


下面我们通过两个例子来看一下如何对裁切对象进行裁切

1、模型裁切

使用上面创建的平面对模型进行裁切。在球上添加一个模型,并设置其属性clippingPlanes的值为上面创建的平面,代码如下:

var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, 100.0);
var heading = Cesium.Math.toRadians(135.0);
var pitch = 0.0;
var roll = 0.0;
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
var entity = viewer.entities.add({
    name : url,
    position : position,
    orientation : orientation,
    model : {
        uri : '../../../../Apps/SampleData/models/CesiumAir/Cesium_Air.glb',
        scale : 8,
        minimumPixelSize : 100.0,
        clippingPlanes : clippingPlanes     // 设置模型的裁切平面
    }
});

因为裁切平面的法向是向下的,平面以上为外部区域,所以会将模型相应的上部门切除,效果图如下,我们可以看到边界处有1px的红色
在这里插入图片描述
假如改变平面法向的方向,即将上面的new Cesium.Cartesian3(0.0, 0.0, -1.0)改为new Cesium.Cartesian3(0.0, 0.0, 1.0),那么裁切平面的法向是向上的,平面以下为外部区域,所以会将模型相应的下部门切除

var clippingPlanes = new Cesium.ClippingPlaneCollection({
    planes : [
        new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 0.0, 1.0), 0.0)
    ],
    edgeColor : Cesium.Color.RED,
    edgeWidth : 1
});

在这里插入图片描述

2、裁切地形

首先,初始化的时候我们先为地球加上地形。接下来是裁切地形,与上面类似,同样是先创建裁切平面集合。
比如我们想要在地形上切出一个方形的洞。那么必然要创建四个裁切平面,四面的法向如下图所示,那么中心区域即是四个平面外部的交集,如要将平面相交的中间区域裁掉,unionClippingRegions的值应设置为false。
在这里插入图片描述
原点在法向相反的方向,所以distance应该设置为负值

var position = Cesium.Cartographic.toCartesian(new Cesium.Cartographic.fromDegrees(116.39, 39.9, 0));
var distance = -700
var clippingPlanes = new Cesium.ClippingPlaneCollection({
    modelMatrix : Cesium.Transforms.eastNorthUpToFixedFrame(position),
    planes : [
        new Cesium.ClippingPlane(new Cesium.Cartesian3( 1.0,  0.0, 0.0), distance),
        new Cesium.ClippingPlane(new Cesium.Cartesian3(-1.0,  0.0, 0.0), distance),
        new Cesium.ClippingPlane(new Cesium.Cartesian3( 0.0,  1.0, 0.0), distance),
        new Cesium.ClippingPlane(new Cesium.Cartesian3( 0.0, -1.0, 0.0), distance)
    ],
    unionClippingRegions: false
});
viewer.scene.globe.clippingPlanes = clippingPlanes

这段代码,我们创建了右、左、前、后四个裁切平面。因为每个平面到原点的距离均为700,那么,最终得到的是一个挖去1400m*1400地形的地球。
在这里插入图片描述
如果只保留中心区域,平面的法向必然如下图所示,并且需要将四个平面所有外部区域全部裁掉,unionClippingRegions的值设置为true,即取并集
在这里插入图片描述
原点在法向的方向,所以distance应该设置为正值

var position = Cesium.Cartographic.toCartesian(new Cesium.Cartographic.fromDegrees(116.39, 39.9, 0));
var distance = 700
var clippingPlanes = new Cesium.ClippingPlaneCollection({
    modelMatrix : Cesium.Transforms.eastNorthUpToFixedFrame(position),
    planes : [
        new Cesium.ClippingPlane(new Cesium.Cartesian3( 1.0,  0.0, 0.0), distance),
        new Cesium.ClippingPlane(new Cesium.Cartesian3(-1.0,  0.0, 0.0), distance),
        new Cesium.ClippingPlane(new Cesium.Cartesian3( 0.0,  1.0, 0.0), distance),
        new Cesium.ClippingPlane(new Cesium.Cartesian3( 0.0, -1.0, 0.0), distance)
    ],
    unionClippingRegions: true
});
viewer.scene.globe.clippingPlanes = clippingPlanes

这段代码,我们创建了左、右、后、前四个裁切平面。因为每个平面到原点的距离均为700,那么最终得到的是一个1400m*1400m的区域。
在这里插入图片描述

总结

关于这个功能,难点在于平面和unionClippingRegions的设置,只要掌握了各个参数的含义,使用起来就会得心应手,官网的两个例子还是很详细的,可以作为参考。

  • 11
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
根据提供的代码和引用,Cesium中的ClippingPlaneCollectionClippingPlane类用于创建和管理裁剪平面。裁剪平面可以用来裁剪模型或场景,只显示在平面范围内的部分,并过滤掉平面范围外的内容。 在给定的代码中,使用了ClippingPlaneCollectionClippingPlane来创建裁剪平面,并将其应用于Cesium的3D模型。裁剪平面可以通过设置平面的法线方向和距离来定义。如果距离为正值,则裁剪平面位于法线的方向上,如果距离为负值,则裁剪平面位于法线的反方向上,如果距离为零,则裁剪平面经过原点。 在这个例子中,裁剪平面的法线方向为(0.0, 0.0, -0.1),距离为0.0。裁剪平面的集合被添加到了Cesium的3D Tileset中,以实现裁剪效果。这样,在渲染时,只有位于裁剪平面内的部分会被显示,而位于裁剪平面外的部分会被裁剪掉。 所以,cesium plane平面是通过ClippingPlaneCollectionClippingPlane来创建和定义的,用于在Cesium中实现裁剪效果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [cesium平面裁切](https://blog.csdn.net/alisa_lisa/article/details/88106624)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [Cesium示例程序学习和讲解(7)-模型裁剪平面](https://blog.csdn.net/qq_32077521/article/details/129573869)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值