How can I remove specific regions of a 2D plot in MATLAB? - matlab

I have a following MATLAB plot, which consists of a rectangular domain with circular holes on it:
I am modeling a flow through that rectangular porous medium. I have plotted streamlines characterizing that flow. However, the streamlines pass through the entire mesh, which means they also pass through the circular holes on the plot. I would like to remove the streamlines from those holes.
Any suggestions on how to do that?
Here is the code I am using to create that plot:
x = linspace(min(X_plot(:,1)), max(X_plot(:,1)), 100);
y = linspace(min(X_plot(:,2)), max(X_plot(:,2)), 100);
[xg, yg] = meshgrid(x, y);
Fx = TriScatteredInterp(X_plot(:,1), X_plot(:,2), qx);
Fy = TriScatteredInterp(X_plot(:,1), X_plot(:,2), qy);
qxg = Fx(xg,yg);
qyg = Fy(xg,yg);
figure(1); hold on;
hl = streamslice(xg, yg, qxg, qyg);
set(hl, 'color', 'b','Linewidth',0.5);
To plot the circles (and the ellipse) on the graph I used:
hold on
P2 = [2,-1.5];
r2=.6;
tt = linspace(0,pi*2);
xx = P2(1) + r2*cos(tt);
yy = P2(2) + r2*sin(tt);
plot(xx,yy,'--','Color',[.7 .7 0])
hold on
P3 = [3,1.5];
r3=1.3;
tt = linspace(0,pi*2);
xx = P3(1) + r3*cos(tt);
yy = P3(2) + r3*sin(tt);
plot(xx,yy,'--','Color',[1 .7 0])
hold on
P5 = [5,-1.5];
r5=.8;
tt = linspace(0,pi*2);
xx = P5(1) + r5*cos(tt);
yy = P5(2) + r5*sin(tt);
plot(xx,yy,'--','Color',[1 .7 0])
hold on
P6 = [6,1.5];
r6=.6;
tt = linspace(0,pi*2);
xx = P6(1) + r6*cos(tt);
yy = P6(2) + r6*sin(tt);
plot(xx,yy,'--','Color',[1 .7 0])
hold on
P4 = [9,0];
r41=.5;
r42=2.4;
tt = linspace(0,pi*2);
xx = P4(1) + r41*cos(tt);
yy = P4(2) + r42*sin(tt);
plot(xx,yy,'--','Color',[.9 .7 0])

Related

How to create MATLAB code for making bilinear coon's surface patch from cubic Bezier curves

