Forming a curve between two lines - matlab

Can anyone let me know how should i go about creating a smooth curve in matlab
Problem statement: There are two straight line and i want to join them with a smooth curve. The dimensions of the curve are not limited to any specific dimensions. It is fine as long as there is a smooth continuity or the two lines are connected to each other by a smooth curve as shown in below figure
final Image
I hope the problem statement is clear and please let me know incase if anything is not clear.
I am using the following code and being a beginner I know its not a prefect code and there maybe mistakes. I would be glad if anyone can let me know how can i implement this curve in the form of a code in matlab.
s=10;
vec=0.6;
i=0; x=0; y=0; z=0; x1=0; y1=0; z1=0;
for i=1:s
x(i)=0;
z(i)=i;
y(i)=0;
end
angle=60;
j=0;
for j=1:s
if j<vec*s
x1(j)=0;
z1(j)=j;
y1(j)=0;
end
if j>=vec*s
x1(j)=x(j);
y1(j)=(z(j)-vec*s)*sind(angle)+y(i)*cosd(angle);
z1(j)=(z(j)-vec*s)*cosd(angle)-y(i)*sind(angle)+vec*s;
end
end
plot3(x1,y1,z1); xlabel('X axis'); ylabel('Y axis'); zlabel('Z axis');

use parametric interpolation (with parameter t):
plot3(x1,y1,z1); xlabel('X axis'); ylabel('Y axis'); zlabel('Z axis');
hold on;
n = length(x1);
t = (1:n)';
v = [x1;y1;z1]';
idx = [1:3 n-2:n]; % points you want to preserve
plot3(x1(idx),y1(idx),z1(idx),'o');
pp = interp1(t(idx,:),v(idx,:),'spline','pp');
tt = linspace(1,n,100);
X = ppval(pp, tt);
plot3(X(:,1),X(:,2),X(:,3));
grid on
and you get:

Related

Gap in MATLAB surface plot

I'm trying to plot a cone in MATLAB using the following code. However, when MATLAB generates the plot, there is a gap in the surface as shown in the image below. Would anyone be able to suggest a way to close it?
clearvars; close all; clc;
[theta, r] = meshgrid(-pi:0.1:pi, -4:0.1:6);
x = (r-1).*cos(theta);
y = (r-1).*sin(theta);
z = r;
% 3-D plot
figure
surf(x, y, z);
xlabel("x"); ylabel("y"); zlabel("z");
zlim([0 8]);
axis square
The problem is that the list of theta stops before reaching pi because the increments of 0.1 do not reach the upper bound.
For example, you may use the line
[theta, r] = meshgrid(-pi:(2*pi/20):pi, -4:0.1:6);
to complete the circle in 20 steps.

Rotating complex matrix with arbitrary angle in Matlab?

