Appearance
线段等分 bisectionLine
把一条三维空间线段按指定段数等分,返回
segments + 1个均匀插值点。对齐源案例Analysis/BisectionLine:源实现用 EntityDraw 拾取两点 + 图钉图片标注,本 SDK 以纯函数bisectionLine(Cartesian3.lerp均匀插值)为核心,用点 / 线实体等价再现等分语义。
能力定位
bisectionLine 适合:
- 空间线段等分:把两点间的直线段等分 N 段,得到 N+1 个均匀分布的点(GIS 常见几何能力);
- 均匀布点:沿线均匀布置管线桩号、路径节点、轨迹采样点等,只需给起点 / 终点 / 段数;
- 纯计算复用:无 Viewer 依赖,可在 Node 环境直接验证,结果数组可直接喂给 Entity / Primitive 消费方。
与其他工具的区分:
| 工具 | 作用面 | 行为 |
|---|---|---|
| bisectionLine(本工具) | 纯几何计算 | 线段等分返回等距插值点,不接触 Viewer |
| BufferAnalysis | turf 计算 + 实体 | 点 / 线 / 面缓冲范围分析,生成缓冲面 |
| Measure | 测距 / 测面 | 测量量算,不生成等分点 |
纯函数
ts
bisectionLine(
start: Cartesian3, // 线段起点(世界坐标)
end: Cartesian3, // 线段终点(世界坐标)
segments: number // 等分段数,正整数(>= 1)
): Cartesian3[] // segments + 1 个等分点| 参数 | 类型 | 描述 |
|---|---|---|
start | Cartesian3 | 线段起点,Cartesian3.fromDegrees 构造 |
end | Cartesian3 | 线段终点,世界坐标 |
segments | number | 等分段数;1 段返回 [start, end] 两点,10 段返回 11 点 |
- 返回:
segments + 1个等分点,首点为start、末点为end,相邻点间欧氏距离相等; - 入参不被修改,返回数组元素为新对象,可安全用于 Entity 等消费方;
segments为0/ 负数 / 非整数 /NaN时抛错。
基础示例
ts
import { bisectionLine } from '@nexa/gis-cesium'
import { Cartesian3 } from 'cesium'
// 把 贵阳→成都 线段等分 10 段 → 11 个等分点
const start = Cartesian3.fromDegrees(106.63, 26.65, 0)
const end = Cartesian3.fromDegrees(104.06, 30.66, 0)
const points = bisectionLine(start, end, 10)
// points.length === 11
// Cartesian3.equalsEpsilon(points[0], start, 1e-9) === true
// Cartesian3.equalsEpsilon(points[10], end, 1e-9) === true进阶示例
配合 Cesium 实体展示等分结果:橙色源线段 + 绿起点 / 红终点 + 蓝色等分点(关闭深度测试避免被地表遮挡):
ts
const points = bisectionLine(start, end, 20)
// 源线段(橙)
viewer.entities.add({
polyline: { positions: [start, end], width: 3, material: Cesium.Color.ORANGE },
})
// 起点 / 终点
viewer.entities.add({ position: start, point: { pixelSize: 12, color: Cesium.Color.LIME, disableDepthTestDistance: Number.POSITIVE_INFINITY } })
viewer.entities.add({ position: end, point: { pixelSize: 12, color: Cesium.Color.RED, disableDepthTestDistance: Number.POSITIVE_INFINITY } })
// 等分点
points.forEach((p) => {
viewer.entities.add({
position: p,
point: { pixelSize: 7, color: Cesium.Color.SKYBLUE, disableDepthTestDistance: Number.POSITIVE_INFINITY },
})
})交互拾取起 / 终点后自动重新等分:
ts
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
handler.setInputAction((e) => {
const picked = viewer.scene.pickPosition(e.position) ||
viewer.scene.camera.pickEllipsoid(e.position, viewer.scene.globe.ellipsoid)
if (!picked) return
// 用 picked 替换 start / end 后重新调用 bisectionLine 即可
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)实现说明
- 算法:
count = segments + 1,第i点插值系数offset = i / (count - 1),result[i] = Cartesian3.lerp(start, end, offset)——相邻点欧氏距离必然相等; - 纯函数无副作用:入参
start/end不被修改(lerp写入独立new Cartesian3()),结果数组为全新对象,可直接消费; - 输入校验:
segments必须为正整数,非法值抛错,避免0段导致除零 / 数组异常; - 高度语义:对同经纬度垂直段,高度随插值系数线性变化;对不同经纬度的斜线,ECEF 笛卡尔插值的高度并非线性(由地球曲率决定),如需精确的高度等分应分别对经纬度与高度插值。
验证
- 单元测试
LineUtils.spec.ts(7 例):1 段返回 2 点、N 段返回 N+1 点、相邻距离相等、共线(尺度无关sinθ判定)、入参不可变、同经纬度垂直段高度线性、非法参数抛错; - 浏览器验证:示例外壳
?id=bisectionLine顶视俯瞰渲染线段 + 21 个等分点,拾取起 / 终点自动重算。
Cesium 版本限制
- 仅依赖 Cesium 公开 API:
Cartesian3.lerp、Cartesian3.fromDegrees; - 无私有字段 / GLSL 依赖;已验证目标版本:Cesium 1.133.1。