I have following data from which I need to create coon's patch. Matrix of polygon vertices given below:
P0u = \[0,0,0; 0.2357,0.2357,0.3333; 1.1785,0.2357,0.3333; 1.4142,0,0\];
P0w = \[1.4142,0,0; 1.1785,0.2357,0.3333; 1.1785,1.1785,0.3333; 1.4142,1.4142,0\];
P1u = \[1.4142,1.4142,0; 1.1785,1.1785,0.3333; 0.2357,1.1785,0.3333; 0,1.4142,0\];
P1w = \[0,1.4142,0; 0.2357,1.1785,0.3333; 0.2357,0.2357,0.3333; 0,0,0\];
What can I try next?
I have prepared partial MATLAB code but do not know how to proceed further. See the below code:
clc
clear
close all
%% Define input parameters
A1 = [0,0,0];
A2 = [0.2357,0.2357,0.3333];
A3 = [1.1785,0.2357,0.3333];
A4 = [1.4142,0,0];
B1 = [1.4142,0,0];
B2 = [1.1785,0.2357,0.3333];
B3 = [1.1785,1.1785,0.3333];
B4 = [1.4142,1.4142,0];
C1 = [1.4142,1.4142,0];
C2 = [1.1785,1.1785,0.3333];
C3 = [0.2357,1.1785,0.3333];
C4 = [0,1.4142,0];
D1 = [0,1.4142,0];
D2 = [0.2357,1.1785,0.3333];
D3 = [0.2357,0.2357,0.3333];
D4 = [0,0,0];
P0u = [A1;A2;A3;A4]; % Creating matrix for polygon vertices
P0w = [B1;B2;B3;B4]; % Creating matrix for polygon vertices
P1u = [C1;C2;C3;C4]; % Creating matrix for polygon vertices
P1w = [D1;D2;D3;D4]; % Creating matrix for polygon vertices
[r1,s1] = size(P0u); % getting size of matrix in terms of rows and columns
[r2,s2] = size(P0w); % getting size of matrix in terms of rows and columns
[r3,s3] = size(P1u); % getting size of matrix in terms of rows and columns
[r4,s4] = size(P1w); % getting size of matrix in terms of rows and columns
n1 = r1-1; % n+1 represents number of vertices of the polygon
n2 = r2-1; % n+1 represents number of vertices of the polygon
n3 = r3-1; % n+1 represents number of vertices of the polygon
n4 = r4-1; % n+1 represents number of vertices of the polygon
np = 20; % represents number of equi-distance points on the bezier curve
t = linspace(0,1,np);
%% Plot polygon
for k1 = 1:n1
figure(1)
plot([P0u(k1,1),P0u(k1+1,1)], [P0u(k1,2),P0u(k1+1,2)], 'r', 'LineWidth', 2)
hold all
grid on
view(45,45)
end
for k2 = 1:n2
plot([P0w(k2,1),P0w(k2+1,1)], [P0w(k2,2),P0w(k2+1,2)], 'r', 'LineWidth', 2)
end
for k3 = 1:n3
plot([P1u(k3,1),P1u(k3+1,1)], [P1u(k3,2),P1u(k3+1,2)], 'r', 'LineWidth', 2)
end
for k4 = 1:n4
plot([P1w(k4,1),P1w(k4+1,1)], [P1w(k4,2),P1w(k4+1,2)], 'r', 'LineWidth', 2)
end
%% Generate the points on the bezier curve
for j1 = 1:np
P1 = [0,0,0];
for i1 = 0:n1
M1(i1+1) = (factorial(n1)/(factorial(i1)*factorial(n1-i1)))*((t(j1))^i1)*((1-t(j1))^(n1-i1));
P1 = P1 + P0u(i1+1,:)*M1(i1+1);
end
Q1(j1,:) = P1;
end
for j2 = 1:np
P2 = [0,0,0];
for i2 = 0:n2
M2(i2+1) = (factorial(n2)/(factorial(i2)*factorial(n2-i2)))*((t(j2))^i2)*((1-t(j2))^(n2-i2));
P2 = P2 + P0w(i2+1,:)*M2(i2+1);
end
Q2(j2,:) = P2;
end
for j3 = 1:np
P3 = [0,0,0];
for i3 = 0:n3
M3(i3+1) = (factorial(n3)/(factorial(i3)*factorial(n3-i3)))*((t(j3))^i3)*((1-t(j3))^(n3-i3));
P3 = P3 + P1u(i3+1,:)*M3(i3+1);
end
Q3(j3,:) = P3;
end
for j4 = 1:np
P4 = [0,0,0];
for i4 = 0:n4
M4(i4+1) = (factorial(n4)/(factorial(i4)*factorial(n4-i4)))*((t(j4))^i4)*((1-t(j4))^(n4-i4));
P4 = P4 + P1w(i4+1,:)*M4(i4+1);
end
Q4(j4,:) = P4;
end
%% Plot the bezier curve from the obtained points
for l1 = 1:np-1
plot([Q1(l1,1),Q1(l1+1,1)],[Q1(l1,2),Q1(l1+1,2)], 'b', 'LineWidth', 2);
end
for l2 = 1:np-1
plot([Q2(l2,1),Q2(l2+1,1)],[Q2(l2,2),Q2(l2+1,2)], 'b', 'LineWidth', 2);
end
for l3 = 1:np-1
plot([Q3(l3,1),Q3(l3+1,1)],[Q3(l3,2),Q3(l3+1,2)], 'b', 'LineWidth', 2);
end
for l4 = 1:np-1
plot([Q4(l4,1),Q4(l4+1,1)],[Q4(l4,2),Q4(l4+1,2)], 'b', 'LineWidth', 2);
end
%% Clearing workspace
clc
clear
close all
%% Defining input parameters
% Defining individual point on polygon
A1 = [0,0,0];
A2 = [0.2357,0.2357,0.3333];
A3 = [1.1785,0.2357,0.3333];
A4 = [1.4142,0,0];
B1 = [1.4142,0,0];
B2 = [1.1785,0.2357,0.3333];
B3 = [1.1785,1.1785,0.3333];
B4 = [1.4142,1.4142,0];
C1 = [1.4142,1.4142,0];
C2 = [1.1785,1.1785,0.3333];
C3 = [0.2357,1.1785,0.3333];
C4 = [0,1.4142,0];
D1 = [0,1.4142,0];
D2 = [0.2357,1.1785,0.3333];
D3 = [0.2357,0.2357,0.3333];
D4 = [0,0,0];
%% Plot polygon
P0u = [A1;A2;A3;A4]; % Creating matrix for polygon vertices
P0w = [B1;B2;B3;B4]; % Creating matrix for polygon vertices
P1u = [C1;C2;C3;C4]; % Creating matrix for polygon vertices
P1w = [D1;D2;D3;D4]; % Creating matrix for polygon vertices
[r,s] = size(P0u); % getting size of matrix in terms of rows and columns
[r,s] = size(P0w); % getting size of matrix in terms of rows and columns
[r,s] = size(P1u); % getting size of matrix in terms of rows and columns
[r,s] = size(P1w); % getting size of matrix in terms of rows and columns
n = r-1; % n+1 represents number of vertices of the polygon
np = 50; % represents number of equi-distance points on the bezier curve
t = linspace(0,1,np);
hold all
grid on
view(45,45)
figure(1)
xlabel('X-Axis')
ylabel('Y-Axis')
zlabel('Z-Axis')
for k = 1:n
plot3([P0u(k,1),P0u(k+1,1)], [P0u(k,2),P0u(k+1,2)], [P0u(k,3),P0u(k+1,3)], 'r', 'LineWidth', 1);
plot3([P0w(k,1),P0w(k+1,1)], [P0w(k,2),P0w(k+1,2)], [P0w(k,3),P0w(k+1,3)], 'r', 'LineWidth', 1);
plot3([P1u(k,1),P1u(k+1,1)], [P1u(k,2),P1u(k+1,2)], [P1u(k,3),P1u(k+1,3)], 'r', 'LineWidth', 1);
plot3([P1w(k,1),P1w(k+1,1)], [P1w(k,2),P1w(k+1,2)], [P1w(k,3),P1w(k+1,3)], 'r', 'LineWidth', 1);
end
%% Generate the points on the bezier curve
for j = 1:np
P1 = [0,0,0];
P2 = [0,0,0];
P3 = [0,0,0];
P4 = [0,0,0];
for i = 0:n
M(i+1) = (factorial(n))/(factorial(i)*factorial(n-i))*((t(j))^i)*((1-t(j))^(n-i));
P1 = P1 + P0u(i+1,:).*M(i+1);
P2 = P2 + P0w(i+1,:).*M(i+1);
P3 = P3 + P1u(i+1,:).*M(i+1);
P4 = P4 + P1w(i+1,:).*M(i+1);
end
Q1(j,:) = P1;
Q2(j,:) = P2;
Q3(j,:) = P3;
Q4(j,:) = P4;
end
Q3 = flipud(Q3);
Q4 = flipud(Q4);
%% Plot the bezier curve from the obtained points
for l = 1:np-1
plot3([Q1(l,1),Q1(l+1,1)],[Q1(l,2),Q1(l+1,2)], [Q1(l,3),Q1(l+1,3)], 'b', 'LineWidth', 1);
plot3([Q2(l,1),Q2(l+1,1)],[Q2(l,2),Q2(l+1,2)], [Q2(l,3),Q2(l+1,3)], 'b', 'LineWidth', 1);
plot3([Q3(l,1),Q3(l+1,1)],[Q3(l,2),Q3(l+1,2)], [Q3(l,3),Q3(l+1,3)], 'b', 'LineWidth', 1);
plot3([Q4(l,1),Q4(l+1,1)],[Q4(l,2),Q4(l+1,2)], [Q4(l,3),Q4(l+1,3)], 'b', 'LineWidth', 1);
end
%% Bilinear surface
npu = 50; % Number of points in u-direction
npw = 50; % Number of points in w-direction
u = linspace(0,1,npu);
w = linspace(0,1,npw);
Px = zeros(npu,npw);
Py = Px;
Pz = Px;
for i = 1:npu
for j = 1:npw
Px(i,j) = Q1(i,1)*(1-w(j)) + Q2(j,1)*(u(i)) + Q3(i,1)*w(j) + Q4(j,1)*(1-u(i)) - Q1(1,1)*(1-u(i))*(1-w(j)) - Q1(end,1)*(u(i))*(1-w(j)) - Q3(1,1)*(1-u(i))*(w(j)) -Q3 (end,1)*u(i)*w(j);
Py(i,j) = Q1(i,2)*(1-w(j)) + Q2(j,2)*(u(i)) + Q3(i,2)*w(j) + Q4(j,2)*(1-u(i)) - Q1(1,2)*(1-u(i))*(1-w(j)) - Q1(end,2)*(u(i))*(1-w(j)) - Q3(1,2)*(1-u(i))*(w(j)) - Q3(end,2)*u(i)*w(j);
Pz(i,j) = Q1(i,3)*(1-w(j)) + Q2(j,3)*(u(i)) + Q3(i,3)*w(j) + Q4(j,3)*(1-u(i)) - Q1(1,3)*(1-u(i))*(1-w(j)) - Q1(end,3)*(u(i))*(1-w(j)) - Q3(1,3)*(1-u(i))*(w(j)) - Q3(end,3)*u(i)*w(j);
end
end
surf(Px,Py,Pz)
xlabel('X-Axis')
ylabel('Y-Axis')
zlabel('Z-Axis')

