📄 scgui.m
字号:
% Map it
img = mappts(pt(1,1)+i*pt(1,2));
ax(1) = data.PhysicalAxes;
ax(2) = data.CanonicalAxes;
domain = find(gca==ax);
% Ensure the existence of the line objects.
if isempty(data.PhysicalPoints) | ~ishandle(data.PhysicalPoints)
data.PhysicalPoints = make_pointsobject(data,'Physical');
end
if isempty(data.CanonicalPoints) | ~ishandle(data.CanonicalPoints)
data.CanonicalPoints = make_pointsobject(data,'Canonical');
end
h = [data.PhysicalPoints data.CanonicalPoints];
% Update objects to show points
axes(ax(domain))
set(h,'erasemode','none')
xs = [get(h(domain),'xdata') pt(1,1)];
ys = [get(h(domain),'ydata') pt(1,2)];
set(h(domain),'xdata',xs,'ydata',ys)
xi = [get(h(3-domain),'xdata') real(img)];
yi = [get(h(3-domain),'ydata') imag(img)];
set(h(3-domain),'xdata',xi,'ydata',yi)
if domain==1
data.phypoints = xs + i*ys;
data.canpoints = xi + i*yi;
else
data.phypoints = xi + i*yi;
data.canpoints = xs + i*ys;
end
set(h,'erasemode','normal')
guidata(gcbf,data)
end
function editpts(varargin)
domain = get(gca,'tag');
if isempty(domain), return, end
data = guidata(gcbo);
pphan = data.PhysicalPoints;
cphan = data.CanonicalPoints;
wp = get(pphan,'xdata')+i*get(pphan,'ydata');
zp = get(cphan,'xdata')+i*get(cphan,'ydata');
wp = wp(~isnan(wp));
zp = zp(~isnan(zp));
% Interpretation of box depends on current view domain
if strcmp(domain,'PhysicalAxes')
[flag,wp] = scgedit('Edit points','Physical',wp);
if flag > 0
zp = mappts(wp);
end
elseif strcmp(domain,'CanonicalAxes')
[flag,zp] = scgedit('Edit points','Canonical',zp);
if flag > 0
wp = mappts(zp);
end
end
if flag > 0
% Update point objects
set(pphan,'xdata',real(wp(:))','ydata',imag(wp(:))')
set(cphan,'xdata',real(zp(:))','ydata',imag(zp(:))')
data.phypoints = wp(:);
data.canpoints = zp(:);
guidata(gcbf,data)
end
function importexport(obj,varargin)
data = guidata(obj);
fig = data.SCfig;
% Find import/export window, or create if necessary
fig2 = findobj(0,'tag','sc_importexport');
if isempty(fig2)
fig2 = make_importexportfig;
else
figure(fig2)
end % (create window)
data = guidata(fig2);
data.parentfig = fig;
guidata(fig2,data)
% Reveal window and wait for action
set(fig2,'vis','on')
uiwait(fig2)
set(fig2,'vis','off') % turn it off
function scimport(obj,varargin)
% Data from the I/E dialog.
IEdata = guidata(obj);
% Data from the SC figure
SCfig = IEdata.parentfig;
SCdata = guidata(SCfig);
name = get(IEdata.PolygonEdit,'string');
if ~isempty(name)
try
p = evalin('base',name);
deletepoly(SCfig,'confirmed')
deletemap(SCfig)
addpoly(SCfig,p)
catch
errordlg(lasterr,'SC Error')
end
end
name = get(IEdata.MapEdit,'string');
if ~isempty(name)
try
map = evalin('base',name);
% This overrides an imported polygon.
p = polygon(map);
deletepoly(SCfig,'confirmed')
deletemap(SCfig)
addpoly(SCfig,p)
addmap(SCfig,map)
catch
errordlg(lasterr,'SC Error')
uiresume(gcbf)
end
end
plotcanonical(SCfig)
setdomain(SCfig)
setview(SCfig)
uiresume(gcbf)
function scexport(varargin)
% Data from the I/E dialog.
IEdata = guidata(gcbf);
% Data from the SC figure
SCfig = IEdata.parentfig;
SCdata = guidata(SCfig);
name = get(IEdata.PolygonEdit,'string');
if ~isempty(name) & ~isempty(SCdata.polygon)
assignin('base',name,SCdata.polygon);
end
name = get(IEdata.MapEdit,'string');
if ~isempty(name) & SCdata.iscurrent
assignin('base',name,SCdata.map);
end
uiresume(gcbf)
function setview(obj,varargin)
data = guidata(obj);
ax(1) = data.PhysicalAxes;
ax(2) = data.CanonicalAxes;
viewdom = get(data.ViewPopup,'value');
% Set axes positions
window = data.axeswindow;
if viewdom==1 | viewdom==2
set(ax,'pos',window)
else
% They must occupy the window together
dx = .46*window(3);
dy = window(4);
set(ax(1),'pos',[window(1) window(2) dx dy])
set(ax(2),'pos',[window(1)+window(3)-dx window(2) dx dy])
end
% Set visibility, map-on-click functions
vis = [viewdom~=2 viewdom~=1];
set(findobj(ax(vis)),'visible','on')
set(findobj(ax(~vis)),'visible','off')
% All children get the buttondown set to map points. This is because lines
% can "hide" the axes in a zone around the line (so no mapping close to the
% boundary). Even though the 'hittest' property seems to fix this,
% if that is turned off then we don't get nice context menus. The addpt
% function will sort out left clicks from right.
if ~isempty(data) & data.iscurrent
set(findobj(ax(vis)),'buttondown',@addpt)
else
set(findobj(ax(vis)),'buttondown','')
end
set(findobj(ax(~vis)),'buttondown','')
if sum(vis)==1
axes(ax(vis))
end
function setdomain(obj,varargin)
data = guidata(obj);
fig = data.SCfig;
mapnum = get(data.DomainPopup,'value');
%type = {'disk','half-plane','strip','rectangle','exterior'};
curmapnum = strmatch(class(data.map),data.mapclass);
if ~isempty(curmapnum) & mapnum~=curmapnum
% Map type has been changed, so kill old map
deletemap(obj)
end
% Mesh line options should be r/theta or x/y
set(data.XREdit,'string','defaults');
set(data.YTEdit,'string','defaults');
xrtext = data.XRText;
yttext = data.YTText;
if mapnum==1 | mapnum==5
set(xrtext,'string','r =')
set(yttext,'string','theta =')
else
set(xrtext,'string','x =')
set(yttext,'string','y =')
end
%%% Clear all current mesh lines
%%delete(findobj(fig,'tag','MeshLines'))
function scquit(varargin)
if strcmp(questdlg('Really quit?','Quit SC mapping'),'Yes')
selfdelete
end
function selfdelete(varargin)
delete([findobj(0,'tag','sc_importexport') gcbf])
function resize(varargin)
resize_widgets(gcbf)
function savedata(varargin)
obj = gcbo;
data = guidata(obj);
p = data.polygon; map = data.map;
if isempty(p) && isempty(map)
return
end
if ~isfield(data,'savename') || isempty(data.savename)
filter = '*.mat';
else
filter = data.savename;
end
[filen,pathn] = uiputfile(filter,'Save SC data');
if isstr(filen)
data.savename = [pathn filen];
guidata(obj,data);
save([pathn filen],'p','map');
end
function loaddata(varargin)
obj = gcbo;
data = guidata(obj);
if ~isfield(data,'savename') || isempty(data.savename)
filter = '*.mat';
else
filter = data.savename;
end
[filen,pathn] = uigetfile(filter,'Load SC data');
if isstr(filen)
S = load([pathn filen]);
if ~isfield(S,'p') || ~isfield(S,'map')
error('File %s does not contain needed GUI data',[pathn filen])
else
data.savename = [pathn filen];
guidata(obj,data);
deletepoly(obj,'confirmed')
deletemap(obj)
addpoly(obj,S.p)
if ~isempty(S.map), addmap(obj,S.map), end
end
end
function printablecopy(varargin)
fig = gcbf;
data = guidata(fig);
ax(1) = data.PhysicalAxes;
ax(2) = data.CanonicalAxes;
viewdom = get(data.ViewPopup,'value');
if viewdom==1 || viewdom==2 % only one view
idx = viewdom;
else
idx = [1 2];
end
newfig = figure;
for l = 1:length(idx)
subplot(1,length(idx),l);
tmp = gca;
axun = get(tmp,'unit'); axpos = get(tmp,'pos');
newax = copyobj( ax(idx(l)), newfig );
delete(tmp)
set(newax,'unit',axun,'pos',axpos);
% Wipe out GUI-specific markers.
set(newax,'buttondown','','tag','')
set(allchild(newax),'uicontextmenu',[],'buttondown','','tag','')
end
function addpoly(obj,p,varargin)
% Add a polygon. Make sure that it is displayed and tagged properly, and
% enable appropriate further actions.
data = guidata(obj);
data.polygon = p;
guidata(obj,data)
if isempty(p), return, end
if nargin<3 | ~all(ishandle(varargin{1}))
axes(data.PhysicalAxes)
axis auto
h = plot(p);
else
h = varargin{1};
end
set(h, 'tag','PolygonPlot', 'uicontext',data.PolygonContextMenu);
set(data.PolygonEnabled,'enable','on')
function deletepoly(obj,varargin)
% Remove the polygon from display and the data structure.
if nargin < 2 | ~isequal( varargin{1},'confirmed')
answer = questdlg('Really delete the current polygon?','Confirm delete',...
'Yes','No','No');
if strcmp(answer,'No'), return, end
end
data = guidata(obj);
data.polygon = [];
guidata(obj,data)
delete(findobj(data.SCfig,'tag','PolygonPlot'))
% Without a polygon, some controls are disabled.
set(data.PolygonEnabled,'enable','off')
function menudeletepoly(obj,varargin)
deletepoly(obj)
deletemap(obj)
function addmap(obj,map)
% Add a map. Make sure that supporting objects exist and
% enable appropriate further actions.
data = guidata(obj);
data.map = map;
data.iscurrent = 1;
guidata(obj,data)
% Correct the class popup to reflect reality.
set(data.DomainPopup,'value',strmatch(class(map),data.mapclass))
plotcanonical(obj)
% Enable relevant controls.
set(data.MapEnabled,'enable','on')
function deletemap(obj,varargin)
% The current map has been deleted (or never existed). Take care of the data
% structures and widgets.
data = guidata(obj);
% We may not erase the memory of the map if we want to do continuation.
if nargin < 2 | ~isequal(varargin{1},'continue')
data.map = [];
end
data.iscurrent = 0;
guidata(obj,data)
set(data.MapEnabled,'enable','off')
% No mesh lines or canonical domain.
ml = findobj(data.SCfig,'tag','MeshLines');
set(ml,'erasemode','normal')
delete(ml)
delete(findobj(data.CanonicalAxes,'tag','PolygonPlot'))
% There can be no points to display...
deletepoints(obj,'confirmed')
% ...nor can more be mapped.
set(findobj([data.PhysicalAxes,data.CanonicalAxes]),'buttondown','')
function deletepoints(obj,varargin)
% Remove plotted points from display and data structure.
if nargin < 2 | ~isequal( varargin{1},'confirmed')
answer = questdlg('Really delete the plotted points?','Confirm delete',...
'Yes','No','No');
if strcmp(answer,'No'), return, end
end
data = guidata(obj);
data.phypoints = [];
data.canpoints = [];
h = [data.PhysicalPoints,data.CanonicalPoints];
set(h(ishandle(h)),'xdata',[],'ydata',[])
guidata(obj,data)
function hp = make_pointsobject(data,type)
hp = line('parent',getfield(data,[type 'Axes']),...
'linestyle','none','marker','o','markersize',5,...
'color',[1 0 0],'markerfacecolor',[1 0 0],...
'tag',[type 'Points'],'uicontextmenu',data.PointContextMenu,...
'xdata',[],'ydata',[]);
function [flag,x1,x2] = scgedit(name,xlab1,x1,xlab2,x2)
% Pops up a figure window to edit some data.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -