( points: XYPoint[], index: number, out: XYPoint = _defaultNormal, )
| 269 | * @returns unit normal |
| 270 | */ |
| 271 | export function computeVertexNormal( |
| 272 | points: XYPoint[], |
| 273 | index: number, |
| 274 | out: XYPoint = _defaultNormal, |
| 275 | ): XYPoint { |
| 276 | let nx = 0; |
| 277 | let ny = 0; |
| 278 | const last = points.length - 1; |
| 279 | const p = points[index]; |
| 280 | |
| 281 | if (index < last) { |
| 282 | const dx = points[index + 1].x - p.x; |
| 283 | const dy = points[index + 1].y - p.y; |
| 284 | const len = Math.sqrt(dx * dx + dy * dy); |
| 285 | if (len > 0) { |
| 286 | const invLen = 1 / len; |
| 287 | nx -= dy * invLen; |
| 288 | ny += dx * invLen; |
| 289 | } |
| 290 | } |
| 291 | if (index > 0) { |
| 292 | const dx = p.x - points[index - 1].x; |
| 293 | const dy = p.y - points[index - 1].y; |
| 294 | const len = Math.sqrt(dx * dx + dy * dy); |
| 295 | if (len > 0) { |
| 296 | const invLen = 1 / len; |
| 297 | nx -= dy * invLen; |
| 298 | ny += dx * invLen; |
| 299 | } |
| 300 | } |
| 301 | |
| 302 | const nlen = Math.sqrt(nx * nx + ny * ny); |
| 303 | if (nlen > 0) { |
| 304 | const invNlen = 1 / nlen; |
| 305 | nx *= invNlen; |
| 306 | ny *= invNlen; |
| 307 | } else { |
| 308 | nx = 0; |
| 309 | ny = 1; |
| 310 | } |
| 311 | |
| 312 | out.x = nx; |
| 313 | out.y = ny; |
| 314 | return out; |
| 315 | } |
| 316 | |
| 317 | /** |
| 318 | * 2D cross product of vectors (p1-p0) and (p2-p0). |
no outgoing calls
no test coverage detected