How to filter high freq signals?

So I have a task to do for university to filter High frequency signals in MATLAB. I wrote code for it but it doesn't filter correctly. This is my code:
A1 = 7;
A2 = 10;
A3 = 2;
f1 = 934;
f2 = 232;
f3 = 844;
th1 = 5*pi/4;
th2 = pi/4;
th3 = 5*pi/8;
M = 21;
T = 0.7823;
T1 = 0.0331;
T2 = 0.08;
fd = 6395;
K = 3;
Td = 1/fd; % diskretizavimo periodas
N = fix(T/Td); %modeliuojamo signalo reiksmiu skaicius
t = (0:N-1)*Td;
y = A1*sin(2*pi*f1*t + th1)+A2*sin(2*pi*f2*t + th2);
df = 1/T;
Nf=fd/df;
frib=(f1+f2)/2;
Wn = frib/fd;
b = fir1(M, Wn, 'high');
N2=Nf/2;
fasis = (0:Nf-1)*df;
filt_y = filter(b,1, y);
FILT_Y = abs(fft(filt_y, Nf));
figure(17)
subplot(2,1,1)
plot(t(1:T1*2/Td),filt_y(1:T1*2/Td));box('off'); axis tight;
set(gca, 'fontsize', 12); title('Filtruotas sinusu sumos signalas')
subplot(2,1,2)
stem(fasis(1:N2),FILT_Y(1:N2),'.');box('off'); axis tight;
set(gca, 'fontsize', 12); title('Filtruoto sinusu sumos signalo spektras')
frib is the cut-off frequency
And these are my diagrams:
Can you please tell me what can I do to make only one visible in the second diagram (near 1000 freq)? I don't know what I could do more
If you see the Fourier components of your signal before and after, you can clearly see how the first main frequency gets hugely reduced:
noFILT_Y = abs(fft(y, Nf));
subplot(2,1,2)
stem(fasis(1:N2),FILT_Y(1:N2),'.');box('off'); axis tight;
subplot(2,1,1)
stem(fasis(1:N2),noFILT_Y(1:N2),'.');box('off'); axis tight;
But if you follow #irreducible's suggestion:
Wn = frib/(fd/2);

