-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathplot_2D_Pattern_polar_dB.m
212 lines (179 loc) · 6.86 KB
/
plot_2D_Pattern_polar_dB.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
function plot_2D_Pattern_polar_dB(angdeg, rdB, rangedB, stepdB, stepdeg, noLeg)
% FUNCTION plot_2D_Pattern_polar_dB(phideg, rdB, rangedB, stepdB, stepdeg, noLeg)
%
% Makes 2D polar plot of angle-vs-r in logarithmic scale (for r).
% It plots on the existing figure/axis, or creates a new one.
%
% Special settings are applied when plotting LVDAM-ANT patterns,
% so that the figure plot matches the software GUI plot
%
% === Inputs ===
% * phideg = polar angles in [0,360] deg. Plots for [0,180] are mirrored.
% * rdB = radial distance in dB(log) scale, e.g., rdB=10*log10(r)
% * rangedB = [min,max] dB range for the plot, default is [-30 +10]dB
% * stepdB = dB step for the plot markings, default is 10 dB
% * stepdeg = deg step for the plot markings, default is 30 deg
% * noLeg = boolean, disables dB marks on the right, default is 0
%
% MIT License | Copyright (c) 2022 Alexandros Pitilakis, Thessaloniki/Greece
% Test inputs
if nargin == 0
clc; close all; clear all;
theta = linspace(eps,pi,100);
kLs = 2*pi*[ 0.001 0.5 1 1.5 ];
r = NaN*zeros(length(kLs),length(theta));
for k = 1:length(kLs)
kL = kLs(k);
F = ( ( cos( kL/2*cos(theta) ) - cos(kL/2) )./ sin(theta) ).^2;
r(k,:) = 2*F / trapz( theta, F.*sin(theta) );
end
rdB = 10*log10( r );
angdeg = theta*180/pi;
end
% -------------------------------------------------------------------------
% Preliminary operations
% -------------------------------------------------------------------------
% Input argument check
if nargin == 1
warning('myApp:argChk', 'Not enough input arguments.');
help polar_dB;
return;
end
% Default inputs
if nargin < 6, noLeg = 0; end
if nargin < 5, stepdeg = 30; end
if nargin < 4, stepdB = 10; end
if nargin < 3, rangedB = [-30 +10]; end;
% Some more checks:
if length(angdeg) ~= length(rdB) % Multiple rad-pat plots:
error( ' ## polar_dB:ERROR: rdB and phideg must be equal length!' )
end
if diff(rangedB) < 0 % error in range dB
error( ' ## polar_dB:ERROR: rangedB should be [min_dB max_dB]!' );
end
if max(rdB(:)) > rangedB(2) % warning for dB-range
disp( ' ## polar_dB:Warning: max rdB of curve(s) exceed(s) range!' );
end
if any( imag(rdB)~=0 ), % complex rdB
error( ' ## polar_dB:ERROR: rdB complex? Real inputs only!');
end
% Number of "rays" for angle marking
rays = 360/stepdeg;
% Arrange phideg and rdB row-wise
angdeg = angdeg(:)';
if size(rdB,1) > size(rdB,2)
rdB = rdB';
end
% LV rad-pats special settings
try
LVspecial = min(size(rdB))==2 && all(angdeg==0:1:359);
catch
LVspecial = 0;
end
if LVspecial
rangedB = [-30 0];
stepdB = 5;
rdB = rdB(:,[1:end,1]);
angdeg = [angdeg,360];
end
% -------------------------------------------------------------------------
% Prepare polar plot area:
% -------------------------------------------------------------------------
% White circlular-board on which RadPat will be printed
if LVspecial==0
figure;
end
phi0 = linspace(0,360,100);
R0 = 1;
x0 = R0*sind(phi0);
y0 = R0*cosd(phi0);
patch('xdata',x0,'ydata',y0, 'edgecolor','black','facecolor','w');
hold on
% -------------------------------------------------------------------------
% Scale & Plot the Rad-Pat
% -------------------------------------------------------------------------
% Colors for the curves, if multiple are to be plotted simultaneously
if LVspecial % E and H planes only
colspace = [1 0 0; 0 0 1];
elseif size(rdB,1) <= 4
colspace = [0 0 0; 1 0 0; 0 0.5 0;0 0 1];
else
colspace = jet( size(rdB,1) );
end
% Crop rdB to min/max to fit in plot, and scale it to [0->1] for plot
rdBcr = rdB;
rdBcr( rdB >= rangedB(2) ) = rangedB(2); % crop to max
rdBcr( rdB <= rangedB(1) ) = rangedB(1); % crop to min
rdBsc = 1 + (rdBcr-rangedB(2)) / diff(rangedB); % scale to [0...1]
% Plot all the curves
for rp = 1 : min( size(rdB) )
x = rdBsc(rp,:) .* cosd(angdeg);
y = rdBsc(rp,:) .* sind(angdeg) * (-1)^LVspecial;
hp(rp) = plot( y, x,'LineStyle','-','color',colspace(rp,:),'LineWidth', 2);
% For Theta-plots (0...180 deg): mirror along vertical axis
if max(angdeg) <= 180
plot( -y, x,'LineStyle',':','color',colspace(rp,:),'LineWidth', 1)
end
end
% Legend for the rdB plots
if LVspecial
legend( hp , {'E','H'} );
elseif min( size(rdB) ) > 1
legend( hp , num2str( (1 : min( size(rdB) ))' ) );
end
% -------------------------------------------------------------------------
% Plot "cosmetics": iso-dB cicles and phi-rays
% -------------------------------------------------------------------------
% Fixed radial (dB) distance circles
c_log = rangedB(1):stepdB:rangedB(2);
c = (c_log-rangedB(2))/diff(rangedB);
for k = 2 : length(c_log)-1 % dont do the outmost (it's there) and inmost
plot(x0*c(k), y0*c(k),'LineStyle',':','color','black');
end
% Markers/labels for the iso-radial (dB) distance circles
% place on the right side
if noLeg == false
for k = 1 : length(c_log)
dBval = c_log(length(c_log)-k+1);
if k==1
text(1.3,+c(k), sprintf( '\\bf{%+2.0f dB}' , rangedB(2) ),...
'horizontalalignment', 'left', 'verticalalignment', 'middle'); %,'fontsize', 13
text(1.3,-c(k), sprintf( '\\bf{%+2.0f dB}' , rangedB(2) ),...
'horizontalalignment', 'left', 'verticalalignment', 'middle'); %,'fontsize', 13
elseif k == length(c_log)
text(1.3,+c(k), sprintf( '\\bf{%+2.0f dB}' , dBval ),...
'horizontalalignment', 'left', 'verticalalignment', 'middle'); %,'fontsize', 13
else
text(1.3,+c(k), sprintf('%+2.0f dB',dBval),...
'horizontalalignment', 'left', 'verticalalignment', 'middle'); %,'fontsize', 13
text(1.3,-c(k), sprintf('%+2.0f dB',dBval),...
'horizontalalignment', 'left', 'verticalalignment', 'middle'); %,'fontsize', 13
end
end
end
% Rays -- Indicating the angles
phi_s=linspace(0,2*pi,rays+1);
x_s = sin(phi_s);
y_s = cos(phi_s);
% Rays Labels -- For theta (0...180 deg), ray labels are mirrored
if max(angdeg) <= 180
if mod(rays,2)~=0
error( 'Only works for even number of "rays!"' );
end
phi_s_label = phi_s( [1:(rays/2+1),(rays/2):-1:1] );
else
phi_s_label = phi_s;
end
% Rays -- Plot 'em and label them
for k=1:rays
% Lines
line([x_s(k)/diff(rangedB)*stepdB,x_s(k)],...
[y_s(k)/diff(rangedB)*stepdB,y_s(k)],'LineStyle',':','color','black');
% Labels
text(1.1*x_s(k)*(-1)^LVspecial,1.1*y_s(k),...
sprintf('%.3g^o',phi_s_label(k)/pi*180),...
'horizontalalignment', 'center', 'verticalalignment', 'middle'); %,'fontsize', 15
end
% Final touches
axis square;
axis off