Parameters ---------- xys : (N, 2) array-like Coordinates of vertices. p : (float, float) Coordinates of point. Returns ------- d2min : float Minimum square distance of *p* to *xys*. proj : (float, float) Projection of *p* onto *xys*.
(xys, p)
| 531 | |
| 532 | |
| 533 | def _find_closest_point_on_path(xys, p): |
| 534 | """ |
| 535 | Parameters |
| 536 | ---------- |
| 537 | xys : (N, 2) array-like |
| 538 | Coordinates of vertices. |
| 539 | p : (float, float) |
| 540 | Coordinates of point. |
| 541 | |
| 542 | Returns |
| 543 | ------- |
| 544 | d2min : float |
| 545 | Minimum square distance of *p* to *xys*. |
| 546 | proj : (float, float) |
| 547 | Projection of *p* onto *xys*. |
| 548 | imin : (int, int) |
| 549 | Consecutive indices of vertices of segment in *xys* where *proj* is. |
| 550 | Segments are considered as including their end-points; i.e. if the |
| 551 | closest point on the path is a node in *xys* with index *i*, this |
| 552 | returns ``(i-1, i)``. For the special case where *xys* is a single |
| 553 | point, this returns ``(0, 0)``. |
| 554 | """ |
| 555 | if len(xys) == 1: |
| 556 | return (((p - xys[0]) ** 2).sum(), xys[0], (0, 0)) |
| 557 | dxys = xys[1:] - xys[:-1] # Individual segment vectors. |
| 558 | norms = (dxys ** 2).sum(axis=1) |
| 559 | norms[norms == 0] = 1 # For zero-length segment, replace 0/0 by 0/1. |
| 560 | rel_projs = np.clip( # Project onto each segment in relative 0-1 coords. |
| 561 | ((p - xys[:-1]) * dxys).sum(axis=1) / norms, |
| 562 | 0, 1)[:, None] |
| 563 | projs = xys[:-1] + rel_projs * dxys # Projs. onto each segment, in (x, y). |
| 564 | d2s = ((projs - p) ** 2).sum(axis=1) # Squared distances. |
| 565 | imin = np.argmin(d2s) |
| 566 | return (d2s[imin], projs[imin], (imin, imin+1)) |
| 567 | |
| 568 | |
| 569 | _docstring.interpd.register(contour_set_attributes=r""" |
no test coverage detected
searching dependent graphs…