Given the 2D view coordinates, find the point on the nearest axis pane that lies directly below those coordinates. Returns a 3D point in data coordinates.
(self, xv, yv, renderer=None)
| 1682 | return eye |
| 1683 | |
| 1684 | def _calc_coord(self, xv, yv, renderer=None): |
| 1685 | """ |
| 1686 | Given the 2D view coordinates, find the point on the nearest axis pane |
| 1687 | that lies directly below those coordinates. Returns a 3D point in data |
| 1688 | coordinates. |
| 1689 | """ |
| 1690 | if self._focal_length == np.inf: # orthographic projection |
| 1691 | zv = 1 |
| 1692 | else: # perspective projection |
| 1693 | zv = -1 / self._focal_length |
| 1694 | |
| 1695 | p1 = np.array(proj3d.inv_transform(xv, yv, zv, self.invM)).ravel() |
| 1696 | |
| 1697 | # Get the vector from the camera to the point on the view plane |
| 1698 | vec = self._get_camera_loc() - p1 |
| 1699 | |
| 1700 | # Get the pane locations for each of the axes |
| 1701 | pane_locs_data = [axis.active_pane()[1] for axis in self._axis_map.values()] |
| 1702 | |
| 1703 | # Find the distance to the nearest pane by projecting the view vector |
| 1704 | scales = np.zeros(3) |
| 1705 | for i in range(3): |
| 1706 | if vec[i] == 0: |
| 1707 | scales[i] = np.inf |
| 1708 | else: |
| 1709 | scales[i] = (pane_locs_data[i] - p1[i]) / vec[i] |
| 1710 | pane_idx = np.argmin(abs(scales)) |
| 1711 | scale = scales[pane_idx] |
| 1712 | |
| 1713 | # Calculate the point on the closest pane |
| 1714 | p2 = p1 + scale * vec |
| 1715 | |
| 1716 | # Convert from transformed to data coordinates |
| 1717 | p2 = np.array(self._untransform_point(p2[0], p2[1], p2[2])) |
| 1718 | return p2, pane_idx |
| 1719 | |
| 1720 | def _arcball(self, x: float, y: float) -> np.ndarray: |
| 1721 | """ |