Get axes position from a 3D coordinate
9 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
I'm creating quality animations of vectors for an educational video I'm making. I don't like that the existing quiver and quiver3 implementations don't create arrowheads that are solid, so would like to use annotation( 'arrow', ...) instead. In 2D, then, I can make animations that look like this:
I'd like to now do this for 3D vectors, where I can preferably also rotate the view. Since annotations only accept x & y, and have a 1x4 Position property, I think I should be able to compute the [n0 n1 width height] Position at each render frame from the [x, y, z] coordinates and then update the annotations. I've looked around the Add-ons manager and while there are quite a few "3D Arrow" add-ons, it seems like they either don't (easily) support updating coordinates of the arrow, don't draw a solid arrow, or the arrowhead doesn't stay "normal" to the camera. Any thoughts?
Here's a code framework, based on quiver3, that I'd like to get working as I've described:
clear
close all
fig = figure;
% Initialize "arrow" plotting
vec3d = [ 0.34; 0.72; 0.50 ];
q3d = quiver3( 0, 0, 0, 0, 0, 0, "off", LineWidth=2, MaxHeadSize=0.5 );
% Axis setup
ax = gca;
ax.Units = "normalized";
axis equal
axis vis3d
ax.XLim = [-1 1];
ax.YLim = [-1 1];
ax.ZLim = [-1 1];
ax.Box = "on";
ax.BoxStyle = "full";
view( 50, 20 )
drawnow
% Update vector draw length
rotation_angle = 360;
num_frames = 60;
for frame = 1 : num_frames
q3d.UData = vec3d(1) * frame / num_frames;
q3d.VData = vec3d(2) * frame / num_frames;
q3d.WData = vec3d(3) * frame / num_frames;
drawnow
end
% Rotate view
num_frames = 60;
for frame = 1 : num_frames
ax.View(1) = ax.View(1) + rotation_angle / num_frames;
drawnow
end
0 comentarios
Respuestas (1)
akshatsood
el 1 de Sept. de 2023
Editada: akshatsood
el 18 de Oct. de 2023
Hi Gregory,
I understand that you wish to create quality animations for an educational video and prefer not to leverage quiver3 implementations. I carefully investigated your requirements and boiled down to a possible workaround which utilises arrow function. To be clear, I have used arrow function to plot the line in 3D space along with the arrowhead. Also, while updating the vector draw length, I have set the visibility of the arrow handle arr to off so that it does not get carried forward with the next iteration. Here is the code snippet for your reference
clear; close all;
origin = [0 0 0];
vec3d = [0.34 0.72 0.50];
% axis setup
ax = gca;
ax.Units = "normalized";
axis equal
axis vis3d
ax.XLim = [-1 1];
ax.YLim = [-1 1];
ax.ZLim = [-1 1];
ax.Box = "on";
ax.BoxStyle = "full";
view(50,20);
rotation_angle = 360;
num_frames = 60;
for frame = 1 : num_frames
newCoord = vec3d*(frame/num_frames); % store next set of coordinates
arr = arrow(origin,newCoord);
drawnow
arr.Visible = 'off';
end
arr.Visible = 'on'; % set Visible to on after updating the line
% Rotate view
for frame = 1 : num_frames
ax.View(1) = ax.View(1) + rotation_angle / num_frames;
drawnow
end
I hope this helps.
0 comentarios
Ver también
Categorías
Más información sobre 2-D and 3-D Plots en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!