如何检查起点坐标与当前焦点坐标间的区域是否包含指定坐标项
TypeScript 坐标命中检测函数实现
核心逻辑说明
只需要对待检测数组里的每个坐标做两层判断即可:
- 先锁定起点到焦点的矩形范围,再叠加上hitSlop的容差,初步筛选出落在这个扩大矩形里的坐标
- 可选优化:如果需要更精准的线段命中(而不是矩形命中),可以额外计算待检测点到起点-焦点连线的垂直距离,距离小于等于hitSlop即符合要求
完整代码
type Coordinate = {x: number; y: number}; export const getHorizontalIntermediate = ( anchorCoordinate: Coordinate, // 起点 focusCoordinate: Coordinate, // 当前焦点 dimension: number, screenCoordinates: Coordinate[], // 待检测坐标数组 hitSlop = 25, ): Coordinate[] => { // 1. 先计算起点和焦点的x、y边界 const minX = Math.min(anchorCoordinate.x, focusCoordinate.x); const maxX = Math.max(anchorCoordinate.x, focusCoordinate.x); const minY = Math.min(anchorCoordinate.y, focusCoordinate.y); const maxY = Math.max(anchorCoordinate.y, focusCoordinate.y); // 2. 叠加上容差得到最终的判断范围 const validXRange = [minX - hitSlop, maxX + hitSlop]; const validYRange = [minY - hitSlop, maxY + hitSlop]; // 3. 过滤符合要求的坐标 const matchedCoordinates = screenCoordinates.filter(point => { // 基础矩形命中判断 const isXInRange = point.x >= validXRange[0] && point.x <= validXRange[1]; const isYInRange = point.y >= validYRange[0] && point.y <= validYRange[1]; if (!isXInRange || !isYInRange) return false; // 以下是可选的精准线段命中判断,不需要可以直接删掉 // 计算线段的向量 const lineVecX = focusCoordinate.x - anchorCoordinate.x; const lineVecY = focusCoordinate.y - anchorCoordinate.y; // 计算起点到待检测点的向量 const pointVecX = point.x - anchorCoordinate.x; const pointVecY = point.y - anchorCoordinate.y; // 计算点积,判断点是否在线段的前后范围外 const dot = pointVecX * lineVecX + pointVecY * lineVecY; if (dot < 0) return false; // 计算线段长度平方 const lineLengthSq = lineVecX * lineVecX + lineVecY * lineVecY; if (dot > lineLengthSq) return false; // 计算点到线段的距离 const cross = pointVecX * lineVecY - pointVecY * lineVecX; const distance = Math.abs(cross) / Math.sqrt(lineLengthSq); return distance <= hitSlop; // 如果dimension参数需要用到,比如判断元素是否完全/部分落在范围内,可以在这里补充逻辑 // 比如水平场景下dimension是元素宽度的话,可以额外判断 point.x + dimension/2 >= validXRange[0] && point.x - dimension/2 <= validXRange[1] }) return matchedCoordinates; };
内容的提问来源于stack exchange,提问作者gpbaculio
相关产品推荐
相关产品推荐