Merge line stiles in MATLAB legend

I have two datasets which I want to plot in the same figure, e.g. two cosine and two sine plots which just differ in the amplitude:
x = -pi:pi/20:pi;
hold all;
amplitude = 1;
plot(x,amplitude*cos(x),'-');
plot(x,amplitude*sin(x),'-');
ax = gca;
ax.ColorOrderIndex = 1;
amplitude=3;
plot(x,amplitude*cos(x),'.');
plot(x,amplitude*sin(x),'.');
legend('1*cos(x)','1*sin(x)', '2*cos(x)','2*sin(x)');
hold off;
I want to "compress" the legend so that the two line stiles (normal line and dotted line) are "merged" and appear next to the same textual entry in the legend, such as:
How can I achieve this in MATLAB? I am currently using R2015b.
This is the closest I have got having a quick look with r2015b:
%%
f = figure;
ax = axes;
x = -pi:pi/20:pi;
hold all;
amplitude = 1;
c1 = plot(x,amplitude*cos(x),'-', 'DisplayName', 'cos(x)');
s1 = plot(x,amplitude*sin(x),'-', 'DisplayName', 'sin(x)');
ax.ColorOrderIndex = 1;
amplitude=3;
c2 = plot(x,amplitude*cos(x),'.', 'DisplayName', ' ');
s2 = plot(x,amplitude*sin(x),'.', 'DisplayName', ' ');
lg = legend([c1 c2 s1 s2]);
hold off;
Manipulating legends was easier pre HG2 - so using an older version of Matlab (r2013a) I get:
%%
f = figure;
ax = handle(axes);
x = -pi:pi/20:pi;
hold all;
amplitude = 1;
c1 = plot(x,amplitude*cos(x),'r-', 'DisplayName', 'cos(x)');
s1 = plot(x,amplitude*sin(x),'b-', 'DisplayName', 'sin(x)');
amplitude=3;
c2 = plot(x,amplitude*cos(x),'r.', 'DisplayName', ' ');
s2 = plot(x,amplitude*sin(x),'b.', 'DisplayName', ' ');
lg = handle(legend([c1 c2 s1 s2]));
hold off;
% You need to find which of the children on the legend is
% each of the plots:
c1 = handle(lg.Children(1));
c1.YData = 0.3;
s1 = handle(lg.Children(7));
s1.YData = 0.75;

