Source code for rofunc.utils.visualab.ellipsoid

# Copyright 2023, Junjia LIU, jjliu@mae.cuhk.edu.hk
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import matplotlib.colors as colors
import matplotlib.pyplot as plt
import nestle
import numpy as np
from matplotlib import cm
from numpy import linalg

import rofunc as rf


[docs]def sphere_plot3d(mean, cov, color=[1, 0, 0], alpha=0.2, ax=None): """ Plot 3D sphere or ellipsoid Example:: >>> import rofunc as rf >>> import numpy as np >>> from matplotlib import pyplot as plt >>> means = np.array([0.5, 0.0, 0.0]) >>> covs = np.diag([6, 12, 0.1]) >>> rf.visualab.sphere_plot3d(means, covs) >>> plt.show() :param mean: the mean point coordinate of sphere :param cov: the covariance matrix of the sphere :param color: the color of the ellipsoid :param alpha: the transparency of the ellipsoid :param ax: the axis to plot the ellipsoid """ # ell_gen = nestle.Ellipsoid(mean, np.dot(cov.T, cov)) ell_gen = nestle.Ellipsoid(mean, np.linalg.inv(cov)) npoints = 100 points = ell_gen.samples(npoints) pointvol = ell_gen.vol / npoints # Find bounding ellipsoid(s) ells = nestle.bounding_ellipsoids(points, pointvol) # plot if ax is None: fig = plt.figure(figsize=(10., 10.)) ax = fig.add_subplot(111, projection='3d') for ell in ells: plot_ellipsoid_3d(ell, ax, color, alpha)
[docs]def plot_ellipsoid_3d(ell, ax, color, alpha): """ Plot the 3-d Ellipsoid ell on the Axes3D ax. :param ell: the ellipsoid to plot :param ax: the axis to plot the ellipsoid :param color: the color of the ellipsoid :param alpha: the transparency of the ellipsoid """ # points on unit sphere u = np.linspace(0.0, 2.0 * np.pi, 100) v = np.linspace(0.0, np.pi, 100) z = np.outer(np.cos(u), np.sin(v)) y = np.outer(np.sin(u), np.sin(v)) x = np.outer(np.ones_like(u), np.cos(v)) # transform points to ellipsoid for i in range(len(x)): for j in range(len(x)): x[i, j], y[i, j], z[i, j] = ell.ctr + np.dot(ell.axes, [x[i, j], y[i, j], z[i, j]]) ax.plot_surface(x, y, z, rstride=4, cstride=4, color=color, alpha=alpha)
[docs]def ellipsoid_plot3d(ellipsoids, mode='quaternion', Rs=None): """ Plot the ellipsoids in 3d, used by `rf.robolab.manipulability.mpb.get_mpb_from_model` :param ellipsoids: list of ellipsoids to plot :param mode: 'quaternion' or 'euler' or 'given' :param Rs: rotation matrices :return: None """ if mode == 'given': assert Rs is not None, "Rotation matrices are not given" fig = plt.figure(figsize=(8, 8)) ax = fig.add_subplot(111, projection='3d') # set colour map so each ellipsoid as a unique colour n_ellip = len(ellipsoids) norm = colors.Normalize(vmin=0, vmax=n_ellip) cmap = cm.jet m = cm.ScalarMappable(norm=norm, cmap=cmap) # compute each and plot each ellipsoid iteratively for index in range(n_ellip): # your ellipsoid and center in matrix form if mode in ['quaternion', 'euler']: center = ellipsoids[index, :3] if mode == 'quaternion': R = rf.robolab.coord.homo_matrix_from_quaternion(ellipsoids[index, 3:7]) elif mode == 'euler': R = rf.robolab.coord.homo_matrix_from_euler(ellipsoids[index, 3], ellipsoids[index, 4], ellipsoids[index, 5], 'sxyz') # find the rotation matrix and radii of the axes U, s, rotation = linalg.svd(R) radii = 1.0 / np.sqrt(s) * 0.3 # reduce radii by factor 0.3 # calculate cartesian coordinates for the ellipsoid surface u = np.linspace(0.0, 2.0 * np.pi, 60) v = np.linspace(0.0, np.pi, 60) x = radii[0] * np.outer(np.cos(u), np.sin(v)) y = radii[1] * np.outer(np.sin(u), np.sin(v)) z = radii[2] * np.outer(np.ones_like(u), np.cos(v)) elif mode == 'given': center = np.zeros(3) rotation = Rs[index] radii = ellipsoids[index] # calculate cartesian coordinates for the ellipsoid surface u = np.linspace(0.0, 2.0 * np.pi, 60) v = np.linspace(0.0, np.pi, 60) x = radii[0] * np.outer(np.cos(u), np.sin(v)) y = radii[1] * np.outer(np.sin(u), np.sin(v)) z = radii[2] * np.outer(np.ones_like(u), np.cos(v)) else: raise ValueError("Unknown mode") for i in range(len(x)): for j in range(len(x)): [x[i, j], y[i, j], z[i, j]] = np.dot([x[i, j], y[i, j], z[i, j]], rotation) + center ax.plot_surface(x, y, z, rstride=3, cstride=3, color=m.to_rgba(index), linewidth=0.1, alpha=0.2, shade=True) # rf.visualab.set_axis(ax) plt.show()