Convert a point (x, y) to a point on a virtual trackball. This is Ken Shoemake's arcball (a sphere), modified to soften the abrupt edge (optionally). See: Ken Shoemake, "ARCBALL: A user interface for specifying three-dimensional rotation using a mouse." in
(self, x: float, y: float)
| 1718 | return p2, pane_idx |
| 1719 | |
| 1720 | def _arcball(self, x: float, y: float) -> np.ndarray: |
| 1721 | """ |
| 1722 | Convert a point (x, y) to a point on a virtual trackball. |
| 1723 | |
| 1724 | This is Ken Shoemake's arcball (a sphere), modified |
| 1725 | to soften the abrupt edge (optionally). |
| 1726 | See: Ken Shoemake, "ARCBALL: A user interface for specifying |
| 1727 | three-dimensional rotation using a mouse." in |
| 1728 | Proceedings of Graphics Interface '92, 1992, pp. 151-156, |
| 1729 | https://doi.org/10.20380/GI1992.18 |
| 1730 | The smoothing of the edge is inspired by Gavin Bell's arcball |
| 1731 | (a sphere combined with a hyperbola), but here, the sphere |
| 1732 | is combined with a section of a cylinder, so it has finite support. |
| 1733 | """ |
| 1734 | s = mpl.rcParams['axes3d.trackballsize'] / 2 |
| 1735 | b = mpl.rcParams['axes3d.trackballborder'] / s |
| 1736 | x /= s |
| 1737 | y /= s |
| 1738 | r2 = x*x + y*y |
| 1739 | r = np.sqrt(r2) |
| 1740 | ra = 1 + b |
| 1741 | a = b * (1 + b/2) |
| 1742 | ri = 2/(ra + 1/ra) |
| 1743 | if r < ri: |
| 1744 | p = np.array([np.sqrt(1 - r2), x, y]) |
| 1745 | elif r < ra: |
| 1746 | dr = ra - r |
| 1747 | p = np.array([a - np.sqrt((a + dr) * (a - dr)), x, y]) |
| 1748 | p /= np.linalg.norm(p) |
| 1749 | else: |
| 1750 | p = np.array([0, x/r, y/r]) |
| 1751 | return p |
| 1752 | |
| 1753 | def _on_move(self, event): |
| 1754 | """ |