three.js GeometryUtils 指南:用 Hilbert 曲线与 Gosper 曲线生成程序化几何坐标 three.js GeometryUtils 指南用 Hilbert 曲线与 Gosper 曲线生成程序化几何坐标【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.jsGeometryUtils 是 three.js 提供的一组曲线/空间填充曲线坐标生成工具包含hilbert2D、hilbert3D与gosper三个函数可用于快速生成 Hilbert 曲线与 Gosper 岛的顶点序列。本指南围绕 GeometryUtils 官方文档 展开并结合 examples/jsm/utils/GeometryUtils.js 的源码实现与官方示例讲解每个函数的签名、参数含义、默认值与底层递归原理最终给出可直接运行的 three.js 实战用法帮助你用这些几何工具搭建曲线网格、虚线路径与程序化地形骨架。模块导入方式GeometryUtils 是 three.js 的 addon附加模块不会被three核心包自动导出必须显式导入import * as GeometryUtils from three/addons/utils/GeometryUtils.js;在官方示例中这一导入通常配合 importmap 使用例如 webgl_lines_dashed.html 中的映射方式script typeimportmap { imports: { three: ../build/three.module.js, three/addons/: ./jsm/ } } /script script typemodule import * as THREE from three; import * as GeometryUtils from three/addons/utils/GeometryUtils.js; /script如果你使用构建工具如 Vite、Rollup、webpack也可以从打包入口直接获取。在源码层面GeometryUtils 同时通过 examples/jsm/Addons.js 以export * as GeometryUtils from ./utils/GeometryUtils.js的形式统一导出。方法总览该模块共导出 3 个函数均接受纯数值/向量参数并返回坐标数组不依赖任何渲染上下文方法作用返回类型gosper( size )生成 XY 平面上的 Gosper 岛Gosper curveArray.number扁平坐标每 3 个一组hilbert2D( center, size, iterations, v0, v1, v2, v3 )生成二维 Hilbert 曲线坐标Array.Vector3hilbert3D( center, size, iterations, v0...v7 )生成三维 Hilbert 曲线坐标Array.Vector3文档中三个方法均标注为(inner)表示它们是模块内部 API以几何算法工具的形式提供给用户组合使用。.gosper( size : number ) : Array.生成一条位于 XY 平面内的 Gosper 曲线又称流涡岛曲线属于六边形分形曲线家族。参数size单个 Gosper 岛的大小边长步长默认值为1。返回值Gosper 岛的点序列返回类型为扁平的Array.number坐标按[x, y, z, x, y, z, ...]的顺序排列每 3 个数值构成一个点且所有点的 z 坐标恒为0曲线完全落在 XY 平面。源码实现L-system 重写与海龟作图从 examples/jsm/utils/GeometryUtils.js 的实现看gosper由两个内部函数协作完成fractalize( config )按 L-systemLindenmayer 系统规则迭代重写字符串。初始公理axiom为A共执行 4 步迭代重写规则为rules: { A: ABFBF-FA--FAFA-BF, B: -FABFBFBFFA--FA-B }toPoints( config )采用海龟作图turtle graphics方式逐字符解释重写后的字符串字符表示逆时针旋转 60°Math.PI / 3字符-表示顺时针旋转 60°字符F表示沿当前方向前进size距离并记录新坐标点} else if ( char F ) { currX config.size * Math.cos( angle ); currY - config.size * Math.sin( angle ); path.push( currX, currY, 0 ); }因此size实际上控制的是每段F前进的步长值越大整条曲线在空间中的跨度越大迭代步数固定为 4 步决定了曲线的分形细节层级。实战直接构建 Line 几何体webgl_framebuffer_texture.html 给出了完整用法——用gosper的输出直接构造BufferGeometryconst points GeometryUtils.gosper( 8 ); const geometry new THREE.BufferGeometry(); const positionAttribute new THREE.Float32BufferAttribute( points, 3 ); geometry.setAttribute( position, positionAttribute ); geometry.center(); const material new THREE.LineBasicMaterial( { vertexColors: true } ); const line new THREE.Line( geometry, material ); line.scale.setScalar( 0.05 ); scene.add( line );注意gosper返回的是扁平number数组因此用new THREE.Float32BufferAttribute( points, 3 )直接指定每 3 个元素构成一个顶点即可无需再组装成Vector3数组。.hilbert2D( center : Vector3, size : number, iterations : number, v0, v1, v2, v3 ) : Array.生成沿二维 Hilbert 曲线的坐标点。Hilbert 曲线是一种空间填充曲线能将二维空间按细分网格顺序遍历常用于像素遍历、图像扫描与 LOD 排序等场景。参数参数含义默认值centerHilbert 曲线的中心点Vector3new Vector3( 0, 0, 0 )sizeHilbert 曲线的总宽度10iterations细分次数递归层数1官方文档写作 10源码实际默认值为 1见下方说明v0角索引 -X, -Z0v1角索引 -X, Z1v2角索引 X, Z2v3角索引 X, -Z3返回值Hilbert 曲线的Vector3点数组。所有点位于同一平面y保持为中心点的y值。关于 iterations 默认值的说明官方文档 module-GeometryUtils.html.md 中hilbert2D的iterations默认值写作10而当前仓库源码 examples/jsm/utils/GeometryUtils.js 中实际声明为iterations 1与hilbert3D保持一致。建议以源码实现为准不传iterations时只生成最基础的 4 个角点需要更高密度曲线时显式传入较大值如 35并注意点数量随4^iterations增长。源码实现四象限递归重排从 examples/jsm/utils/GeometryUtils.js 的实现可以看出hilbert2D将中心点周围按 -X/-Z、-X/Z、X/Z、X/-Z 顺序排列出 4 个角向量vec_s再按传入的v0..v3顺序重排为vec。当iterations递减后仍非负时对 4 个子象限递归调用每层把size减半并交换角索引组合if ( 0 -- iterations ) { return [ ...hilbert2D( vec[ 0 ], half, iterations, v0, v3, v2, v1 ), ...hilbert2D( vec[ 1 ], half, iterations, v0, v1, v2, v3 ), ...hilbert2D( vec[ 2 ], half, iterations, v0, v1, v2, v3 ), ...hilbert2D( vec[ 3 ], half, iterations, v2, v1, v0, v3 ) ]; } return vec;这一重排-递归-拼接结构正是 Hilbert 曲线保持空间连续性的核心相邻子曲线的连接处首尾相接整条曲线可以一笔画遍历整个区域。.hilbert3D( center : Vector3, size : number, iterations : number, v0...v7 ) : Array.生成沿三维 Hilbert 曲线的坐标点是hilbert2D的立体推广曲线在三维空间内逐格遍历。参数参数含义默认值centerHilbert 曲线的中心点Vector3new Vector3( 0, 0, 0 )sizeHilbert 曲线的总宽度10iterations细分次数递归层数1v0角索引 -X, Y, -Z0v1角索引 -X, Y, Z1v2角索引 -X, -Y, Z2v3角索引 -X, -Y, -Z3v4角索引 X, -Y, -Z4v5角索引 X, -Y, Z5v6角索引 X, Y, Z6v7角索引 X, Y, -Z7返回值Hilbert 曲线的Vector3点数组。八个角索引的坐标方向见 examples/jsm/utils/GeometryUtils.js先以center为中心按 ±X、±Y、±Z 构造正方体 8 个顶点vec_s再按v0..v7顺序重排。源码实现八象限递归重排与二维版本类似hilbert3D 在递归时对 8 个子立方体分别传入不同的角索引组合if ( -- iterations 0 ) { return [ ...hilbert3D( vec[ 0 ], half, iterations, v0, v3, v4, v7, v6, v5, v2, v1 ), ...hilbert3D( vec[ 1 ], half, iterations, v0, v7, v6, v1, v2, v5, v4, v3 ), // ... 其余 6 个子立方体 ]; } return vec;点数量随8^iterations增长因此迭代次数不宜过大官方示例普遍使用iterations 1生成 8 个顶点或recursion 1配合样条插值获得平滑路径。实战三维 Hilbert 曲线 虚线渲染webgl_lines_dashed.html 展示了完整的三维曲线构建流程先由hilbert3D生成控制点再用CatmullRomCurve3做样条细分最后以LineDashedMaterial渲染虚线const subdivisions 6; const recursion 1; const points GeometryUtils.hilbert3D( new THREE.Vector3( 0, 0, 0 ), 25.0, recursion, 0, 1, 2, 3, 4, 5, 6, 7 ); const spline new THREE.CatmullRomCurve3( points ); const samples spline.getPoints( points.length * subdivisions ); const geometrySpline new THREE.BufferGeometry().setFromPoints( samples ); const line new THREE.Line( geometrySpline, new THREE.LineDashedMaterial( { color: 0xffffff, dashSize: 1, gapSize: 0.5 } ) ); line.computeLineDistances(); scene.add( line );同样的hilbert3D调用模式也出现在 webgl_lines_colors.html、webgl_lines_fat.html、webgpu_lines_fat.html 与 webgpu_instance_points.html 中可见它是构建三维空间填充路径的标准入口。在这些示例中iterations均为1仅通过修改size20200控制曲线在场景中的整体跨度。常见问题与注意事项返回类型不一致gosper返回扁平number数组需配合Float32BufferAttribute( points, 3 )使用hilbert2D/hilbert3D返回Vector3数组可直接传给CatmullRomCurve3、setFromPoints或Line。迭代次数与顶点规模二维曲线点数为4^iterations三维曲线点数为8^iterations指数增长非常快。官方示例默认只用1次迭代若要增加细节建议配合样条细分如CatmullRomCurve3.getPoints而非盲目提高迭代次数。v0..v7的作用这些参数用于指定遍历立方体/正方形顶点的顺序默认按坐标顺序排布修改它们会改变曲线走向与旋转方向可用于对齐到特定坐标轴习惯。模块为 addon使用前必须显式 import见 导入方式核心包three不会自动包含该模块。延伸阅读源码examples/jsm/utils/GeometryUtils.js官方文档docs/pages/module-GeometryUtils.html.md二维/三维 Hilbert 曲线的原始实现思路分别参考 openprocessing.org 上 sketch 15493 与 user 5654 的作品Gosper 曲线参考 nitaku 的 gist上述来源已在源码 JSDoc 中标注相关示例webgl_lines_dashed.html、webgl_lines_fat.html、webgl_framebuffer_texture.html、webgpu_instance_points.html【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考