* Find the nearest edge to (worldX, worldY) within maxDistance. * Uses point-to-segment (or point-to-quadratic-curve) distance testing.
(worldX: number, worldY: number, maxDistance = 8)
| 2163 | * Uses point-to-segment (or point-to-quadratic-curve) distance testing. |
| 2164 | */ |
| 2165 | findEdgeAt(worldX: number, worldY: number, maxDistance = 8): PixiEdge | null { |
| 2166 | if (this.edges.length === 0) return null; |
| 2167 | |
| 2168 | let bestEdge: PixiEdge | null = null; |
| 2169 | let bestDist = maxDistance; |
| 2170 | |
| 2171 | for (let i = 0; i < this.edges.length; i++) { |
| 2172 | const e = this.edges[i]; |
| 2173 | if (this.hiddenLinkTypes.has(e.label)) continue; |
| 2174 | const s = this.nodes.get(e.sourceId); |
| 2175 | const t = this.nodes.get(e.targetId); |
| 2176 | if (!s?.visible || !t?.visible) continue; |
| 2177 | |
| 2178 | const sx = this.mode3d ? s.sprite.position.x : s.x; |
| 2179 | const sy = this.mode3d ? s.sprite.position.y : s.y; |
| 2180 | const tx = this.mode3d ? t.sprite.position.x : t.x; |
| 2181 | const ty = this.mode3d ? t.sprite.position.y : t.y; |
| 2182 | |
| 2183 | // Early bounding-box pruning |
| 2184 | const dx = tx - sx; |
| 2185 | const dy = ty - sy; |
| 2186 | const lenSq = dx * dx + dy * dy; |
| 2187 | const isCurve = this.bp.edgeStyle === 'curve'; |
| 2188 | const padding = |
| 2189 | maxDistance + (isCurve ? Math.sqrt(lenSq) * this.curvature : 0); |
| 2190 | |
| 2191 | if ( |
| 2192 | worldX < Math.min(sx, tx) - padding || |
| 2193 | worldX > Math.max(sx, tx) + padding || |
| 2194 | worldY < Math.min(sy, ty) - padding || |
| 2195 | worldY > Math.max(sy, ty) + padding |
| 2196 | ) { |
| 2197 | continue; |
| 2198 | } |
| 2199 | |
| 2200 | let dist: number; |
| 2201 | if (isCurve) { |
| 2202 | dist = pointToQuadraticDist( |
| 2203 | worldX, |
| 2204 | worldY, |
| 2205 | sx, |
| 2206 | sy, |
| 2207 | tx, |
| 2208 | ty, |
| 2209 | this.curvature, |
| 2210 | ); |
| 2211 | } else { |
| 2212 | dist = pointToSegmentDist(worldX, worldY, sx, sy, tx, ty); |
| 2213 | } |
| 2214 | |
| 2215 | if (dist < bestDist) { |
| 2216 | bestDist = dist; |
| 2217 | bestEdge = e; |
| 2218 | } |
| 2219 | } |
| 2220 | |
| 2221 | return bestEdge; |
| 2222 | } |
no test coverage detected