You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
GCSGUI/src/utils/map/geocomputation.ts

89 lines
3.2 KiB
TypeScript

/*
* @Author: cbwu 504-wuchengbo@htsdfp.com
* @Date: 2024-03-22 15:42:49
* @LastEditors: cbwu
* @LastEditTime: 2024-04-01 14:05:43
* @Description:
*/
import { Cartesian3, Math as Cesium_Math } from 'cesium'
/**
* 线
* @param lineStart 线[longitude1, latitude1, height1]
* @param lineEnd 线:[longitude2, latitude2, height2]
* @param point :[[longitude3, latitude3, height3]]
* @returns
*/
function getClosestPoint(
lineStart: Cartesian3,
lineEnd: Cartesian3,
point: Cartesian3,
): Cartesian3 {
// 计算直线方向向量
const lineDirection = new Cartesian3()
Cartesian3.subtract(lineEnd, lineStart, lineDirection)
Cartesian3.normalize(lineDirection, lineDirection)
// 计算点到直线起点的向量
const pointToStart = new Cartesian3()
Cartesian3.subtract(point, lineStart, pointToStart)
// 计算投影长度,即点到直线的向量在直线方向向量上的分量长度
const projectionLength = Cartesian3.dot(pointToStart, lineDirection)
// 使用标量乘法和向量加法确定交点
const closestPoint = new Cartesian3()
Cartesian3.multiplyByScalar(lineDirection, projectionLength, closestPoint)
Cartesian3.add(lineStart, closestPoint, closestPoint)
return closestPoint
}
/**
* 线
* @param lineStart 线[longitude1, latitude1, height1]
* @param lineEnd 线[longitude2, latitude2, height2]
* @param pointToCheck 线[longitude3, latitude3, height3]
* @param tolerance
* @returns 线
*/
function isOnLineSegment(
lineStart: Cartesian3,
lineEnd: Cartesian3,
pointToCheck: Cartesian3,
tolerance: number = Cesium_Math.EPSILON1,
): boolean {
const dist_AP = Cartesian3.distance(lineStart, pointToCheck)
const dist_BP = Cartesian3.distance(lineEnd, pointToCheck)
const dist_AB = Cartesian3.distance(lineStart, lineEnd)
const isCollinear = Math.abs(dist_AP + dist_BP - dist_AB) < tolerance
return isCollinear
/*
const startToEnd = new Cartesian3()
const startToPoint = new Cartesian3()
const endToPoint = new Cartesian3()
// 计算向量
Cartesian3.subtract(lineEnd, lineStart, startToEnd)
Cartesian3.subtract(pointToCheck, lineStart, startToPoint)
Cartesian3.subtract(pointToCheck, lineEnd, endToPoint)
// 判断共线
const cross = Cartesian3.cross(startToEnd, startToPoint, new Cartesian3())
console.log('cross:' + Cartesian3.magnitude(cross).toString())
// Math.EPSILON6 是一个非常小的值,用来防止浮点数计算的误差
const isCollinear = Cartesian3.magnitude(cross) < tolerance
// 判断点是否在线段之间
let isBetween = false
if (isCollinear) {
const dotProduct1 = Cartesian3.dot(startToEnd, startToPoint)
const dotProduct2 = Cartesian3.dot(startToEnd, endToPoint)
isBetween = dotProduct1 >= 0 && dotProduct2 <= 0
}
return isBetween
*/
}
export { getClosestPoint, isOnLineSegment }