splinetool.m
来自「演示matlab曲线拟和与插直的基本方法」· M 代码 · 共 1,585 行 · 第 1/5 页
M
1,585 行
function splinetool(x,y)
%SPLINETOOL Spline approximation experimentation tool (GUI).
%
% SPLINETOOL prompts you for some data sites and data values to fit and
% lets you do this in various ways.
% One of the choices is to provide your own data, in which case both
% the sites and values can be expressions that evaluate to vectors required
% to be of the same length.
% You can also specify the values by providing the name of a function whose
% values at the sites are to be used as data values.
% You can also provide the name of an M-file (like 'titanium') whose
% two-argument output provides numerical values for sites and values.
% In any case, there must be at least two distinct sites.
% The other choices provide specific sample sites and values to illustrate
% various aspects of the GUI.
%
% SPLINETOOL(X,Y) uses the input data sites X and data values Y, and these
% must be numerical vectors of the same length > 1. The data sites need not
% be distinct nor ordered, but there must be at least two distinct sites.
%
% Example:
% x = linspace(1,pi,101); y = cos(x)+(rand(size(x))-.5)/10;
% splinetool(x,y)
% might start an interesting experimentation with noisy data.
%
% See also CSAPI, CSAPS, SPAPS, SPAP2, SPAPI.
% Copyright 1987-2005 C. de Boor and The MathWorks, Inc.
% $Revision: 1.38.4.2 $ $Date: 2005/05/31 16:41:11 $
updated = '04may05'; testing = 0;
v = ver('splines'); if size(v,2)>1, v = v(:,1); end
[relYear,ignored] = datevec(v.Date);
abouttext = {[v.Name ' ' v.Version]; ...
['Copyright 1987-' int2str(relYear) ' C. de Boor and The MathWorks, Inc.']};
if nargin<1 % import data
action = 'start';
else
if ischar(x)
action = x; hand = get(gcbf,'Userdata');
if isstruct(hand)&&isfield(hand,'currentline')
hc = hand.currentline; % make available, for use with changes
end
else % check and sort the given data
[x,y] = chckxy(x,y);
xname = 'x'; yname = 'y';
isf = 0;
action = 'start';
end
end
switch action
case 'add_item' % add an item
switch get(hand.data_etc,'Value')
case 1
[xx,yy] = ask_for_add(hand);
x = get(hand.dataline,'Xdata');
if xx<x(1)||xx>x(end)
warndlg(['The Spline Tool will let you only', ...
' add interior data sites.'], ...
'Attempted change of interval of approximation','modal')
elseif get(hand.method,'Value')==4&&~isempty(find(x==xx,1))
warndlg(['Since SPAPI would interpret repeated data sites',...
' as a request for osculatory interpolation, the Spline Tool',...
' won''t let you create repeated data sites now.'], ...
'Repeated data sites', 'modal');
else
set(hand.undo,'Enable','on')
insert_and_mark(x,get(hand.dataline,'Ydata'),xx,yy,hand)
undoud = get(hand.undo,'Userdata');
undoud.lineud = get(hand.nameline,'Userdata');
set(hand.undo,'Userdata',undoud);
get_approx(hand)
end
if isequal(get(hand.undo,'Enable'),'off')
V = get(hand.params(1,3),'Value');
set(hand.params(2,3),'String',x(V))
if isequal(get(hand.params(2,5),'Visible'),'on')
y = get(hand.dataline,'Ydata');
set(hand.params(2,5),'String',y(V))
end
end
case 2
switch get(hand.method,'Value')
case 3
xx = ask_for_add(hand);
lineud = get(hand.nameline,'Userdata');
[lineud.knots,i] = sort([lineud.knots,xx]);
placed = find(i==length(lineud.knots));
if placed==1||placed==length(lineud.knots)
warndlg('The Spline Tool will only let you add interior knots.',...
'The end knots are forever','modal')
lineud.knots(placed)=[];
set(hand.nameline,'Userdata',lineud)
set(hand.params(2,4),'String', ...
lineud.knots(get(hand.params(1,4),'Value')))
else
set(hand.params(1,4),'String',lineud.knots(:),'Value', placed)
lineud = update(hand,'knots',lineud);
lineud.kc(end+1) = ...
addchange(hc,['knots = sort([knots,',num2str(xx,15),']);',...
' %% you added a knot']);
set(hand.nameline,'Userdata',lineud)
% update knots display
set(hand.buttonm,'Visible','on')
markb(hand), set_bdisplay(lineud.knots,hand)
get_approx(hand)
end
end %switch get(hand.method,'Value')
case 3
end %switch get(hand.data_etc,'Value')
case 'align' % make sure the left and right data list are aligned
% at present, this serves no function, but sits here in case clicking
% anywhere on a list box activates a callback
tag = get(gcbo,'Tag');
if tag(5)=='l', j=3; else j=5; end
set(hand.params(1,8-j),'Value',get(hand.params(1,j),'Value'))
case 'axesclick' % action when the axes is clicked
% protect against clicks on Print Figure window:
if isempty(hand), return, end
% only react here to LEFT clicks
tmp = get(hand.figure,'SelectionType');
if tmp(1)=='n'
% get the location of the latest click in data coordinates:
clickp = get(hand.Axes(1),'CurrentPoint');
switch get(hand.data_etc,'Value')
case {1,3} % highlight the nearest data point
highlightn(clickp,hand)
case 2
switch get(hand.method,'Value')
case {1,3,4}
% find the nearest break
breaks = str2num(get(hand.params(1,4),'String'));
[ignored,V]=min(abs(breaks(:)-repmat(clickp(1),length(breaks),1)));
if get(hand.params(1,4),'Value')~=V
set(hand.params(1,4),'Value',V), markb(hand)
end
case 2
highlightn(clickp,hand)
end %switch get(hand.method,'Value')
end %switch get(hand.data_etc,'Value')
end %if tmp(1)=='n'
case 'change_name' % change the name of the current spline
names = get_names(get(hand.list_names,'String'));
V = get(hand.list_names,'Value');
oldname = names(V,:); oldname = oldname(6:end);
name = '';
while isempty(name)
answer = inputdlg(...
'Give a (valid MATLAB variable) name for the current spline:',...
'Please provide a new name for the current spline ...', 1,...
{deblank(oldname)});
if isempty(answer)||strcmp(answer{:},oldname), return, end
name = full_name(answer{1});
end
hand.name = name; hand.dbname = deblank(name);
set(hand.figure,'Userdata',hand)
if get(hand.ask_show,'Value')==1
names(V,:) = ['v || ',name];
else
names(V,:) = [' || ',name];
end
set(hand.list_names,'String',{names})
lineud = update(hand,'fit');
if isfield(lineud,'kc')
lineud.kc(end+1) = addchange(hc, ...
[hand.dbname,' = ',deblank(oldname),'; %% you changed the name']);
end
lineud.bottom = [' ',hand.dbname, ...
lineud.bottom(findstr(' =',lineud.bottom(1:14)):end)];
set(hand.bottomlinetext, 'String',lineud.bottom)
set(hand.nameline,'Tag',name,'Userdata',lineud)
set_view_label(name,hand)
if names(V,1)=='v'
legend(hand.Axes(1),'off'), set_legend(hand,hand.Axes(1))
end
case 'change_order' % call_back from the order selector in approximation field
M = get(hand.method,'Value');
switch M
case 2 % we are smoothing, hence now must change the edit fields
set_edits(2,hand)
case {3,4}
lineud = update(hand,'knots');
lineud.k = get(hand.order,'Value');
if M==3 % we are doing least-squares
lineud.knots = augknt(lineud.knots,lineud.k);
lineud.kc(end+1) = ...
addchange(hc,['knots = augknt(knots,',num2str(lineud.k),');',...
' %% you changed the order']);
else % we are doing interpolation
[lineud.knots,lineud.k] = aptknt(get(hand.dataline,'Xdata'),lineud.k);
end
if get(hand.data_etc,'Value')==2 % need to update the knot display
set(hand.params(1,4),'String',lineud.knots(:),'Value',1+lineud.k)
markb(hand), set_bdisplay(lineud.knots,hand)
end
set(hand.nameline,'Userdata',lineud)
end %switch M
get_approx(hand)
case {'close','exit','finish','quit'} % terminate splinetool
answer = questdlg(...
sprintf(['Do you really want to quit the SPLINE TOOL?\n', ...
'All unsaved data or approximations will be lost.']), ...
'Do you want to quit?','OK','Cancel','OK');
if isempty(answer)||answer(1)=='C', return, end
splinetool 'closefile'
case 'closefile' % close splinetool without further ado
delete(findobj('Tag','Spline Tool Example Message Box'))
delete(findobj(allchild(0),'name','Spline Tool'))
case 'data_etc' % callback from 'data_etc' to set up for present edit choice
if nargin>1, hand = y; end
% start clean
set([reshape(hand.params(:,3:5),15,1); hand.buttonm; hand.piecem; ...
hand.piecetext; ...
hand.highlightxy;hand.highlightb;hand.breaks(:);hand.rep_knot(:); ...
hand.add_item(:);hand.del_item(:)], 'Visible','off')
set(hand.breaks(:),'Userdata','off')
set(hand.undo,'Enable','off')
switch get(hand.data_etc,'Value')
case 1 % turn on the data display
set(hand.add_item,'Label','&Add Point ...','Visible','on')
set(hand.del_item,'Label','&Delete Point','Visible','on')
set(get(hand.Axes(1),'Children'),'UIContextMenu',hand.context)
x = get(hand.dataline,'Xdata');
set(hand.params(1,3),'String',x, ...
'Visible','on', ...
'Backgroundcolor',[1 1 1], ...
'Callback','splinetool ''highlightxy''', ...
'TooltipString', ...
'Mark a point, for editing below (same as leftclick on point in graph)')
set(hand.params(2,3),'String',x(1),'Visible','on')
set(hand.params([3 5],3), 'Visible','on')
set(hand.params(4,3),'Visible','on','Value',0)
if ~get(hand.params(4,3),'Value')
set(hand.params(4,3),'String',(x(end)-x(1))/(10*length(x)))
end
y = get(hand.dataline,'Ydata');
if get(hand.dataline,'Userdata')
set(hand.params(1,5),'String',y,'Visible','on', ...
'Backgroundcolor',.9*[1 1 1], ...
'Callback','splinetool ''highlightxy''', ...
'TooltipString','')
else
set(hand.params(1,5),'String',y, 'Visible','on', ...
'Backgroundcolor',[1 1 1], ...
'Callback','splinetool ''highlightxy''', ...
'TooltipString', ...
'Mark a point, for editing below (same as leftclick on point in graph)')
set(hand.params(2,5),'String',y(1),'Visible','on')
set(hand.params([3 5],5), 'Visible','on')
set(hand.params(4,5),'Visible','on','Value',0)
if ~get(hand.params(4,5),'Value')
set(hand.params(4,5),'String',(max(y)-min(y))/(10*length(y)))
end
end %if get(hand.dataline,'Userdata')
set(hand.highlightxy,'Visible','on')
markxy(hand) % also sets the editclkr field
case 2
M = get(hand.method,'Value');
switch M
case 1 % turn on the breaks display on the middle
set(get(hand.Axes(1),'Children'),'UIContextMenu',[])
lineud = get(hand.nameline,'Userdata');
breaks = fnbrk(lineud.cs,'breaks');
set(hand.params(1,4),'String',breaks(:), ...
'Visible','on', ...
'TooltipString','Mark a break', ...
'Callback','splinetool ''highlightb''')
set_bdisplay(breaks,hand), markb(hand)
set(hand.highlightb,'Visible','on')
case 2 % turn on the sites/weight display
set(get(hand.Axes(1),'Children'),'UIContextMenu',[])
set(hand.params(1,3),'String',get(hand.dataline,'Xdata'), ...
'Visible','on', ...
'Backgroundcolor',.9*[1 1 1], ...
'Callback','splinetool ''highlightxy''', ...
'TooltipString','')
lineud = get(hand.nameline,'Userdata');
set(hand.params(1,5),'String',lineud.w(:), ...
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?