Matlab - combining two surface plots - matlab

I'm trying to combine two surface plots in a single figure. The problem is that one of the two is plotted on the wrong axis. The reason is that:
surface1 = surf(x,y,z)
surface2 = surf(x,z,y)
This is due to the mathematical equations behind x,z and y. I can't change them, i.e. rearrange z in terms of y for surface2.
Is there a way to map the two to the correct axes?

if you show the code you briefly mention in the question, readers may have a chance to reproduce the problem.

Related

Linear transformations performed on a coordinate grid in MATLAB

Is it possible to graphically represent linear transformations in MATLAB like the one shown below?
In particular, I'm looking for a way to represent the way a coordinate grid might become squished, stretched, or rotated after a matrix multiplication has been performed. I've tried using meshgrid(x,y) to plot the grid but I've been having trouble getting it to display properly. Ideally, it would be nice to see the way that the transformation acts on a unit square (and, if possible, to see the transformation being performed in a continuous fashion, where you can see the graphs morphing into each other). However, I'm willing to sacrifice these last two requirements.
Here is the code I have used so far:
x = -10:2:10;
y = -10:2:10;
[X,Y] = meshgrid(x,y);
plot(X,Y)
For some reason, only vertical lines have been plotted. (The documentation says it will display a square grid.)
please read the plot doc.
the problem is that what you are doing is trying to plot mash matrixes in a plot not by using mesh or something like that.
you may find this very helpful.

Subtract delaunay surfaces from each other

I have a surface by the code below and another surface which is created by the exact same code. I want to see the height differences in another figure. How am I able to do that? Already operated with the Minus-operator but this won't work.
Furthermore the matrices have NOT the same size!
Appreciate your help!
x1 = Cx1;
y1 = Cy1;
z1 = Cz1;
tri1 = delaunay(x1,y1);
fig1 = figure%('units','normalized','outerposition',[0 0 1 1]);
trisurf(tri1,x2,y2,z2)
xlabel('x [mm] ','FontSize',30)
ylabel('y [mm] ','FontSize',30)
zlabel('z [mm] ','FontSize',30)
The simplest way to solve this problem is to interpolate from one mesh onto the other one. Such an approach works well when one is more highly resolved than the other, or when you're not as concerned with results at individual nodes, but rather the overall pattern across elements. If that's not the case, then you have a very complicated problem because you need to create a polygonal surface that fully captures all nodes and edges of both triangulations. Consider the following pair of triangular patterns:
A surface that captured all the variations would need to have all the vertices and edges that make up both of them, which is not a purely triangular surface. So, let us instead assume the easier case. To map results from one triangulation to the other, you simply need to formulate functions that define how the values vary along the triangles, which are more broadly called basis functions. It is often assumed that values betweeen the nodes (i.e. vertices) of the triangles vary linearly along the surfaces of the triangles. You can do it differently if you want, it just requires defining new basis functions. If we go for linear functions, then the equations in 2D are pretty simple. Let's say you make an array trimap that has which triangle each of the vertices of the other triangulation is inside of. This can be accomplished using the info here. Then, we set the coordinates of the vertices of the current triangle to (x1,y1), (x2,y2), and (x3,y3), and then do the math:
for cnt1=1,npoints
x1=x(tri1(trimap(cnt1),1));
x2=x(tri1(trimap(cnt1),2));
x3=x(tri1(trimap(cnt1),3));
y1=y(tri1(trimap(cnt1),1));
y2=y(tri1(trimap(cnt1),2));
y3=y(tri1(trimap(cnt1),3));
delta=x2*y3+x1*y2+x3*y1-x2*y1-x1*y3-x3*y2;
delta1=(x2*y3-x3*y2+xstat(cnt1)*(y2-y3)+ystat(cnt1)*(x3-x2));
delta2=(x3*y1-x1*y3+xstat(cnt1)*(y3-y1)+ystat(cnt1)*(x1-x3));
delta3=(x1*y2-x2*y1+xstat(cnt1)*(y1-y2)+ystat(cnt1)*(x2-x1));
weights(cnt1,1)=delta1/delta;
weights(cnt1,2)=delta2/delta;
weights(cnt1,3)=delta3/delta;
z1=z(tri1(trimap(cnt1),1));
z2=z(tri1(trimap(cnt1),2));
z3=z(tri1(trimap(cnt1),3));
valinterp(cnt1)=sum(weights(cnt1,:).*[z1,z2,z3]);
end
valinterp is the interpolated value for each point. Here and here are some nice slides explaining the mathematics behind all this. Note that I've not tested any of this code. Note also that you will need to do something to assign to values outside of the triangulation. Perhaps a null value, or an inverse-distance weighted value.