In matlab, how to use k means to make 30 clusters with circle around each cluster and mark the center?

In matlab, if I have a code which draws a circle and generates 100 random points inside it. I want to use k means to cluster these 100 points into 30 clusters with a circle around each cluster to differentiate between the clusters and i want to mark the center if each cluster.this is the code of the circle and the 100 random points inside it . Any help please ?
%// Set parameters
R =250; %// radius
C = [0 0]; %// center [x y]
N = 100; %// number of points inside circle
%// generate circle boundary
t = linspace(0, 2*pi,100);
x = R*cos(t) + C(1);
y = R*sin(t) + C(2);
%// generate random points inside it
th = 2*pi*rand(N,1);
r = R*randnlimit(0, 1, 0.5, 1, [N 1]);
xR = r.*cos(th) + C(1);
yR = r.*sin(th) + C(2);
%// Plot everything
figure(1), clf, hold on
% subplot(1,N0,1);
plot(x,y,'b');
hold on
text(0,0,'C')
plot(xR,yR,'p')
axis equal
zR=cell(N,1);
for i=1:N
zR{i,1}= [xR(i) yR(i)];
end
m=cell2mat(zR);
function clusterCircle()
%// Set parameters
R = 250; %// radius
C = [0 0]; %// center [x y]
N = 100; %// number of points inside circle
k = 30; %// number of clusters
%// generate circle boundary
t = linspace(0, 2*pi, 100);
x = R*cos(t) + C(1);
y = R*sin(t) + C(2);
%// generate random points inside it
th = 2*pi*rand(N,1);
r = R*randnlimit(0, 1, 0.5, 1, [N 1]);
xR = r.*cos(th) + C(1);
yR = r.*sin(th) + C(2);
%// some simple k-means:
% initial centroids:
% -> use different method, if k > N
% -> can be done more reasonable (e.g. run k-Means for different
% seeds, select seeds equidistant, etc.)
xC = xR(1:k)';
yC = yR(1:k)';
% run:
clusters = zeros(N,1);
clusters_old = ones(N,1);
while sum((clusters - clusters_old).^2) > 0
clusters_old = clusters;
[~,clusters] = min((bsxfun(#minus,xR,xC)).^2 + ...
(bsxfun(#minus,yR,yC)).^2 , [] , 2);
for kIdx = 1:k
xC(kIdx) = mean(xR(clusters==kIdx));
yC(kIdx) = mean(yR(clusters==kIdx));
end
end
%// Plot everything
figure(1);
clf;
hold on;
% -> plot circle and center
text(C(1),C(2),'C');
plot(x,y,'k');
% -> plot clusters
co = hsv(k);
for kIdx = 1:k
% plot cluster points
plot(xR(clusters==kIdx),yR(clusters==kIdx),'p','Color',co(kIdx,:));
% plot cluster circle
maxR = sqrt(max((xR(clusters==kIdx)-xC(kIdx)).^2 + ...
(yR(clusters==kIdx)-yC(kIdx)).^2));
x = maxR*cos(t) + xC(kIdx);
y = maxR*sin(t) + yC(kIdx);
plot(x,y,'Color',co(kIdx,:));
% plot cluster center
text(xC(kIdx),yC(kIdx),num2str(kIdx));
end
axis equal
end
%// creates random numbers, not optimized!
function rn = randnlimit(a,b,mu,sigma,sz)
rn = zeros(sz);
for idx = 1:prod(sz)
searchOn = true;
while searchOn
rn_loc = randn(1) * sigma + mu;
if rn_loc >= a && rn_loc <= b
searchOn = false;
end
end
rn(idx) = rn_loc;
end
end

plottnig lines on a 3d surface matlab

I need to plot lines on a 3d surface in matlab. I wrote two scripts one to plot the surface and one to plot the lines on the surface.
script1
function figHandle = plotFunction(funchandle, a , b)
x_vec = -a:.1:a;
y_vec = -b:.1:b;
figHandle = figure();
[X,Y] = meshgrid(x_vec, y_vec);
Z = [];
z_temp = [];
for i = x_vec
for j = y_vec
z_temp =[z_temp; funchandle([i; j])];
end;
Z = [Z, z_temp];
z_temp = [];
end;
h = surf(X,Y,Z);
set(h, 'edgecolor', 'none');
%colormap gray;
colorbar;
view(0,90);
end
script2
function plotStep(figHandle,funcHandle, P1, P2)
figure(figHandle);
hold on;
plot3(P1(1), P1(2), funcHandle([P1(1);P1(2)]), 'r*');
if ~isequal(P1,P2)
Z = [];
X = [];
Y = [];
d = [P2(1)-P1(1), P2(2) - P1(2)];
if (P1(1) < P2(1))
X = P1(1):0.0001:P2(1);
if (P1(2) ~= P2(2))
Y = X.*(d(2)/d(1))+(P1(2)-(d(2)/d(1))*P1(1));
else
for i = X
Y = [Y, P1(2)];
end
end
elseif P1(1) > P2(1)
X = P1(1):-0.0001:P2(1);
if (P1(2) ~= P2(2))
Y = X.*(d(2)/d(1))+(P1(2)-(d(2)/d(1))*P1(1));
else
for i = X
Y = [Y, P1(2)];
end
end
else
if P1(2) < P2(2)
Y = P1(2):0.0001:P2(2);
for i = Y
X = [X, P1(1)];
end
else
Y = P1(2):-0.0001:P2(2);
for i = Y
X = [X, P1(1)];
end
end
end
for i = 1:length(X)
Z = [Z;funcHandle([X(i);Y(i)])];
end
plot3(X, Y, Z, 'r', 'LineWidth', 2);
end
My problem is no matter how close too each other I make the points which form the line after zooming in on the line it does not seem to be continuous.
The simplest way to fix this is to raise the line a little bit off the surface,
plot3(X, Y, Z+1, 'r', 'LineWidth', 2);
but you may have to experiment with the offset. It can sometimes help to make the line a little wider, and to try the different renderers as well.