I have implemented the Hermite-Gaussian function in matlab for producing different modes. The light beam along z direction can be seen as a complex matrix in the plane.
The function for HG modes is as below.
%Hermite polynomial
function hk = HermitePoly(n)
if n==0
hk = 1;
elseif n==1
hk = [2 0];
else
hkm2 = zeros(1,n+1);
hkm2(n+1) = 1;
hkm1 = zeros(1,n+1);
hkm1(n) = 2;
for k=2:n
hk = zeros(1,n+1);
for e=n-k+1:2:n
hk(e) = 2*(hkm1(e+1) - (k-1)*hkm2(e));
end
hk(n+1) = -2*(k-1)*hkm2(n+1);
if k<n
hkm2 = hkm1;
hkm1 = hk;
end
end
end
% this is the function of HG modes in z position.
function [HGBeam,X,Y] = Hermite_Gaussian(N,hx,hy,w0,delta,lamda,z)
[X Y]=meshgrid((-N/2:N/2-1)*delta);
[theta,rad] = cart2pol(X,Y);
k=2*pi/lamda;
zr=pi*w0^2/lamda;
wz=w0*sqrt(1+(z/zr)^2);
qz=z+1i*zr;
q0=1i*zr;
if z==0
rz=Inf;
else
rz=z*(1+(zr/z)^2);
end
AmpLGB=sqrt(2/(2^(hx+hy)*pi*factorial(hx)*factorial(hy)*w0^2)).*(q0/qz).*(-conj(qz)/qz)^((hx+hy)/2).*exp(-(rad.*rad)/(wz)^2).*polyval(HermitePoly(hx),sqrt(2)*X/wz).*polyval(HermitePoly(hy),sqrt(2)*Y/wz);
PsLGB=exp(-1i*(k*(rad.*rad)/(2*rz)+k*z-(hx+hy+1)*atan(z/zr)));
HGBeam=AmpLGB.*PsLGB;
end
Now I plot one example for HG(2,0) as the following (example1):
clc
clear all;
close all;
lambda=809e-9; % optical wavelength
w0=0.025; %optical beam waist 15mm
k=2*pi/lambda; % optical wavenumber
Zr=pi*w0^2/lambda; % Rayleigh range
z0=0; % start position z=0; but careful 0*Inf is undefined, here 0*Inf=NAN
N=1024; % samples/side length at source plane
D1=0.25; % side length [m] at source plane
delta1=D1/N; % grid spacing [m]
x1=-D1/2:delta1:D1/2-delta1; % source plane x and y coordinates
y1=x1;
%% HG modes
HGx=2;
HGy=0;
HGintheory=Hermite_Gaussian(N,HGx,HGy,w0,delta1,lambda,z0);
h7=figure(7);
imagesc(x1,y1,abs(HGintheory).^2);
title(sprintf('z=%d; HG(%d,%d)',z0,HGx,HGy))
xlabel('x (m)'); ylabel('y (m)');
The plot of the light field will be as the following picture in the left side (its intensity):
We can use rot90() function to rotate matrix HGintheory (which is add one line code: HGintheory=rot90(HGintheory);) and then the field will rotate 90 degree (right side of the intensity plot).
Because I want to work with the light field. So the question is how can I rotate the complex matrix HGintheory in
arbitrary angle? For example 45 degree?
Does anyone knows how to rotate a complex matrix with big size? If something is wrong or unclear, please pointing out and Thank you in advance!
You can decompose your complex field into two real fields (amplitude and phase), rotate both with imrotate, and combine them afterwards pixel-wise
Hamp=abs(HGintheory);
Hphase=angle(HGintheory);
RotAngle=45;
HampRot=imrotate(Hamp,RotAngle,'bilinear','crop');
HphaseRot=imrotate(Hphase,RotAngle,'bilinear','crop');
HfullRot=HampRot.*exp(1i*HphaseRot);
figure(1);
imagesc(x1,y1,abs(HGintheory).^2);
figure(2);
imagesc(x1,y1,abs(HfullRot).^2);
You can rotate your initial meshgrid using:
[X,Y] = meshgrid(x1,y1)
xyc = [mean(x1), mean(y1)];
angel = 45;
R = [cosd(angel), -sind(angel); sind(angel), cosd(angel)];
XY = xyc' + R * ([X(:) Y(:)]-xyc)';
XR = reshape(XY(1,:),size(X));
YR = reshape(XY(2,:),size(Y));
and then use those transformed coordinates to plot:
imagesc(XR,YR,IntensityHGin);

Plotting Accelerometer 3 axis value in Matlab

I have two task to do
getting data serially from microcontroller.
plotting the 3 axis value in real time.
For first I used the following code:
s=serial('COM10');
fopen(s);
out=fscanf(s);
while(out~=0)
out=fscanf(s);
disp(out);
end
fclose(s);
now in second part i have to plot there data in real time how can i do it ,m new to matlab i tried the following sample code to plot 3 values but didn't worked out. please help.
x = -50;
y = 10;
z = 20;
while(1)
plot3(x,y,z);
XLABEL('X Axis');
YLABEL('Y Axis');
ZLABEL('Z Axis');
set(gca, 'XColor', 'r', 'YColor', [0 0.5 0.5], 'ZColor', 'y')
x=x+2;
y=y+2;
z=z+2;
end
Change the code, use plot only once:
X=[];Y=[];Z=[];
x=0;y=0;z=0;
figure(1);
myplot=plot3(x,y,z);
while(1)
x=x+1;
y=sin(x);
z=cos(x);
X(end+1)=x;
Y(end+1)=y;
Z(end+1)=z;
set(myplot,'Xdata',X,'YData',Y,'ZData',Z);
drawnow limitrate;
end
If the loop run long enough, don't forget to limit X,Y,Z sizes(for example every 1000 samples delete 500)

How to show image and plot simultaneously in loop