Graph different 2D ellipses in 3D axes at different heights in MATLAB

I want to graph different ellipses at different heights (z-coordinates).
My idea was to write the following code:
z=0:1/64:3/8;
t=linspace(-pi,pi,25);
[t,z]=meshgrid(t,z);
x=cos(-t);
y=cos(-t-4*pi*z);
I would like MATLAB to read my code like:
"Find x and y, and plot at the corresponding height (z). By doing so, join the points such that you'll form an ellipse at constant z".
I'm not sure what kind of function I could use here to do this and was hoping for someone to tell me if there exists such a function that will do the job or something similar.
In case you're wondering, I want to graph the polarization of light given two counterpropagating beams.
EDIT: While this is similar to the question draw ellipse and ellipsoid in MATLAB, that question doesn't address plotting 2D ellipses in 3D axes, which is what I am trying to do.
This can be solved by removing the meshgrid, and just using a plain old for-loop.
t = linspace(-pi,pi,25);
z = 0:1/64:3/8
f = figure;
hold on;
for i = 1:length(z)
x=cos(-t); y=cos(-t-4*pi*z(i));
plot3(x,y,z(i)*ones(length(z),1));
end
The problem in the original code is that you're trying build the ellipses all at once, but each ellipse only depends on a single z value, not the entire array of z values.
When I run this code, it produces the following plot:

finding gradient/curvature of surface defined by arbitrary, non-grid-spaced points

So I have a 3 dimensional matrix of points that (presumably) define a surface. For my purposes, X and Y can be random values but when plotted along with their Z coordinates, they will define some undulating surface. I'd like to measure the local curvatures of said surface, and in order to do that, I need to be able to find the gradient of said surface, at which point calculating the curvature is trivial.
I have not yet found an implementation of how to measure this curvature that doesn't make use of Matlab's gradient function. The problem with Matlab's gradient function is that it assumes that the points are in some sort of order, similar to diff(X). This would suffice if my points were spaced along a grid, which is not necessarily the case.
One possible solution to measuring the gradient is to give in and assign each point to a discrete coordinate in a grid in the XY plane, thus overcoming this issue. However, this solution seems somewhat inelegant and was curious to see if anyone had suggestions. Thanks!
You can use griddata to interpolate from your scattered data points to grid spaced points and then calculate the gradient.

SLERP rotates in the wrong direction (i.e. not shortest path)

I have two ellipsoids in R3 described in terms of their centre points (P), their axes lengths (a,b,c), and their rotation vector (R). I wish to interpolate a tubular structure between these two ellipsoids along a given centre line. This is done by creating an ellipsoid centred at each point along the centre line. Its axes lengths are interpolated linearly between those at the two endpoints, and the rotation is obtained as a quaternion using spherical linear interpolation, or SLERP.
I previously asked a similar question on this problem here. I have since isolated the issue a little further, and thought it warranted a new post. The difference here is that before doing SLERP, I first rotate the two reference ellipsoids by the inverse of the rotation matrix that describes one of them, such that one of them is now axis-aligned (i.e. has no rotation). Previously this appeared to solve the problem, but I have encountered an example where this fix does not work.
The source code to reproduce this issue is available here. The relevant function is ellipsoidSLERP and the functions it calls. Here is a screenshot of the output:
What you are seeing is an interpolation of ellipsoid volumes (blue) between two reference ellipsoid volumes at either end (green) along a centreline (cyan).
Problem Statement
The interpolation on the left works correctly, resulting in a smooth tubular structure. The interpolation on the right does not work correctly, and results in a twist.
What is causing this behaviour, and how can I correct it?
Please let me know if there's anything I can do to clarify.