threejs 根据离散点生成不规则三角网(三角剖分),检测点是否在该三角网内(区域搜索)

        我们知道threejs中的模型都是一个个三角网组成的,三角网数量越多,模型就越精细。

        在 Three.js 中,你可以通过创建一个三角网格对象来表示三维模型,这个对象通常由一个顶点数组和一个索引数组构成。顶点数组包含了模型的各个顶点的坐标信息,而索引数组则定义了如何将这些顶点连接起来形成三角形。通过修改这些顶点的坐标信息,你可以改变模型的形状,从而实现各种各样的动态效果。

一、导入剖分三角形网格的库

npm install delaunator
//引入
import Delaunator from "delaunator";

 二、计算三角形顶点索引

//传入数据points:[{x:0,y:0,z:0}]
const points3d = points.map((t) => new Vector3(t.x, t.y, t.z));

const indexDelaunay = Delaunator.from(
    points3d.map((v) => {
      return [v.x, v.z];
    })
);

三、生成模型

const geom = new BufferGeometry().setFromPoints(points3d);
const meshIndex = [];
for (let i = 0; i < indexDelaunay.triangles.length; i++) {
    meshIndex.push(indexDelaunay.triangles[i]);
}
geom.setIndex(meshIndex);
const mesh = new Mesh(geom,new MeshBasicMaterial({
    color: "red",
    wireframe: true,
    transparent: true,
    opacity: 0.5,
    side: THREE.DoubleSide,//双面展示
}));
scene.add(mesh)//添加到场景

四、检测点是否在网格内        

判断点是否在网格内,并且与网格的垂直距离不超过 (阈值)

思路:

        1.遍历顶点索引,然后取出对应顶点坐标,生成三角形

        2.计算三角形平面法向量,计算点到三角形平面所在距离,如果小于等于某个阈值,就继续检查是否在三角形内部

        3.计算投影点,检查投影点是否在三角形边界上,在就返回true,否则返回false 

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
生成三角网面模型可以使用 Delaunay 三角剖分算法,它是一种将离散集转化为三角形网格的方法。在 JavaScript 中,可以使用 D3.js 库提供的 Delaunay 类来实现。 首先,需要将地形数据以 JSON 格式存储,并通过 JavaScript 读取数据。然后,使用 D3.js 的 Delaunay 类,将数据转化为三角形网格。最后,使用 WebGL 或者 Three.js 等图形库,将三角形网格渲染出来。 以下是一个简单的示例代码: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Discrete Terrain Data Points to Triangular Mesh Model</title> <script src="https://d3js.org/d3.v6.min.js"></script> <script src="https://d3js.org/d3-delaunay.v2.min.js"></script> </head> <body> <canvas id="canvas"></canvas> <script> // 读取地形数据 d3.json("terrain_points.json").then(function(data) { // 转化为三角形网格 const delaunay = Delaunay.from(data); const triangles = delaunay.triangles(); // 渲染三角形网格 const canvas = document.getElementById("canvas"); const context = canvas.getContext("webgl"); const vertices = []; for (let i = 0; i < triangles.length; i += 3) { vertices.push(data[triangles[i]][0], data[triangles[i]][1], 0); vertices.push(data[triangles[i+1]][0], data[triangles[i+1]][1], 0); vertices.push(data[triangles[i+2]][0], data[triangles[i+2]][1], 0); } const vertexBuffer = context.createBuffer(); context.bindBuffer(context.ARRAY_BUFFER, vertexBuffer); context.bufferData(context.ARRAY_BUFFER, new Float32Array(vertices), context.STATIC_DRAW); const vertexShaderSource = ` attribute vec3 a_position; void main() { gl_Position = vec4(a_position, 1); }`; const fragmentShaderSource = ` precision mediump float; void main() { gl_FragColor = vec4(0, 0, 1, 1); }`; const vertexShader = context.createShader(context.VERTEX_SHADER); context.shaderSource(vertexShader, vertexShaderSource); context.compileShader(vertexShader); const fragmentShader = context.createShader(context.FRAGMENT_SHADER); context.shaderSource(fragmentShader, fragmentShaderSource); context.compileShader(fragmentShader); const program = context.createProgram(); context.attachShader(program, vertexShader); context.attachShader(program, fragmentShader); context.linkProgram(program); context.useProgram(program); const positionAttributeLocation = context.getAttribLocation(program, "a_position"); context.enableVertexAttribArray(positionAttributeLocation); context.bindBuffer(context.ARRAY_BUFFER, vertexBuffer); context.vertexAttribPointer(positionAttributeLocation, 3, context.FLOAT, false, 0, 0); context.drawArrays(context.TRIANGLES, 0, vertices.length / 3); }); </script> </body> </html> ``` 在这个示例中,假设地形数据已经以 JSON 格式存储在 terrain_points.json 文件中。读取数据使用了 D3.js 库提供的 d3.json() 方法。将数据转化为三角形网格使用了 Delaunay 类的 from() 和 triangles() 方法。渲染三角形网格使用了 WebGL,使用了 WebGL 的基本操作和着色器编程。 需要注意的是,这个示例只是一个简单的示例,几乎没有进行任何优化。在实际应用中,可能需要对数据进行预处理、对三角形网格进行加密、使用更高级的着色器等等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值