Issue
I have three orthonormal vectors
(-0.460021, -0.241295, -0.854493),
(-0.641846, 0.755344, 0.132244),
(-0.613526, -0.609288, 0.502348)
and a magntitude value along each of these direction 1.44, 3.45
and 2.02
.
How can I plot an ellipsoid (3D surface) representing the axis directions along the orthonormal vectors and the axis lengths given by their magnitude ?
Solution
If I understand your question correctly, you want to create an ellipsoid and rotate it so that its major axis are aligned with the orthonormal vectors.
Note: since Matplotlib's 3D capability are rather limited, I'm going to use Plotly: it will make our life a lot easier since it provides an "equal" aspect ratio for 3D plots. You can easily change the plotting library to Matplotlib.
The parametric equations for an ellipsoid can be found here.
import numpy as np
import matplotlib.pyplot as plt
import plotly.graph_objects as go
# compute ellipsoid coordinates on standard basis
# e1=(1, 0, 0), e2=(0, 1, 0), e3=(0, 0, 1)
a, b, c = 1.44, 3.45, 2.02
u, v = np.mgrid[0:2*np.pi:40j, 0:np.pi:20j]
x1 = a * np.cos(u) * np.sin(v)
y1 = b * np.sin(u) * np.sin(v)
z1 = c * np.cos(v)
# points on the ellipsoid
points = np.stack([t.flatten() for t in [x1, y1, z1]])
v1 = np.array([-0.460021, -0.241295, -0.854493])
v2 = np.array([-0.641846, 0.755344, 0.132244])
v3 = np.array([-0.613526, -0.609288, 0.502348])
# 3x3 transformation matrix
T = np.array([v1, v2, v3]).T
# transform coordinates to the new orthonormal basis
new_points = T @ points
x2 = new_points[0, :]
y2 = new_points[1, :]
z2 = new_points[2, :]
x2, y2, z2 = [t.reshape(x1.shape) for t in [x2, y2, z2]]
# scale vector for better visualization
scale = 5
v1, v2, v3 = [scale * t for t in [v1, v2, v3]]
fig = go.Figure([
# axis on the standard base
go.Scatter3d(x=[0, 5], y=[0, 0], z=[0, 0], mode="lines", name="x1", line=dict(width=5, color="red")),
go.Scatter3d(x=[0, 0], y=[0, 5], z=[0, 0], mode="lines", name="y1", line=dict(width=5, color="green")),
go.Scatter3d(x=[0, 0], y=[0, 0], z=[0, 5], mode="lines", name="z1", line=dict(width=5, color="blue")),
# axis on the new orthonormal base
go.Scatter3d(x=[0, v1[0]], y=[0, v1[1]], z=[0, v1[2]], mode="lines", name="x2", line=dict(width=2, color="red")),
go.Scatter3d(x=[0, v2[0]], y=[0, v2[1]], z=[0, v2[2]], mode="lines", name="y2", line=dict(width=2, color="green")),
go.Scatter3d(x=[0, v3[0]], y=[0, v3[1]], z=[0, v3[2]], mode="lines", name="z2", line=dict(width=2, color="blue")),
# original ellipsoid aligned to the standard base
go.Surface(x=x1, y=y1, z=z1, opacity=0.35, colorscale="plotly3", surfacecolor=y1, cmin=y1.min(), cmax=y1.max(), colorbar=dict(len=0.6, yanchor="bottom", y=0)),
# final ellipsoid aligned to the new orthonormal base
go.Surface(x=x2, y=y2, z=z2, opacity=1, colorscale="aggrnyl", surfacecolor=y1, cmin=y1.min(), cmax=y1.max(), colorbar=dict(len=0.6, yanchor="bottom", y=0, x=0.95))
])
fig.update_layout({"scene": {"aspectmode": "auto"}})
fig
Answered By - Davide_sd
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.