I want to show image and plot in the loop. I want to show image in one figure and plot in other figure. So I try to use my code, but it does not work. Could you help me fix it? Thanks so much
x=0;
x_arr=[]
I=imread('peppers.png');
figure
for i=1:100
if mod(i,10)==0
pause(0.5);
x=i.^2+1;
x_arr=[x_arr x]
%show image
hold on
imshow(I);
hold off
%show plot
pause(0.5);
hold on
plot(y_arr);
hold off
end
end
you can do so by using figure for handeling 2 windows:
x=0;
x_arr=[]
I=imread('peppers.png');
for i=1:100
if mod(i,10)==0
pause(0.5);
x=i.^2+1;
x_arr=[x_arr x];
%show image
figure(1)
imshow(I);
%show plot
pause(0.5);
figure(2)
plot(x_arr);
end
end
or by using subplots to keep it in one window:
x=0; x_arr=[]
I=imread('peppers.png');
figure (1)
for i=1:100
if mod(i,10)==0
pause(0.5);
x=i.^2+1;
x_arr=[x_arr x] %show image
subplot(1,2,1);
imshow(I);
%show plot
pause(0.5);
subplot(1,2,2)
plot(x_arr);
end
end

Creating a point moving along a graph in MATLAB

I am looking to create a simple log(x) graph within MATLAB in which the model shows the point moving along the curve with time.
The overall aim is to have two of these graphs alongside one another and to apply an algorithm to them. I am really unsure where to start here.
I am relatively new at MATLAB coding so any help would be very useful!
Thanks
Luke
Here is a variation on #Jacob's solution. Instead of redrawing everything at each frame (clf) we simply update the point's location:
%# control animation speed
DELAY = 0.01;
numPoints = 600;
%# create data
x = linspace(0,10,numPoints);
y = log(x);
%# plot graph
figure('DoubleBuffer','on') %# no flickering
plot(x,y, 'LineWidth',2), grid on
xlabel('x'), ylabel('y'), title('y = log(x)')
%# create moving point + coords text
hLine = line('XData',x(1), 'YData',y(1), 'Color','r', ...
'Marker','o', 'MarkerSize',6, 'LineWidth',2);
hTxt = text(x(1), y(1), sprintf('(%.3f,%.3f)',x(1),y(1)), ...
'Color',[0.2 0.2 0.2], 'FontSize',8, ...
'HorizontalAlignment','left', 'VerticalAlignment','top');
%# infinite loop
i = 1; %# index
while true
%# update point & text
set(hLine, 'XData',x(i), 'YData',y(i))
set(hTxt, 'Position',[x(i) y(i)], ...
'String',sprintf('(%.3f,%.3f)',[x(i) y(i)]))
drawnow %# force refresh
%#pause(DELAY) %# slow down animation
i = rem(i+1,numPoints)+1; %# circular increment
if ~ishandle(hLine), break; end %# in case you close the figure
end
A simple solution is:
x = 1:100;
y = log(x);
DELAY = 0.05;
for i = 1:numel(x)
clf;
plot(x,y);
hold on;
plot(x(i),y(i),'r*');
pause(DELAY);
end
You may want to have a look at the COMET function, which will make an animation of the curve.
For example (using the same numbers as #Jacob)
x = 1:100;
y = log(x);
comet(x,y)
If you want to show the point moving on the line (not 'drawing' it), you simply plot the line before
x = 1:100;
y = log(x);
plot(x,y,'r')
hold on %# to keep the previous plot
comet(x,y,0) %# 0 hides the green tail
a little more complex solution along the same lines as #Jacob. Here I add some optimization using handle graphics and a MATLAB movie object for playback.
x=1:100;
y=log(x);
figure
plot(x,y);
hold on; % hold on so that the figure is not cleared
h=plot(x(1),y(1),'r*'); % plot the first point
DELAY=.05;
for i=1:length(x)
set(h,'xdata',x(i),'ydata',y(i)); % move the point using set
% to change the cooridinates.
M(i)=getframe(gcf);
pause(DELAY)
end
%% Play the movie back
% create figure and axes for playback
figure
hh=axes;
set(hh,'units','normalized','pos',[0 0 1 1]);
axis off
movie(M) % play the movie created in the first part
solution can be this way
x = .01:.01:3;
comet(x,log(x))