Create the projection matrix from the current viewing position.
(self)
| 1427 | self.set_zlim3d(zmin, zmax, auto=None) |
| 1428 | |
| 1429 | def get_proj(self): |
| 1430 | """Create the projection matrix from the current viewing position.""" |
| 1431 | |
| 1432 | # Transform to uniform world coordinates 0-1, 0-1, 0-1 |
| 1433 | box_aspect = self._roll_to_vertical(self._box_aspect) |
| 1434 | # For non-linear scales, we use the scaled limits so the world |
| 1435 | # transformation maps transformed coordinates (not data coordinates) |
| 1436 | # to the unit cube |
| 1437 | scaled_limits = self._get_scaled_limits() |
| 1438 | worldM = proj3d.world_transformation(*scaled_limits, pb_aspect=box_aspect) |
| 1439 | |
| 1440 | # Look into the middle of the world coordinates: |
| 1441 | R = 0.5 * box_aspect |
| 1442 | |
| 1443 | # elev: elevation angle in the z plane. |
| 1444 | # azim: azimuth angle in the xy plane. |
| 1445 | # Coordinates for a point that rotates around the box of data. |
| 1446 | # p0, p1 corresponds to rotating the box only around the vertical axis. |
| 1447 | # p2 corresponds to rotating the box only around the horizontal axis. |
| 1448 | elev_rad = np.deg2rad(self.elev) |
| 1449 | azim_rad = np.deg2rad(self.azim) |
| 1450 | p0 = np.cos(elev_rad) * np.cos(azim_rad) |
| 1451 | p1 = np.cos(elev_rad) * np.sin(azim_rad) |
| 1452 | p2 = np.sin(elev_rad) |
| 1453 | |
| 1454 | # When changing vertical axis the coordinates changes as well. |
| 1455 | # Roll the values to get the same behaviour as the default: |
| 1456 | ps = self._roll_to_vertical([p0, p1, p2]) |
| 1457 | |
| 1458 | # The coordinates for the eye viewing point. The eye is looking |
| 1459 | # towards the middle of the box of data from a distance: |
| 1460 | eye = R + self._dist * ps |
| 1461 | |
| 1462 | # Calculate the viewing axes for the eye position |
| 1463 | u, v, w = self._calc_view_axes(eye) |
| 1464 | self._view_u = u # _view_u is towards the right of the screen |
| 1465 | self._view_v = v # _view_v is towards the top of the screen |
| 1466 | self._view_w = w # _view_w is out of the screen |
| 1467 | |
| 1468 | # Generate the view and projection transformation matrices |
| 1469 | if self._focal_length == np.inf: |
| 1470 | # Orthographic projection |
| 1471 | viewM = proj3d._view_transformation_uvw(u, v, w, eye) |
| 1472 | projM = proj3d._ortho_transformation(-self._dist, self._dist) |
| 1473 | else: |
| 1474 | # Perspective projection |
| 1475 | # Scale the eye dist to compensate for the focal length zoom effect |
| 1476 | eye_focal = R + self._dist * ps * self._focal_length |
| 1477 | viewM = proj3d._view_transformation_uvw(u, v, w, eye_focal) |
| 1478 | projM = proj3d._persp_transformation(-self._dist, |
| 1479 | self._dist, |
| 1480 | self._focal_length) |
| 1481 | |
| 1482 | # Combine all the transformation matrices to get the final projection |
| 1483 | M0 = np.dot(viewM, worldM) |
| 1484 | M = np.dot(projM, M0) |
| 1485 | return M |
| 1486 |