I want to add the shadow/reflection of the trajectory to each side of my 3d plot (2D perspective projection), something like the picture below:
a = 1.;
b = 0.3;
c = 0.3;
b1 = 0.008;
b2 = 0.008;
b3 = 0.002;
c1 = 0.004;
c2 = 0.0045;
eta = [50 20 20];
F = #(t,y) [a*y(1) - b1*y(1)*y(2)-b2*y(1)*y(3)- b3* y(1)*y(1) ; -b*y(2) + c1*y(1)*y(2); -c*y(3) + c2*y(1)*y(3)];
[t,y] = ode45(F,[0: (300/1000000): 300], eta);
plot3(y(:,1),y(:,2),y(:,3), 'color', 'blue','LineWidth',2)
grid on;
I guess the simplest approach would be to plot lines on the plane of the axes. For instance, in your given example (I assumed a = 0.3 as you did not specify a) plot3 produces this figure:
Here is what you wanted to add:
hold on
plot3(0*y(:,1),y(:,2),y(:,3), 'color', 'k','LineWidth',1); % shadow on the Y-Z plane
plot3(y(:,1),0*y(:,2),y(:,3), 'color', 'k','LineWidth',1); % shadow on the X-Z plane
plot3(y(:,1),y(:,2),0*y(:,3), 'color', 'k','LineWidth',1); % shadow on the X-Y plane
which produces a graph like this:
FYI, you can also use imagesc to produce shadow for a surface like the example in this page which basically adds a 2D image of a 3D surface on the axes.
Related
I'm writing a code to plot the circular orbit of a satellite (created using comet3() function) around a 3d model of the Earth (created using surf() and set() functions). The problem is that I can't seem to find a way to get them together in the same plot. I have tried using hold on and hold off but that doesn't seem to work either. I'm pasting the MATLAB code below for reference.
Edit: All the other functions like sv_from_coe(), odeset, etc. are working perfectly, the only place I'm facing issue is combining the plots from comet3() and set().
G = 6.67E-11;
Me = 5.976E24;
coe = [6776, 0.0005638, 2.0543, 0.9, 5.549, 0];
[r, v] = sv_from_coe(coe);
rv = [r v];
opt = odeset('RelTol', 1e-6, 'AbsTol', 1e-6);
[t,X] = ode45(#rate, [0 2*1.5*3600], rv, opt);
[x,y,z] = sphere;
r_earth = 6378*1000;
figure
hs1 = surf(x*r_earth,y*r_earth,-z*r_earth);
cdata = imread('1024px-Land_ocean_ice_2048.jpg');
alpha = 1;
hold on
axis equal
comet3(X(:,1), X(:,2), X(:,3))
set(hs1, 'FaceColor', 'texturemap', 'CData', cdata, 'FaceAlpha', alpha, 'EdgeColor', 'none')
You just have to reverse the order, first plot the earth and set the texture. Then use comet3 to animate the trajectory:
% earth
[x,y,z] = sphere;
r_earth = 6378*1000;
% some simple trajectory
phi = 0:0.01:2*pi;
r_orbit = r_earth + 408*1e3; % ISS orbit height
xv = r_orbit * cos(phi);
yv = r_orbit * sin(phi);
zv = zeros(size(yv));
% draw figure
figure(1); clf;
ax = axes;
% first plot the earth and set texture
hs1 = surf(x*r_earth,y*r_earth,-z*r_earth);
alpha = 1;
cdata = imread("Land_ocean_ice_2048.jpg");
set(hs1, 'FaceColor', 'texturemap', 'CData', cdata, 'FaceAlpha', alpha, 'EdgeColor', 'none')
hold on
axis equal
% finally, animate using comet3
comet3(xv,yv,zv)
How to generate a 3D plot of a parametric curve with the orthographic projections on the inside walls of the 3D plot, as shown in this video?
I can generate a 3D plot of the curve using the plot3 function but I am lost how to create the blue orthographic projections on the inner walls of the cube ...and the red dashed lines.
P.S.
Also, how to generate the 3 separate "Coordinate Functions" plots (not shown on the diagram above but shown in the video) ...and how to synchronize them together during the animation?
Well, this took a lot of time to write.
clear;clc;close all
t = 0:0.01:6;
x = cos(5*t);
y = sin(5*t);
z = t;
%for x,y,z as as general function of t
xmin = min(x);
xmax = max(x);
ymin = min(y);
ymax = max(y);
zmin = min(z);
zmax = max(z);
orangeColorRGB = [0.8500 0.3250 0.0980];
%3D plot
plot3DSubplot = subplot(3,2,[1 3 5]);
view(3)
grid on
title('Parametric curve in R^3')
xlabel('x(t)')
ylabel('y(t)')
zlabel('z(t)')
xyProjectionOffset = -0.5;
xzProjectionOffset = 1.5;
yzProjectionOffset = 1.5;
xlim([xmin max(xmax, yzProjectionOffset)])
ylim([ymin max(ymax, xzProjectionOffset)])
zlim([min(zmin ,xyProjectionOffset) zmax])
curve3D_marker = animatedline(plot3DSubplot,x(1),y(1),z(1),'Marker','o','Color','magenta'); %marker in 3D
curve3D = animatedline(plot3DSubplot, x(1),y(1),z(1),'Color','magenta','LineStyle','-','LineWidth',2); %3D curve
curve3D_projectedToXY = animatedline(plot3DSubplot,x(1),y(1),xyProjectionOffset,'Color','blue','LineStyle','-','LineWidth',2); %projection on xy
curve3D_projectionStraightLineToXY = animatedline(plot3DSubplot,x(1),y(1),z(1),'Color',orangeColorRGB,'LineStyle','--','LineWidth',2); %projection on xy
curve3D_projectedToXZ = animatedline(plot3DSubplot,x(1),xzProjectionOffset,z(1),'Color','blue','LineStyle','-','LineWidth',2); %projection on xz
curve3D_projectionStraightLineToXZ = animatedline(plot3DSubplot,x(1),y(1),z(1),'Color',orangeColorRGB,'LineStyle','--','LineWidth',2); %projection on xy
curve3D_projectedToYZ = animatedline(plot3DSubplot,yzProjectionOffset,y(1),z(1),'Color','blue','LineStyle','-','LineWidth',2); %projection on yz
curve3D_projectionStraightLineToYZ = animatedline(plot3DSubplot,x(1),y(1),z(1),'Color',orangeColorRGB,'LineStyle','--','LineWidth',2); %projection on xy
%x plot
xPlot = subplot(3,2,2);
grid on
title('Coordinates')
ylabel('cos(5t)')
xlim([t(1) t(end)])
ylim([xmin xmax])
xCoordinate = animatedline(xPlot,t(1),x(1),'Color','blue');
xCoordinate_projectedValue = animatedline(xPlot,t(1),x(1),'Color',orangeColorRGB,'LineStyle','--');
xCoordinateMarker = animatedline(xPlot,t(1),x(1),'Color','blue','Marker','o');
%y plot
yPlot = subplot(3,2,4);
grid on
ylabel('sin(5t)')
xlim([t(1) t(end)])
ylim([ymin ymax])
yCoordinate = animatedline(yPlot,t(1),y(1),'Color','blue');
yCoordinate_projectedValue = animatedline(yPlot,t(1),y(1),'Color',orangeColorRGB,'LineStyle','--');
yCoordinateMarker = animatedline(yPlot,t(1),y(1),'Color','blue','Marker','o');
%z plot
zPlot = subplot(3,2,6);
grid on
ylabel('t')
xlim([t(1) t(end)])
ylim([zmin zmax])
zCoordinate = animatedline(zPlot,t(1),z(1),'Color','blue');
zCoordinate_projectedValue = animatedline(zPlot,t(1),z(1),'Color',orangeColorRGB,'LineStyle','--');
zCoordinateMarker = animatedline(zPlot,t(1),z(1),'Color','blue','Marker','o');
for i=2:length(t)
% 3D plot & projections
addpoints(curve3D,x(i),y(i),z(i))
clearpoints(curve3D_marker)
addpoints(curve3D_marker,x(i),y(i),z(i))
%XY projection
addpoints(curve3D_projectedToXY,x(i),y(i),xyProjectionOffset)
clearpoints(curve3D_projectionStraightLineToXY)
addpoints(curve3D_projectionStraightLineToXY,[x(i) x(i)],[y(i) y(i)],[xyProjectionOffset z(i)])
%XZ projection
addpoints(curve3D_projectedToXZ,x(i),xzProjectionOffset,z(i))
clearpoints(curve3D_projectionStraightLineToXZ)
addpoints(curve3D_projectionStraightLineToXZ,[x(i) x(i)],[xzProjectionOffset y(i)],[z(i) z(i)])
%YZ projection
addpoints(curve3D_projectedToYZ,1.5,y(i),z(i))
clearpoints(curve3D_projectionStraightLineToYZ)
addpoints(curve3D_projectionStraightLineToYZ,[yzProjectionOffset x(i)],[y(i) y(i)],[z(i) z(i)])
%2D x plot
addpoints(xCoordinate,t(i),x(i))
clearpoints(xCoordinate_projectedValue)
addpoints(xCoordinate_projectedValue,[t(1) t(i)],[x(i) x(i)])
clearpoints(xCoordinateMarker)
addpoints(xCoordinateMarker,t(i),x(i))
%2D y plot
addpoints(yCoordinate,t(i),y(i))
clearpoints(yCoordinate_projectedValue)
addpoints(yCoordinate_projectedValue,[t(1) t(i)],[y(i) y(i)])
clearpoints(yCoordinateMarker)
addpoints(yCoordinateMarker,t(i),y(i))
%2D z plot
addpoints(zCoordinate,t(i),z(i))
clearpoints(zCoordinate_projectedValue)
addpoints(zCoordinate_projectedValue,[t(1) t(i)],[z(i) z(i)])
clearpoints(zCoordinateMarker)
addpoints(zCoordinateMarker,t(i),z(i))
drawnow
end
Outside the for-loop:
Define your subplots.
Define your lines in a somewhat object-oriented approach. Define lines with animatedline
including their
properties
(color, linewidth etc).
Define lines with animatedline with the intention to use only the marker.
Inside the for-loop:
Add the new points to those lines using addpoints.
Regarding the projections to the xy,yz,xz planes:
The projection of a point (x0,y0,z0) to the xy plane defined by z = -2 is (x0,y0,-2). Therefore when you have a point (x,y,z) you project to the correct plane in the same way.
For the vertical lines that connect the current point to the projection, at every update to the plot remove previous points and redraw them. That's why I first call
clearpoints
to remove any previous points and then addpoints to add 2 points for a straight line from the projection to the actual (x,y,z) point.
For the "marker-lines", again clearpoints and then add the new point.
After adding the points to all the lines, call
drawnow
before the next loop iteration for all lines to be updated at the same time (and for the updates to appear synchronized).
I am trying to make a cut out of a pipe and I want to make a curved surface to represent the outside of the pipe. However when I plot the surface I only get the diagonal of the surface instead of the surface itself. How can I fix this?
MWE:
r = 0:0.1:3;
z = 0:0.1:10;
[rr, zz] = meshgrid(r,z);
% set cut planes angles
theta1 = 0;
theta2 = pi*135/180;
nt = 101; % angle resolution
figure(1);
clf;
t3 = linspace(theta1, (theta2 - 2*pi), nt);
[rr3, tt3] = meshgrid(r,t3);
% Create curved surface
xx5 = r(end) * cos(tt3);
yy5 = r(end) * sin(tt3);
h5 = surface(xx5, yy5,zz)
The mesh-grid you created is based on theta and the radius. However, the radius is constant for the outside of the pipe so instead it should be based on theta and z since those are the two independent variables defining the grid. Based on this reasoning I believe the following is what you're after.
r = 0:0.1:3;
z = 0:0.1:10;
% set cut planes angles
theta1 = 0;
theta2 = pi*135/180;
nt = 101; % angle resolution
figure(1);
clf;
% create a grid over theta and z
t3 = linspace(theta1, (theta2 - 2*pi), nt);
[tt3, zz3] = meshgrid(t3, z);
% convert from cylindical to Cartesian coordinates
xx5 = r(end) * cos(tt3);
yy5 = r(end) * sin(tt3);
% plot surface
h5 = surface(xx5, yy5, zz3, 'EdgeColor', 'none');
% extra stuff to make plot prettier
axis vis3d
axis equal
view(3)
camzoom(0.7);
Try with surf with surf(xx5, yy5, zz). Is this what you are looking for?
I would like to visualize the 3D volume under a surface generated by a 2-variable function. So far I can generate the surface but I don't know how to actually visualize the volume.
funCube = #(x,y)2.6207.*(sin(x)+cos(x)).*cos(y);
funCylinder = #(x, y) 3.078677852.*cos(y);
cubePlot = ezsurf(funCube, [0, 0.26, 0, 0.26], 120);
hold on;
cylinderPlot = ezsurf(funCylinder, [0, 0.26, 0, 0.26], 120);
This is a solution using filled polygons (patch objects). The idea is that in addition to the surface we create 5 polygons to form "4 walls and a floor" while the surface itself acts as a "ceiling".
The result:
I'd say it gives the impression of volume quite well.
function q47361071
%% Definitions:
% Define a surface equation: z = f(x,y)
funCube = #(x,y)2.6207.*(sin(x)+cos(x)).*cos(y);
% Evaluate the surface equation at a grid of points:
X = 0:0.01:0.26; Y = X;
[YY,XX] = meshgrid(X,Y);
ZZ = funCube(XX,YY);
%% Visualization:
figure(); surf(XX,YY,ZZ); hAx = gca; hold(hAx,'on'); view([-50 35]);
draw5Poly(hAx,XX,YY,ZZ);
end
function draw5Poly(hAx,XX,YY,ZZ)
P = {[XX(1,1), YY(1,1), 0; [XX(:,1) YY(:,1) ZZ(:,1) ]; XX(end,1),YY(end,1), 0],...
[XX(1,end), YY(1,end),0; [XX(:,end) YY(:,end) ZZ(:,end) ]; XX(end,1),YY(end,end), 0],...
[XX(1,1), YY(1,1), 0; [XX(1,:).' YY(1,:).' ZZ(1,:).' ]; XX(1,end),YY(1,end), 0],...
[XX(end,1), YY(end,1),0; [XX(end,:).' YY(end,:).' ZZ(end,:).']; XX(end,end),YY(end,end),0],...
[XX(1,1),YY(1,1),0; XX(1,end),YY(1,end),0; XX(end,end),YY(end,end),0; XX(end,1),YY(end,1),0]};
for indP = 1:numel(P)
patch(hAx, P{indP}(:,1),P{indP}(:,2),P{indP}(:,3),'k', 'FaceColor', 'y', 'FaceAlpha', 0.7);
end
end
As you might notice, the helper function draw5Poly is designed for a scenario where you only need to visualize one such volume per axes. If you do this with two surfaces/volumes it might be difficult to understand if all "walls" are yellow - for this reason you might want to make FaceColor an input to the function (so you could paint different volumes with a different color).
I have little or no experience with volumetric data in MATLAB,
I need to complete next task:
I have 3 vectors ( rows ):
x_ = vector(1:smpl:max_row,1);
y_ = vector(1:smpl:max_row,2);
z_ = vector(1:smpl:max_row,3);
that are samples from large 3 columns array vector with height max_row.
x_ , y_ , z_ are points of 3D figure - surface points of the figure ( volume ). They represent 3D body that should be drawn in matlab.
I created linear grid:
%linear grid
a = -1.1:step:(-1.1+step*(length(x_)-1));
b = -1.1:step:(-1.1+step*(length(y_)-1));
c = -1.1:step:(-1.1+step*(length(z_)-1));
[x,y,z] = meshgrid(-1.1:step:(-1.1+step*(length(x_)-1)));
and also I create array v length(x_)*length(x_)*length(x_) that contains '1' in cells that are of 3D body representation function points and '0' another.
I tryied to make interpolation:
vi = interp3(x,y,z,v,x,y,z,'nearest');
but then vi = v that I've already created.
Now I need to plot the v array on 3D and form 3D body like in
http://www.mathworks.com/help/techdoc/ref/isonormals.html
for example.
I make that next way:
%plotting:
figure
p = patch(isosurface(x,y,z,v,1e-5,'verbose'),'FaceColor','green','EdgeColor','none');
grid on;
isonormals(v,p);
daspect([1 1 1])
view(3);
axis tight;
camproj perspective;
camlight
lighting gouraud
colormap(hsv)
but I get then only small rectangles in place of function '1' that are not connected like in picture that is attached.
I expect solid body enclosed by that points to be plotted.
Does anybody know what is the problem , how to draw 3D body from the x,y,z,v arrays ?
Thanks in advance.
image:
http://imgur.com/Ulegj
Try this, which will be a nice plot (it interpolates a bit though):
x = vector(1:smpl:max_row,1);
y = vector(1:smpl:max_row,2);
z = vector(1:smpl:max_row,3);
% Settings
displaySurface = 1;
displayPoints = 0;
xres = 800; % Resolution, the higher, the smoother
yres = 800;
cm = 'default'; % Colormap
% Axes Limits
xmin = min(x);
ymin = min(y);
xmax = max(x);
ymax = max(y);
xi = linspace(xmin, xmax, xres);
yi = linspace(ymin, ymax, yres);
% Figure
myfig = figure('Position', [200 200 800 600]);
rotate3d off
[XI, YI] = meshgrid(xi, yi);
ZI = griddata(x, y, z, XI, YI, 'cubic');
mesh(XI,YI,ZI);
colormap(cm)
if(displaySurface == 1)
hold on;
surf(XI, YI, ZI, 'EdgeColor', 'none');
end
hold on;
xlabel('x');
ylabel('y');
zlabel('z');
title('Title', 'FontWeight', 'bold');
xlim([xmin xmax])
ylim([ymin ymax])
grid off;
if(displayPoints == 1)
hold on
plot3(x, y, z,'marker','p','markerfacecolor','w','linestyle','none')
hidden off
end