line passing through a triangulated mesh (MatLab) - matlab

I have a triangulated mesh (as in the figure) and I would like to found the line passing trhough the points (see figure). i tried by a 2D fit but I lose the shape of the mesh.
Can someone suggest a method to obtain a line as that I drown by hand?

Without an actual 3D path or mesh to work with, I have simulated one and show you how to use 3D splines for interpolation:
% simulating a 3D path and plotting it
N = 1000;
rng(1);
xyz = cumsum([randn(N,1)+0.8, randn(N,1)+0.2, randn(N,1)*2]);
plot3(xyz(:,1),xyz(:,2),xyz(:,3),'-b','LineWidth',2);
box on; view(30,30);
% interpolating using 3D splines.
% "smoothness" determines how many points to skip.
smoothness = floor( N/30 );
hold on;
fnplt(cscvn(xyz(1:smoothness:end,:)'),'r',2);
hold off;
Here is what the result shows (the original path is blue, the interpolated path is red):

Related

How to place a geographical map underneath a surf plot in Matlab?

If there is an easier way to do this in general any suggestions would be appreciated.
I have imported a .nc file into Matlab and currently have a surface plot created from the interpolated matrix of data which corresponds to longitudes and latitudes. An alpha scale has been applied to add opacity and now I would like to place a map of said longs and lats beneath it so that it acts as an overlay.
here is the code used to plot where xq,yq is the mesh longitude and latitude grid and newMatrix is the interpolated version of the original matrix. Attached is the top view surf plot which I would like a map of long lat restricted x,y axis beneath (line style or topographic)
f = figure;
ax = axes('Parent',f);
h = surf(xq,yq,newMatrix,'Parent',ax);
set(h, 'edgecolor','none');
view(ax,[0,90]);
alpha color
alpha scaled
grid off
colorbar;
I'm aware of geomap but I'm not sure how it can be used in this way without causing the axis to misalign or just not be applied correctly. Before I was using a contour plot but found it easier to interpolate and plot with surf as per this post: Matlab how to make smooth contour plot?

Matlab: How can I control the color of a streamtube plot?

I am currently trying to plot 3D streamtubes. I want the tubes to be colored corresponding to their respective velocity (e.g. slow = blue, fast = red).
To be more exact, I have three 3D-matrices containing the velocity in x, y and z direction. The color of the streamtubes should be sqrt(vx^2+vy^2+vz^2). When using streamtube(x,y,z,vx,vy,vz,sx,sy,sz) the tubes are colored according to their z-coordinate which is useless because it's a 3D plot anyway.
Well this wasn't easy (it ought to be a builtin option), but by modifying the CData of each tube (they are each their own graphics object), you can achieve the desired result. Here's an example
load wind
[sx,sy,sz] = meshgrid(80,20:10:50,0:5:15);
h=streamtube(x,y,z,u,v,w,sx,sy,sz);
drawnow
view(3)
axis tight
shading interp;
This gives this picture:
but then doing this:
vel=sqrt(u.^2+v.^2+w.^2); %// calculate velocities
for i=1:length(h)
%// Modify the colour data of each tube
set(h(i),'CData',interp3(x,y,z,vel,get(h(i),'XData')...
,get(h(i),'YData'),get(h(i),'ZData'),'spline'))
end
drawnow
view(3)
axis tight
shading interp;
gives this result
NOTES:
1) I don't know if this is fully correct, I don't know how to test it
2) You have to interpolate the velocity data from the points where it's known onto the vertices of the streamtubes
3) I found the spline interpolation option to work best, but the other options might work better in other cases

Plotting a rectangular matrix into a circle

I have generated a rectangular matrix with the azimouth angle changing with rows and the radius changing as you change column. These are meant to represent the relative velocities experienced by a rotating helicopter blade. This produces a matrix called Vmat. I want to plot this to appears in a circle (representing the rotation of the blade)
So far I have tried
[R,T] = meshgrid(r,az);
[x,y] = pol2cart(T,R);
surf(x,y,Vmat(r,az));
which should produce a contoured surface showing velocity as it changes with azimouth angle and radius but it comes up with dimension errors.
I don't mind if it is a 2d contour plot or 3d plot i guess both would be written in a similar way.
Thanks
James
The error is in writing Vmat(r,az), presuming that these are actual values of radius and azimuth, not indexes into your radius and azimuth. If you want to take only a subset of Vmat that's a slightly different matter, but this should work:
[R,T] = meshgrid(r,az); % creates a grid in polar coordinates
[x,y] = pol2cart(T,R); % changes those to cartesian for surf
surf(x,y,Vmat);
Alternatively you could do a contour plot:
h = polar([0 2*pi], [0 max(r)]); % set up polar axes with right scale
delete(h) % remove line
hold on
contour(x,y,Vmat);

