Filling a region between parametric curves?

5 views (last 30 days)
Jonathan Bessette on 7 Apr 2020
Commented: Ameer Hamza on 7 Apr 2020
Hi! I am trying to fill a region between parametric curves, defined by the following code (in a zgrid):
figure; zgrid; hold on;
Ts = .1; wn = [.4*pi/Ts .6*pi/Ts]; FillColor = 'r';
wn_lb = wn(1); wn_ub = wn(2);
% Values of zeta that correspond to start and end of wn curves:
zeta = linspace(0,1);
% Create vector of complex numbers to plot:
mag_lb = exp(-zeta.*wn_lb*Ts);
ang_lb = sqrt(1-zeta.^2).*wn_lb*Ts;
z_lb = mag_lb.*exp(ang_lb*1j);
mag_ub = exp(-zeta.*wn_ub*Ts);
ang_ub = sqrt(1-zeta.^2).*wn_ub*Ts;
z_ub = mag_ub.*exp(ang_ub*1j);
% Create unit circle arc for appropriate shading:
theta_lb = linspace(angle(conj(z_lb(1))),angle(z_lb(1)));
unit_circle_lb = cos(theta_lb) + sin(theta_lb)*1j;
theta_ub = linspace(angle(conj(z_ub(1))),angle(z_ub(1)));
unit_circle_ub = cos(theta_ub) + sin(theta_ub)*1j;
theta = [linspace(angle(conj(z_ub(1))),angle(conj(z_lb(1)))) linspace(angle(z_lb(1)),angle(z_ub(1)))];
unit_circle = cos(theta) + sin(theta)*1j;
% This is a plot of the region I want to get!
scatter([real(z_ub) flip(real(z_ub)) real(unit_circle) real(z_lb) flip(real(z_lb))],...
[imag(z_ub) flip(-imag(z_ub)) imag(unit_circle) imag(z_lb) flip(-imag(z_lb))])
% This is all I've gotten so far... :(
hold off; figure;
fill([real(z_ub),flip(real(z_ub)),(real(unit_circle)),real(z_lb),flip(real(z_lb)),real(unit_circle)], ...
[imag(z_ub),flip(-imag(z_ub)),(imag(unit_circle)),imag(z_lb),flip(-imag(z_lb)),imag(unit_circle)],...
FillColor,'FaceAlpha',.3);
zgrid
However, I can't seem to figure out how to fill the center region of figure 1. Thus far, figure 2 is the best I've gotten to using fill.
(Perhaps using patch?)
Thanks so much!

1 Comment

Jonathan Bessette on 7 Apr 2020
figure; patch([real(z_ub) flip(real(z_ub)) real(unit_circle) real(z_lb) flip(real(z_lb))],...
[imag(z_ub) flip(-imag(z_ub)) imag(unit_circle) imag(z_lb) flip(-imag(z_lb))],'r')
I tried this method, but I can't seem to get the order of the verticies correct.

Ameer Hamza on 7 Apr 2020
The actual issue is the order of the point. The patch function fails because the points are not distributed as a closed-loop. The following uses a very simple way to order the vertices and then call the patch function.
figure; zgrid; hold on;
Ts = .1; wn = [.4*pi/Ts .6*pi/Ts]; FillColor = 'r';
wn_lb = wn(1); wn_ub = wn(2);
% Values of zeta that correspond to start and end of wn curves:
zeta = linspace(0,1);
% Create vector of complex numbers to plot:
mag_lb = exp(-zeta.*wn_lb*Ts);
ang_lb = sqrt(1-zeta.^2).*wn_lb*Ts;
z_lb = mag_lb.*exp(ang_lb*1j);
mag_ub = exp(-zeta.*wn_ub*Ts);
ang_ub = sqrt(1-zeta.^2).*wn_ub*Ts;
z_ub = mag_ub.*exp(ang_ub*1j);
% Create unit circle arc for appropriate shading:
theta_lb = linspace(angle(conj(z_lb(1))),angle(z_lb(1)));
unit_circle_lb = cos(theta_lb) + sin(theta_lb)*1j;
theta_ub = linspace(angle(conj(z_ub(1))),angle(z_ub(1)));
unit_circle_ub = cos(theta_ub) + sin(theta_ub)*1j;
theta = [linspace(angle(conj(z_ub(1))),angle(conj(z_lb(1)))) linspace(angle(z_lb(1)),angle(z_ub(1)))];
unit_circle = cos(theta) + sin(theta)*1j;
% This is a plot of the region I want to get!
scatter([real(z_ub) flip(real(z_ub)) real(unit_circle) real(z_lb) flip(real(z_lb))],...
[imag(z_ub) flip(-imag(z_ub)) imag(unit_circle) imag(z_lb) flip(-imag(z_lb))])
% ordering the vertices
x = [real(z_ub) flip(real(z_ub)) real(unit_circle) real(z_lb) flip(real(z_lb))];
y = [imag(z_ub) flip(-imag(z_ub)) imag(unit_circle) imag(z_lb) flip(-imag(z_lb))];
X_original = [x' y'];
X_ordered = zeros(size(X_original));
X_ordered(1,:) = X_original(1,:);
x_temp = X_original(1,:);
X_original(1,:) = [];
count = 2;
while ~isempty(X_original)
[~,idx] = min(pdist2(X_original, x_temp));
X_ordered(count,:) = X_original(idx, :);
x_temp = X_original(idx, :);
X_original(idx, :) = [];
count = count + 1;
end
hold off; figure;
p = patch(X_ordered(:,1), X_ordered(:,2), 'r');
p.FaceAlpha = 0.2;
p.EdgeColor = 'none';
zgrid

Jonathan Bessette on 7 Apr 2020
Thank you so much! This works perfectly, and is applicable to many other cases!!
Ameer Hamza on 7 Apr 2020

darova on 7 Apr 2020
Try this to detect which values in a wrong order
% This is a plot of the region I want to get!
X = [real(z_ub) flip(real(z_ub)) real(unit_circle) real(z_lb) flip(real(z_lb))];
Y = [imag(z_ub) flip(-imag(z_ub)) imag(unit_circle) imag(z_lb) flip(-imag(z_lb))];
for i = 1:10:length(X)-11
plot(X(i:i+10),Y(i:i+10),'linewidth',2)
pause(0.1)
end

1 Comment

Jonathan Bessette on 7 Apr 2020
Thanks for your input! Ameer Hamza gave a detailed explanation, incorporating the idea (which you mentioned) of properly ordering points before using the "patch" function.