I'm a beginner in matlab and I'm trying to transform a photo according to a function given in the code.
My aim is to see where some points of the R^2 plan go. For example, i'd like to transform :
But I can't figure this out.
I found some good conversations on this topic:
https://www.mathworks.com/matlabcentral/answers/81975-is-it-possible-to-pass-an-image-as-an-input-to-a-function-in-matlab
and good functions like :
https://www.mathworks.com/help/images/ref/imtransform.html
https://www.mathworks.com/help/images/ref/imwarp.html
but I don't understand what to do with that because I don't have a matrix but just like the function "1/z"...
The aim is to do something better than this :
How to plot the Wolfram Alpha grid? [MATLAB]
I've tried to add colors to the mesh graph but I ve not succed in doing so... I could only find how to change uniformly the colors, like setting all in green...
If you have another solution not using an image but constructing a
grid of a range of colors and then deforming it (like in the link) or
even better, instead of a grid, creating a whole plan with an uniform
distribution of the colors... it also fixes the problem!
Thank you !
You can use the surf function to plot a grid with colored patches. If you use the same code in my answer to your previous question, you could visualize the original grid with colors as follows:
C = X.^2 + Y.^2; %change this to any function you like to get different color patterns
surf(X,Y,C);
view([0, 90]); %view the mesh from above
Now, if you want to see how the transformed mesh looks like, you can do:
surf(U,V,C);
view([0, 90]);
where U and V are computed according to my previous answer.
Edit: Added sample code for transforming an image using geometricTransform2d and imwarp.
clear
clc
A = imread('peppers.png');
figure(1)
imshow(A)
t1 = geometricTransform2d(#ftransform);
Rin = imref2d(size(A),[-1 1],[-1 1]);
Rout = imref2d(size(A),[-5 5],[-5 5]);
B = imwarp(A, Rin, t1,'OutputView',Rout);
figure(2);
imshow(B)
function Xt = ftransform(X)
Z = complex(X(:,1),X(:,2));
Zt = 1./Z;
Xt(:,1) = real(Zt);
Xt(:,2) = imag(Zt);
end
Related
i'm currently trying to plot this function:
Z^2 = (X.^2+Y.^2+2*w.*Z.*Y.*a)./(1-w^2*a^2)
Geogebra gives a lightcone https://en.wikipedia.org/wiki/Light_cone but crushes if i change the parameters a bit. I tried then matlab:
[X,Y] = meshgrid(-10:.5:10);
a=2;
w=1;
Z = (X.^2+Y.^2+2*w.*sqrt(abs(Z)).*Y.*a)./(1-w^2*a^2);
surf(X,Y,Z)
zlim([-5,5])
And it has too few points. I wish i could add some changing meshgrid, like (-5:.1:5), but it gives:
Arrays have incompatible sizes for this operation.
Probably due to sqrt(abs(Z)) in the equation. I don't know how to fix it.
Thanks
It's easier to directly generate the cone data with command cylinder
t = 0:pi/10:2*pi;
r =linspace(2,0,numel(t))
[X,Y,Z] = cylinder(r);
figure
hs1=surf(X,Y,Z)
Note that I have added the handle hs1 which is output of surf.
This way you can change any property of the generated cone surface explained in detail here :
https://uk.mathworks.com/help/matlab/ref/matlab.graphics.chart.primitive.surface-properties.html
I have three variables x, y and z. I have inequalities of the form
x >= a, y>= b, z>=c, x+y>=d, y+z>=e, x+z>=f, x+y+z>=g
where a to g are positive numbers. On a 3D plot with axes x, y and z, this is an open volume. I would like to fill the open side (i.e. away from 0) shape with color and show it in a plot. What is the way to do this on MATLAB?
I attempted to use fill3 and a mesh but the result was not very good
[x,y,z] = meshgrid(0:0.01:2,0:0.01:2,0:0.01:2);
ineq = (x>=1)& (y>0.5)&(z>=0.25)&(x+y>1.25)&(y+z>0.6)&(x+z>1.1)&(x+y+z>1.6);
fill3(x(:),y(:),z(:), 'r')
box on
grid on
Using plot3 also was not very good. Is there any other way to generate a nice 3D figure on MATLAB?
Mathematica does this using RegionPlot3D. I was hoping for a similar resultant image.
First of all, be careful when using 3D meshes, the one you defined contains 8M+ points.
Assuming your shape is convex, you can use convhull and trisurf:
Not that the option 'Simplify' is set as true to reduce the number of elements accounted for in the convex hull.
[x,y,z] = meshgrid(0:0.1:2,0:0.1:2,0:0.1:2);
ineq = (x>=1)& (y>0.5)&(z>=0.25)&(x+y>1.25)&(y+z>0.6)&(x+z>1.1)&(x+y+z>1.6);
figure;
x_ineq = x(ineq);
y_ineq = y(ineq);
z_ineq = z(ineq);
id_cvhl = convhull(x_ineq,y_ineq,z_ineq,'Simplify',true);
trisurf(id_cvhl,x_ineq,y_ineq,z_ineq,'FaceColor','cyan','edgecolor','none')
xlim([0 2])
ylim([0 2])
zlim([0 2])
In case you want the result to look a bit more than RegionPlot3D, don't use Simplify, and plot the edges (Be careful not too have a mesh with too many points!).
id_cvhl = convhull(x_ineq,y_ineq,z_ineq);
trisurf(id_cvhl,x_ineq,y_ineq,z_ineq,'Facecolor','yellow')
clc
clear all
n1=rand(1,10);
n2=rand(1,10);
n3=rand(1,10);
n4=rand(1,10);
m1=rand(1,10);
m2=rand(1,10);
m3=rand(1,10);
m4=rand(1,10);
n=[n1;n2;n3;n4];
m=[m1;m2;m3;m4];
z=[0.1,0.2,0.3,0.4];
I want to create a surface plot using above data.for given z=0.1 plot(n1,m1), for z=0.2 plot(n2,m2)....how to combine all this to get a surface plot?
Mathwork's answer on how to plot scattered data should give you the best start.
I assume that your minimal example is not correct regarding z, because all data has to have the same dimension.
Fixing this, interpolation is one answer to your approach.
Following the mentioned link, it should look like this:
n = rand(4,10);
m = rand(4,10);
z=repmat([0.1 : 0.1 : 0.4]',1,size(n,2));
resolution = 0.01;
[xi,yi] = meshgrid(min(n):resolution:max(n), min(m):resolution:max(m));
zi = griddata(n,m,z,xi,yi);
surf(xi,yi,zi);
I am very new to Matlab and am trying to implement the following fresnel diffraction using the fourier transform:
This is taken from the following wikipedia page: http://en.wikipedia.org/wiki/Fresnel_diffraction
I am trying a square aperture of width 5 cm.
clc;clear;
lambda=1*10^-6;
w=.05;
z=2.0;
k=(2*pi)/lambda;
x1=linspace(-0.2,0.2,2048);
y1=linspace(-0.2,0.2,2048);
U1=((abs(x1)<=(w)/2))&((abs(y1)<=(w)/2));
u1=double(U1);
figure(1)
plot(x1,u1)
g=u1'*exp(1i*(pi/(lambda*z))*(x1.^2+y1.^2));
G=fftshift(fft2(g));
h=(exp(1i*k*z)/(1i*lambda*z))*exp(1i*(pi/(lambda*z))*(x1.^2+y1.^2));
H=fftshift(fft2(h));
u2=H*G;
figure(2)
plot(x1,abs(u2));
When I plot the field u2, for any of the distances, z, that I try, it just shows up like some random pattern and not the expected diffraction pattern for a square aperture.
Like I said, I am very new to MATLAB and find it difficult to understand. I think I am making this more complicated than it needs to be, and am implementing the integrals incorrectly.
Any pointers or advice? I am quite stuck...
Thanks!
Looks like you want to simulate Fresnel diffraction with this code.
With a few changes you can view the actual image. Shown here is the amplitude. The intensity would be u2.*conj(u2).
Note however that critical sampling will occur much further away than 2 meters, more like 100 meters, for the physical parameters you are using.
Also there needs to be some additional re-scaling on the output plane, not done here. Otherwise the diffraction pattern will get very small for low Fresnel numbers.
clc;clear;
N=1048;
L=0.4;
lambda=1*10^-6;
w=.05;
z=500.0;
k=(2*pi)/lambda;
src_delta = L/N;
critical_sampling_z = N*src_delta^2/lambda;
[x1 y1] = meshgrid((-N/2 : N/2-1) * src_delta);
X = double(abs(x1)<w/2); Y = double(abs(y1)<w/2);
u1 = X.*Y;
figure(1);
colormap(gray); imagesc(mat2gray(u1));
g=u1'*exp(1i*(pi/(lambda*z))*(x1.^2+y1.^2));
G=fftshift(fft2(g));
h=(exp(1i*k*z)/(1i*lambda*z))*exp(1i*(pi/(lambda*z))*(x1.^2+y1.^2));
H=fftshift(fft2(h));
u2=H*G;
figure(2);
colormap(gray); imagesc(mat2gray(abs(u2)));
I have two normal distributions and i am trying to make a volumetric surface from them. I got the following graph
clear; clc;
nsamp = 100000;
%
% Basic variables
%
m1=2.724;
dp1=0.375;
R = normrnd(m1,dp1, nsamp, 1);
m2=1.345;
dp2=0.135;
S = normrnd(m2,dp2, nsamp, 1);
%
Z = R - S;
I = (Z < 0);
pf = sum(I)/nsamp
beta = -norminv(pf)
%
% Histograms
hist(S,20)
hold on
hist(R,40)
set(findobj('Type','patch'),'Facecolor','none','Edgecolor','black')
set(gca,'Fontsize',18,'Fontname','euclid')
xlabel('R & S')
figure
scatterhist(R,S)
xlabel('R'),ylabel('S')
and i would like to make a 3D surface and the points in red to remain in red and the blue points in blue. Can someone help me? Regards
I can't write a tested solution right now - not access to Matlab license server. But you have two problems here.
The first is to create a surface plot of density. You can use the hist3 function for the this - and if you return the values of the bins you can control the plotting yourself:
[N C] = histc(X)
(I'm sorry it is not clear to me what you really want to plot - is it R, S, Z, or R+S? that's why I used X).
Then to color the graph, you can use patch coloring - see http://www.mathworks.com/help/matlab/visualize/specifying-patch-coloring.html for how to do that.
The combination of these two should get you a long way there... but it's still a little unclear what you really want to do. I hope these hints help you on your way.