project a sphere to a plane using matlab

This is probably very basic matlab, so forgive me.
I use the command sphere to create a 3D sphere and have the x,y,z matrices that will produce it using surf. For example:
[x,y,z]=sphere(64);
I'd like to project (or sum) this 3D sphere into one of the Cartesian 2D planes (for example X-Y plane) to obtain a 2D matrix that will be the projection of that sphere. Using imshow or imagesc on the output should look something like this:
simple summing obviously doesn't work, how can I accomplish that in Matlab?
It is possible that I completely misunderstand your question, in which case I apologize; but I think one of the following three methods may in fact be what you need. Note that method 3 gives an image that looks a lot like the example you provided... but I got there with a very different route (not using the sphere command at all, but computing "voxels inside" and "voxels outside" by working directly with their distance from the center). I inverted the second image compared to the third on since it looked better that way - filling the sphere with zeros made it look almost like a black disk.
%% method 1: find the coordinates, and histogram them
[x y z]=sphere(200);
xv = linspace(-1,1,40);
[xh xc]=histc(x(:), xv);
[yh yc]=histc(y(:), xv);
% sum the occurrences of coordinates using sparse:
sm = sparse(xc, yc, ones(size(xc)));
sf = full(sm);
figure;
subplot(1,3,1);
imagesc(sf); axis image; axis off
caxis([0 sf(19,19)]) % add some clipping
title 'projection of point density'
%% method 2: fill a sphere and add its volume elements:
xv = linspace(-1,1,100);
[xx yy zz]=meshgrid(xv,xv,xv);
rr = sqrt(xx.^2 + yy.^2 + zz.^2);
vol = zeros(numel(xv)*[1 1 1]);
vol(rr<1)=1;
proj = sum(vol,3);
subplot(1,3,2)
imagesc(proj); axis image; axis off; colormap gray
title 'projection of volume'
%% method 3: visualize just a thin shell:
vol2 = ones(numel(xv)*[1 1 1]);
vol2(rr<1) = 0;
vol2(rr<0.95)=1;
projShell = sum(vol2,3);
subplot(1,3,3);
imagesc(projShell); axis image; axis off; colormap gray
title 'projection of a shell'
You can project on the X-Y plane in Matlab by using:
[x,y,z] = sphere(64);
surf(x,y,zeros(size(z)));
But I think you should not use Matlab for this, because the problem is so simple you can do this analytically...
I would look at map projections, which are designed for this purpose.
A search on "map projections matlab" yields documentation on a Matlab mapping toolbox. However, if you want or need to roll your own, there is a good summary at the USGS website, as well as a wikipedia article.

Polar gridlines on a Cartesian scatter plot

I have a script to create scatter plots (using gscatter) based on x-y data (discrete data points, not continuous) produced by another script. Since these data points are actually the locations of certain objects in a circular space, adding polar grid lines will make the plots more meaningful.
Does anyone know how to show polar grid lines on a Cartesian scatter plot, or am I better off using polar plots?
I once made this script for drawing a polar coordinate system on top of a regular plot. Perhaps it can be useful for you. It is based on this script but simplified to only draw the coordinate system and no data. If this wasn't what you were looking for, check out the linked script, perhaps it can help as well.
Be sure to tweak the radius as needed! I usually disable the axis but it's up to you to fix that if you need another look :)
R=6000; %radius
S=10; %num circ.lines
N=10; %num ang.lines
sect_width=2*pi/N;
offset_angle=0:sect_width:2*pi-sect_width;
%------------------
r=linspace(0,R,S+1);
w=0:.01:2*pi;
clf %remove if needed
hold on
axis equal
for n=2:length(r)
plot(real(r(n)*exp(j*w)),imag(r(n)*exp(j*w)),'k--')
end
for n=1:length(offset_angle)
plot(real([0 R]*exp(j*offset_angle(n))),imag([0 R]*exp(j*offset_angle(n))),'k-')
end
%------------------
You can always use the pol2cart function to generate the polar grid lines.
For example:
function DrawGridLines
x = randn(10);
y = randn(10);
figure;scatter(x(:),y(:));
hold on ;
for angle = 0:20:(360-20)
[x1,y1] = pol2cart( angle / 180 * pi , [0 2]);
plot(x1,y1,'r')
end
for rho = 0:0.1:2
[x1,y1] = pol2cart( 0:0.01:2*pi , rho);
plot(x1,y1,'b')
end
axis equal
end