📄 filtdes.m
字号:
for i=1:length(open_axes)
xlim = get(open_axes(i),'xlim');
xlim = .5*[3 -1]*xlim' + [0 diff(xlim)*2];
xlimbound = ud.Objects.fdax(i).xlimbound;
if ~isstr(xlimbound)
xlim = [max(xlim(1),xlimbound(1)) min(xlim(2),xlimbound(2))];
end
set(open_axes(i),'xlim',xlim)
end
case 'passband'
if isempty(ud.Objects.fdax)
return
end
open_axes = ud.Objects.fdax.h;
if iscell(open_axes)
open_axes = [open_axes{:}];
end
for i=1:length(open_axes)
xlimpassband = ud.Objects.fdax(i).xlimpassband;
if ~isstr(xlimpassband)
set(open_axes(i),'xlim',xlimpassband)
end
ylimpassband = ud.Objects.fdax(i).ylimpassband;
if ~isstr(ylimpassband)
set(open_axes(i),'ylim',ylimpassband)
end
end
end
%------------------------------------------------------------------------
%filtdes('help')
% callback of help btn.
case 'help'
fig = gcf;
ud = get(fig,'userdata');
if ud.pointer ~= 2 % if not in help mode
% enter help mode
h1 = ud.Objects.fdspec.h;
if length(h1)~=1
h1 = [h1{:}];
end
h2 = ud.Objects.fdmeas.h;
if length(h2)~=1
h2 = [h2{:}];
end
saveEnableControls = [ud.ht.apply
ud.ht.revert
ud.ht.filtMenu
ud.ht.autoDesign
ud.ht.FsEdit
ud.ht.modulePopup
ud.ht.overlay
h1(:)
h2(:)];
ax1 = ud.Objects.fdax.h;
if length(ax1)~=1
ax1 = [ax1{:}];
end
ax = [ud.toolbar.toolbar; ax1(:)];
titleStr = 'Filter Designer Help';
helpFcn = 'fdhelpstr';
spthelp('enter',fig,saveEnableControls,ax,titleStr,helpFcn,1)
else
spthelp('exit')
end
% -------------------------------------------------------------------------
% struc = filtdes('filt')
% retrieve filter structure from tool
case 'filt'
shh = get(0,'showhiddenhandles');
set(0,'showhiddenhandles','on');
% first, find the tool
fig = findobj('type','figure','tag','filtdes');
if isempty(fig)
set(0,'showhiddenhandles',shh)
error('No Filter Design Tool is open - can''t get filter.')
end
ud=get(fig,'Userdata');
if nargout >= 1, varargout{1} = ud.filt; end
set(0,'showhiddenhandles',shh)
% -------------------------------------------------------------------------
% [b,a,Fs] = filtdes('getfilt')
% retrieve filter coefficients from tool
case 'getfilt'
shh = get(0,'showhiddenhandles');
set(0,'showhiddenhandles','on');
% first, find the tool
fig = findobj('type','figure','tag','filtdes');
if isempty(fig)
set(0,'showhiddenhandles',shh)
error('No Filter Design Tool is open - can''t get coefficients.')
end
ud=get(fig,'Userdata');
Fs = ud.filt.Fs; % sampling frequency
b = ud.filt.tf.num;
a = ud.filt.tf.den;
if nargout >= 1, varargout{1} = b; end
if nargout >= 2, varargout{2} = a; end
if nargout >= 3, varargout{3} = Fs; end
set(0,'showhiddenhandles',shh)
%------------------------------------------------------------------------
% errstr = filtdes('setprefs',panelName,p)
% Set preferences for the panel with name panelName
% Inputs:
% panelName - string; must be 'filtdes'
% (see sptprefp for definitions)
% p - preference structure for this panel
% p has fields:
% .nfft - string - number of points in frequency response
% between 0 and Fs
% .grid - can be 0 (grid off) or 1 (grid on), applies to
% all fdax objects (both xgrid and ygrid)
% .AutoDesignInit - initial value for AutoDesign flag
% .zoomFlag - stay in zoom mode after zoom
case 'setprefs'
errstr = '';
panelName = varargin{2};
p = varargin{3};
arbitrary_obj = {'arb' 'obj'};
nfft = evalin('base',p.nfft,'arbitrary_obj');
if isequal(nfft,arbitrary_obj)
errstr = 'Sorry, the FFT Length you entered could not be evaluated';
elseif isempty(nfft) | (round(nfft)~=nfft | nfft<=0 | ~isreal(nfft))
errstr = ['The FFT Length must be a positive integer.'];
end
varargout{1} = errstr;
if ~isempty(errstr)
return
end
fig = findobj(allchild(0),'tag','filtdes');
if ~isempty(fig)
ud = get(fig,'userdata');
for i=1:length(ud.Objects.fdax)
if p.grid
set(ud.Objects.fdax(i),'xgrid','on','ygrid','on')
else
set(ud.Objects.fdax(i),'xgrid','off','ygrid','off')
end
end
old_nfft = ud.prefs.nfft;
ud.prefs.nfft = nfft;
ud.prefs.grid = p.grid;
ud.prefs.tool.zoompersist = p.zoomFlag;
ud.prefs.AutoDesignInit = p.AutoDesignInit;
set(fig,'userdata',ud)
if ud.prefs.nfft ~= old_nfft
% redesign filter
filtdes('apply')
end
end
%------------------------------------------------------------------------
%gridVal = filtdes('grid',fig)
% returns 'on' or 'off' depending on value of preferences
% for grids.
% Input: fig - handle of filtdes, optional; found with findobj if
% not passed
case 'grid'
if nargin > 1
fig = varargin{2};
else
fig = findobj(allchild(0),'tag','filtdes');
end
ud = get(fig,'userdata');
if ud.prefs.grid
varargout{1} = 'on';
else
varargout{1} = 'off';
end
%------------------------------------------------------------------------
%nfft = filtdes('nfft',fig)
% returns nfft, frequency response length
% Input: fig - handle of filtdes, optional; found with findobj if
% not passed
case 'nfft'
if nargin > 1
fig = varargin{2};
else
fig = findobj(allchild(0),'tag','filtdes');
end
ud = get(fig,'userdata');
varargout{1} = ud.prefs.nfft;
%------------------------------------------------------------------------
%filtdes('resize')
% filtdes portion of filtdes figure's resizefcn.
case 'resize'
fig = findobj('tag','filtdes');
ud = get(fig,'userdata');
fp = get(fig,'position');
minsize = [516 450]; % minimum [width height], in pixels
if fp(3)<minsize(1) | fp(4)<minsize(2)
% figure is too small - resize to minimum size
w = max(minsize(1),fp(3));
h = max(minsize(2),fp(4));
fp = [fp(1) fp(2)+fp(4)-h w h];
set(fig,'position',fp)
end
switch computer
case 'PCWIN'
popTweak = [0 3 0 0];
editTweak = [0 0 0 3];
txtTweak = [0 0 0 0];
case 'MAC2'
popTweak = [0 0 0 0];
editTweak = [0 0 0 0];
txtTweak = [0 0 0 0];
otherwise
popTweak = [0 -1 0 2];
editTweak = [0 0 0 0];
txtTweak = [0 -5 0 6];
end
specWidth = 150;
sz = ud.sz;
toolbar_ht = sz.ih;
sfp = [0 0 specWidth fp(4)-2*toolbar_ht];
mfp = [fp(3)-specWidth 0 specWidth fp(4)-2*toolbar_ht];
afp = [specWidth 0 fp(3)-2*specWidth fp(4)-2*toolbar_ht];
tb2fp = [0 sfp(2)+sfp(4) fp(3) toolbar_ht]; % toolbar2 frame position
% tb2fp = [0 sfp(2)+sfp(4) fp(3) sz.uh+sz.fus*2]; % toolbar2 frame position
% position frames, spec & meas labels, and revert and apply
set(ud.ht.specFrame,'position',sfp)
set(ud.ht.axFrame,'position',afp)
set(ud.ht.measFrame,'position',mfp);
set(ud.ht.tb2Frame,'position',tb2fp);
set(ud.ht.specLabel,'position',[sfp(1)+2 sfp(2)+sfp(4)-(sz.uh+sz.fus) ...
sfp(3)-4 sz.uh]);
set(ud.ht.measLabel,'position',[mfp(1)+2 mfp(2)+mfp(4)-(sz.uh+sz.fus) ...
mfp(3)-4 sz.uh]);
set(ud.ht.revert,'position',[sfp(1)+2 sfp(2)+2 sfp(3)/2-3 sz.uh]);
set(ud.ht.apply,'position',[sfp(1)+4+(sfp(3)/2-3) sfp(2)+2 sfp(3)/2-3 sz.uh]);
%set(ud.ht.toolTip,'position',[afp(1) 0 afp(3) 22]);
% position filter selection popup and its label
set(ud.ht.filtMenuLabel,'position',...
[sz.fus fp(4)-(sz.ih-sz.uh-sz.lh)/3-sz.lh ...
120-2*sz.fus sz.lh]+txtTweak)
set(ud.ht.filtMenu,'position',...
[sz.fus+2*sz.fus fp(4)-2*(sz.ih-sz.uh-sz.lh)/3-sz.lh-sz.uh ...
120-4*sz.fus sz.uh]+popTweak)
% position items in 2nd toolbar:
set(ud.ht.autoDesign,'position',...
[tb2fp(1)+sz.fus tb2fp(2)+(tb2fp(4)-sz.uh)/2 sz.bw sz.uh]+popTweak)
algLW = fp(3)-(5*sz.fus+sz.bw+2*sz.lw); % algorithm label width
set(ud.ht.moduleLabel,'position',...
[tb2fp(1)+2*sz.fus+sz.bw ...
tb2fp(2)+tb2fp(4)-(sz.ih-sz.uh-sz.lh)/3-sz.lh ...
algLW sz.lh]+txtTweak)
set(ud.ht.modulePopup,'position',...
[tb2fp(1)+2*sz.fus+sz.bw+2*sz.fus ...
tb2fp(2)+(sz.ih-sz.uh-sz.lh)/3 algLW-2*sz.fus sz.uh]+popTweak)
set(ud.ht.FsLabel,'position',...
[tb2fp(1)+3*sz.fus+sz.bw+algLW ...
tb2fp(2)+tb2fp(4)-(sz.ih-sz.uh-sz.lh)/3-sz.lh sz.lw sz.lh]+txtTweak)
set(ud.ht.FsEdit,'position',...
[tb2fp(1)+3*sz.fus+sz.bw+algLW+2*sz.fus ...
tb2fp(2)+(sz.ih-sz.uh-sz.lh)/3 sz.lw-2*sz.fus sz.uh]+editTweak)
set(ud.ht.overlay,'position',...
[tb2fp(1)+tb2fp(3)-sz.lw-sz.fus tb2fp(2)+(tb2fp(4)-sz.uh)/2 ...
sz.lw sz.uh]+popTweak)
% reposition objects: by simply reassigning their positions, they are
% positioned relative to the frames that contain them
for i = 1:length(ud.Objects.fdspec)
ud.Objects.fdspec(i).position = ud.Objects.fdspec(i).position;
end
for i = 1:length(ud.Objects.fdax)
ud.Objects.fdax(i).position = ud.Objects.fdax(i).position;
end
for i = 1:length(ud.Objects.fdmeas)
ud.Objects.fdmeas(i).position = ud.Objects.fdmeas(i).position;
end
otherwise % evaluate local function
if (nargout == 0)
feval(varargin{:});
else
[varargout{1:nargout}] = feval(varargin{:});
end
end
%------------------------------------------------------------------------
% ... SUBFUNCTIONS BELOW THIS POINT...
function d = segmentDistance(p,xd,yd)
% returns distance from pt to segment from (xd(1),yd(1)) to (xd(2),yd(2))
% This is the distance from the closest point on the segment, which
% is either the perpendicular distance, or the distance from one of the
% end points of the segment.
%
% Assumes p is a row
[xd,ind] = sort(xd);
yd = yd(ind);
if max(isnan(xd))==1 | max(isnan(yd))==1
% Line segment is the 'invisible' part of the specs line (data is set
% to NaNs). Avoid dividing by NaNs; causes warnings on PCWIN.
d = sqrt(sum( (p([1 1],:)' - [xd(:)'; yd(:)']).^2 ));
d = min(d);
elseif diff(xd)==0 % slope is infinite
if p(2)>=min(yd) & p(2)<=max(yd)
d = abs(xd(1)-p(1));
else
d = sqrt(sum( (p([1 1],:)' - [xd(:)'; yd(:)']).^2 ));
d = min(d);
end
elseif diff(yd)==0 % slope is zero
if p(1)>=xd(1) & p(1)<=xd(2)
d = abs(yd(1)-p(2));
else
d = sqrt(sum( (p([1 1],:)' - [xd(:)'; yd(:)']).^2 ));
d = min(d);
end
else
m1 = diff(yd)/diff(xd); % slope of line connecting (xd(1),yd(1)), (xd(2),yd(2))
b1 = yd(1)-xd(1)*m1;
m2 = -1/m1; % slope and y-intercept of perpendicular line
b2 = p(2)-m2*p(1); % which passes through p
% find intersection of two lines
p_int = [m1 -1; m2 -1]\[-b1; -b2];
% is p_int on the line segment?
if (p_int(1) > xd(1)) & (p_int(1) < xd(2))
d = sqrt(sum((p-p_int').^2));
else
d = sqrt(sum( (p([1 1],:)' - [xd(:)'; yd(:)']).^2 ));
d = min(d);
end
end
function [vertexFlag,dist,ind,segdist,segind] = ...
closestpoint(pt,h,xscale,yscale,xd,yd)
% Find distance to closest point on line from pt
% Inputs:
% pt - current point, in axes units
% h - line handle
% xscale - number of pixels per axes x-unit
% yscale - number of pixels per axes y-unit
% xd - line's xdata
% yd - line's ydata
% Outputs:
% vertexFlag == 1 if closest point is a vertex of the line,
% == 0 if closest point is a segment of the line
% dist - distance in pixels from vertex if vertexFlag is 1
% ind - index of vertex if vertexFlag is 1
% segdist - distance in pixels from segment if vertexFlag is 0
% segind - starting index of segment if vertexFlag is 0
xd1 = xd*xscale;
yd1 = yd*yscale;
pt1 = pt.*[xscal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -