首页 > 其他分享 >Cesium自定义多边形进行模型剖切

Cesium自定义多边形进行模型剖切

时间:2022-12-30 14:36:23浏览次数:48  
标签:const 自定义 Cartesian3 剖切 transform normal Cesium new

方法

针对自定义绘制多边形进行模型剖切实际上有2种方法
方法一:

  • 利用cesium自带的ClippingPlaneCollection进行模型剖切,通过绘制的点,把剖切面构造出来,进行实现模型剖切

方法二:

  • 通过Cesium自身写入shader方法实现,通过判断点是否在多边形内实现剖切

因为这里没有通过方法二实现,因此这里只对方法一进行简述

原理

对于平面的normal,它指向的方向将不会被裁剪,反向的方向才会被裁剪。

1、绘制不规则多边形
2、取不规则多边形中的点的数据(若绘制的顺序是逆时针绘制,则还需要对点数据进行取反操作)
3、点与点之间绘制同向的向量,与向上的向量进行叉乘得到面的法向量(点+法向量即可构造一个面)
4、遍历点与操作3类似,即可构造一系列的剖切面

注意

img
在这一段描述中可以知道原点的选择直接影响到ClippingPlane的构造,如果root.transform存在,需要使用root.transform对应的坐标原点作为构造ClippingPlane时的坐标原点,如果不存在的话,就使用boundingSphere.center。

因此这里计算绘制点的坐标的时候需要加上坐标转换的代码

function getInverseTransform (tileSet) {
  let transform
  let tmp = tileSet.root.transform
  if ((tmp && tmp.equals(Cesium.Matrix4.IDENTITY)) || !tmp) {
  	// 如果root.transform不存在,则3DTiles的原点变成了boundingSphere.center
    transform = Cesium.Transforms.eastNorthUpToFixedFrame(tileSet.boundingSphere.center)
  } else {
    transform = Cesium.Matrix4.fromArray(tileSet.root.transform)
  }
  return Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4())
}

每一个点在与下一个点形成right向量的时候,都需要进行坐标转换,使得点能与模型的局部坐标对应得上,否则形成的面会不在模型上。

关键代码实现

这里的关键代码实际上就是指原理中所说的第三步与第四步,把tileset与绘制的点丢到该方法中即可

          const clippingByPositions = (tilesetData, originPositions) => {
            const Cartesian3 = Cesium.Cartesian3;
            const pointsLength = originPositions.length;
            const clockwise = getPolygonAnticlockwise(originPositions);
            //所有的裁切面
            const clippingPlanes = [];
            let positions;
            if (clockwise) {
              //如果为逆,则需要对数组取反
              positions = originPositions.reverse();
            } else {
              positions = originPositions;
            }

            //转换矩阵
            const inverseTransform = Cesium.Matrix4.inverseTransformation(
              tilesetData.root.transform,
              new Cesium.Matrix4()
            );
            for (let i = 0; i < pointsLength; ++i) {
              const nextIndex = (i + 1) % pointsLength;
              const next = Cesium.Matrix4.multiplyByPoint(
                inverseTransform,
                positions[nextIndex],
                new Cesium.Cartesian3()
              );
              const now = Cesium.Matrix4.multiplyByPoint(
                inverseTransform,
                positions[i],
                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(clippingType.object.clippingType==='内部剖切'){
                  Cartesian3.negate(normal, normal);
                }
              //将法向量进行反向
              // Cartesian3.negate(normal, normal);

              //由于已经获得了法向量和过平面的一点,因此可以直接构造Plane,并进一步构造ClippingPlane
              let planeTmp = Cesium.Plane.fromPointNormal(now, normal);
              const clipPlane = Cesium.ClippingPlane.fromPlane(planeTmp);

              clippingPlanes.push(clipPlane);
            }

            const clipPlanes = new Cesium.ClippingPlaneCollection({
              planes: clippingPlanes,
              edgeWidth: 0.0,
              edgeColor: Cesium.Color.WHITE,
              enabled: true,
              unionClippingRegions: clippingType.object.clippingType==='内部剖切'?false:true,
            });
            tilesetData.clippingPlanes = clipPlanes;
            console.log("clippingPlanes", tilesetData.clippingPlanes);
          };

实现效果

内部裁切
img

外部裁切
img

标签:const,自定义,Cartesian3,剖切,transform,normal,Cesium,new
From: https://www.cnblogs.com/webglblog/p/17014799.html

相关文章

  • Java 自定义Excel数据排序
    通常,我们可以在Excel中对指定列数据执行升序或者降序排序,排序时可依据单元格中的数值、单元格颜色、字体颜色或图标等。在需要自定义排序情况下,我们也可以自行根据排序需要......
  • Wix自定义操作如何以管理员身份运行
    提问Wix自定义操作如何以管理员身份运行回答如果是要让Action用管理员的身份去执行:Impersonate="no"<CustomActionId='RegisterOPC'FileKey='OPCDAServerRegister.b......
  • 自定义注解 + AOP切面 (切面不生效)
    背景业务开发,需要做一个操作日志,操作日志需要记录某一条数据在操作前后的值的变化记录,并写到操作记录表。这种情况,使用自定义注解,加个切面,再合适不过了。于是就开干。......
  • 自定义View,流式布局实践
     一、效果图: 二、FlowLayout实现packagecom.example.widgetsview;importandroid.content.Context;importandroid.content.res.Resources;importandroid.gr......
  • 【维生素C语言】第十二章 - C语言自定义类型讲解(联合体、枚举、联合体)
     原标题:自定义类型讲解?楼下保安大爷直呼内行!!【C语言】前言:本章将对C语言自定义类型进行讲解,前期我们讲过结构体,这章将会把前面结构体还没讲完的知识继续补充。一、结构体(st......
  • vue3+TS 自定义指令:长按触发绑定的函数
    vue3+TS自定义指令:长按触发绑定的函数而然间看到一个在vue2中写的长按触发事件的自定义指定,想着能不能把他copy到我的vue3项目中呢。编写自定义指令时遇到的几个难点1.......
  • windows 10 桌面ctrl alt 自定义快捷键打开程序慢 响应很慢 延迟问题
    思路为:关闭后台应用具体步骤如下:1.)设置,搜索 隐私  2.)找到隐私设置  3.)关闭后台这些后台应用,我都不需要,所以直接全部关闭了,如果有需要可以逐个实验,查找出来到底是哪个后......
  • WPF 自定义附加事件
    我们都知道路由事件,而附加事件用的比较少。但如果是通用的场景,类似附加属性,附加事件就很有必要的。举个例子,输入设备有很多种,WPF中输入事件主要分为鼠标、触摸、触笔:WPF......
  • 自定义view01 - 综述
    TypedArrayvaltypedArray:TypedArray=context.obtainStyledAttributes(attrs,R.styleable.EdgeTransparentView)position=typedArray.getI......
  • 自定义View03 - Canvas
    save/savelayerCanvas里面牵扯两种坐标系:Canvas自己的坐标系、绘图坐标系,当Canvas画布被创建时,Canvas的坐标系就被创建了,并且此坐标系是固定不变的,就是(0,0)到Canvas的宽高......