⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scgui.m

📁 computation of conformal maps to polygonally bounded regions
💻 M
📖 第 1 页 / 共 3 页
字号:
function out = scgui(varargin)
%SCGUI  Create graphical user interface for the SC Toolbox.
%   SCGUI creates the graphical user interface (GUI) for the
%   Schwarz-Christoffel Toolbox in a new figure window.
%
%   For complete details on the interface, see the user's guide.

%   Copyright 1998-2002 by Toby Driscoll.
%   $Id: scgui.m 262 2003-04-01 19:28:55Z driscoll $

% If called from the GUI, reroute to switchyard function cback
%%if nargin > 1
%%  out = cback(guidata(gcbo),varargin{:});
%%  return
%%end

% Create figure
fig = figure('name','Schwarz-Christoffel Mapping','numbertitle','off',...
    'tag','scgui','menubar','none','vis','off');
set(fig,'defaultuicontrolinterrupt','on')

% Determine/set figure size
minsize = [95 36];
unit = get(0,'units');
set(0,'units','char')
ss = get(0,'screensize');
set(0,'units',unit)
optsize = 0.65*ss(3:4);
truesize = max(optsize,minsize);
set(fig,'unit','char','pos',[0 ss(4)-truesize(2)-8 truesize])
% can't figure out why this doesn't work right.
%% movegui(fig,'northeast')

% Custom resize function
% I have to disable this because at least in my window manager (KDE), the
% resizing is soooooooo slow as to be painful. But you can try it on
% your machine.
%%set(fig,'resizefcn',@resize,'deletefcn',@selfdelete)
set(fig,'resize','off')

% Create axes
ax(1) = axes('units','char','tag','PhysicalAxes');
ax(2) = axes('units','char','tag','CanonicalAxes');
set(ax,'next','add','box','on','plotboxaspectratio',[1 1 1])

% Create widgets and set sizes appropriately (subfunctions)
make_widgets(fig);
resize_widgets(fig)
drawnow

set(fig,'closerequestfcn',@scquit)
set(fig,'vis','on')


function draw(obj,varargin)
data = guidata(obj);

p = polyedit;

if ~isempty(p)
  deletepoly(obj,'confirmed')
  deletemap(obj)
  addpoly(obj,p)
end


function domodify(obj,varargin)
data = guidata(obj);
p = data.polygon;
if isempty(p)
  errordlg('You must first draw or import a polygon,','SC Error')
  return
end		
n = length(p);

p1 = polyedit(p);

% Was anything really changed?
changed = 0;
w = vertex(p);
w1 = vertex(p1);
if length(w1) ~= length(w)
  changed = 1;
elseif norm(w(~isinf(w))-w1(~isinf(w1))) > 1000*eps
  changed = 1;
end

if changed
  deletepoly(obj,'confirmed')
  addpoly(obj,p1)
  % Ask about continuation.
  set(findobj(data.SCfig,'tag','MeshLines'),'erase','norm','vis','off')
  if data.iscurrent & length(w1)==length(w)
    a = questdlg('Do you want to use continuation from the current parameter solution?','Map continuation','Yes','No','No');
  else
    a = 'No';
  end
  if strcmp(a,'No')
    deletemap(obj)
  else
    deletemap(obj,'continue')
  end
end



function edit(obj,varargin)
data = guidata(obj);
w = vertex(data.polygon);
if isempty(w), return, end
if any(isinf(w))
  errordlg('Cannot edit vertices of unbounded polygons.','SC Error')
  return
end

n = length(w);

% Call edit window
[flag,w] = scgedit('Edit vertices','Vertices:',w);
% If edit was accepted, try to convert it to a polygon.
if flag > 0
  try 
    p = polygon(w);
  catch
    errordlg('Invalid polygon specified.','SC Error')
    return
  end
else
  return
end

% We now assume the polygon was changed.
deletepoly(obj,'confirmed')
if length(w)~=n
  % No way to be a continuation
  deletemap(obj)
else
  deletemap(obj,'continue')
end

addpoly(obj,polygon(w))


function solve(obj,varargin)
data = guidata(obj);
p = data.polygon;
if isempty(p)
  errordlg('You must first draw or import a polygon.','SC Error')
  return
end

mapnum = get(data.DomainPopup,'value');
maptype = data.mapclass{mapnum};
oldmap = data.map;
trace = 1;
%trace = get(data.TraceBox,'value');
tol = str2num(get(data.TolEdit,'string'));

if trace == 1
  trace = 'on';
else
  trace = 'off';
end

opt = scmapopt('Trace',trace,'Tol',tol);

if ~isempty(oldmap)
  % Continuation
  mapcmd = sprintf('map = %s(oldmap,p,opt);',maptype);
else
  mapcmd = sprintf('map = %s(p,opt);',maptype);
end

try
  eval(mapcmd)
catch
  errordlg('Solution process failed!','SC Error')
  return
end
    
deletemap(obj)
% Store new map
if ~isempty(map)
  addmap(obj,map)
  % Get the polygon back out of the map, because indexing and trivial
  % vertices may change.
  p = polygon(map);
  deletepoly(obj,'confirmed')
  addpoly(obj,p)
end

plotcanonical(obj)
setview(obj)


function plotcanonical(obj,varargin)
data = guidata(obj);
fig = data.SCfig;
if ~data.iscurrent, return, end

% Draw the canonical domain
axes(data.CanonicalAxes)
delete(findobj(gca,'tag','PolygonPlot'))
z = parameters(data.map);
z = z.prevertex;

switch class(data.map)
  case { 'diskmap','extermap','crdiskmap' }
    h = plot(exp(i*linspace(0,2*pi,100)),'linewid',1);
    axis normal
    axis equal
    axis square
    axis([-1.1 1.1 -1.1 1.1])
  case 'hplmap'
    xmin = min(z(~isinf(z)));
    xmax = max(z(~isinf(z)));
    xlim = [1.1*xmin-.1*xmax,1.1*xmax-.1*xmin];
    h = plot(xlim,[0,0],'linewid',1);
    axis normal
    axis equal
    axis square
    axis([xlim,-.1,1])
  case 'stripmap'
    minx = min(real(z(~isinf(z))));
    maxx = max(real(z(~isinf(z))));
    d = (maxx-minx)/2;
    m = (maxx+minx)/2;
    h(1) = plot([m-1.2*d,m+1.2*d],[0,0],'linewid',1);
    h(2) = plot([m-1.2*d,m+1.2*d],[1,1],'linewid',1);
    axis normal
    axis equal
    axis([m-1.2*d,m+1.2*d,-.1,1.1])
  case { 'rectmap','crrectmap' }
    axis auto
    h = plot(polygon(z));
    axis equal
end 	

guidata(fig,data)
    
set(h,'tag','PolygonPlot')
h = plot(real(z),imag(z),'ko','markersize',5,'markerfacecolor','k');
set(h,'tag','PolygonPlot')


function recenter(obj,varargin)
data = guidata(obj);
fig = data.SCfig;
% Only applies to current disk maps
isdisk = any(strcmp(class(data.map),{'diskmap','crdiskmap'}));
if ~data.iscurrent
  errordlg('You must first solve for the map parameters.','SC Error')
  return
elseif ~isdisk
  errordlg('The conformal center is defined only for disk maps.','SC Error')
  return
end

ax(1) = data.PhysicalAxes;
ax(2) = data.CanonicalAxes;
% Show physical domain & turn off point mapping
set(findobj(ax(1)),'vis','on')
set(findobj(ax(2)),'vis','off')
set(ax,'buttondown','')

% Get point and do calculation
axes(ax(1))
title('Click at conformal center')
[xc,yc] = ginput(1);
title('')
data.map = center(data.map,xc+i*yc);
guidata(obj,data)

deletemap(obj)
addmap(obj,data.map)

plotcanonical(obj)
setview(obj)

  
function scdisplay(obj,varargin)
data = guidata(obj);
if ~data.iscurrent
  errordlg('You must first solve for the map parameters.','SC Error')
else
  str = char(data.map);
  pos = [0 0 100 size(str,1)];
  f = figure('unit','char','vis','off','integerhandle','off',...
      'name','Map parameters','numbertitle','off','pos',pos);
  u = uicontrol('style','text','unit','char',...
      'pos',pos,'fontname','FixedWidth','horiz','left',...
      'background','white','string',str);
  set(f,'vis','on')
end


function meshplot(obj,varargin)
data = guidata(obj);
if ~data.iscurrent
  errordlg('You must first solve for the map parameters.','SC Error')
  return
end

ax(1) = data.PhysicalAxes;
ax(2) = data.CanonicalAxes;

% Parse mesh line widgets
xrhan = data.XREdit;
ythan = data.YTEdit;
xrstring = get(xrhan,'string');
ytstring = get(ythan,'string');
if strcmp(xrstring,'defaults') | strcmp(xrstring,'default')
  xr = 10;
else
  xr = str2num(xrstring);
end
if strcmp(ytstring,'defaults') | strcmp(ytstring,'default')
  yt = 10;
else
  yt = str2num(ytstring);
end

% Bring up physical domain and clear old mesh lines
%%    set(findobj(ax(1)),'vis','on')
%%    set(findobj(ax(2)),'vis','off')
ml = findobj(ax,'tag','MeshLines');
set(ml,'erase','normal')
delete(ml)
delete(findobj(ax(1),'tag','PolygonPlot'))
drawnow

% Exterior map: Allow axis autoscale
if strcmp(class(data.map),'extermap')
  set(ax(1),'xlimmode','auto','ylimmode','auto')
end

% Do the plot
[h,xr,yt] = plot(data.map,xr,yt);
set(h,'erasemode','none','tag','MeshLines')

% Plotting routines plot their own copy of the polygon,
% without returning handles. This locates and (re)tags these lines.
hp = findobj(ax(1),'tag','PolygonSide');
set(hp,'tag','PolygonPlot','uicontext',data.PolygonContextMenu)

% Update mesh line widgets
if isempty(xr)
  xrstring = '';
else
  xrstring = ['[',sprintf('%.3g ',xr),']'];
end
isdisk = strcmp(class(data.map),'diskmap');
isdisk = isdisk | strcmp(class(data.map),'extermap');    
if isempty(yt)
  ytstring = '';
elseif isdisk
  ytstring = ['pi*[',sprintf('%.3g ',yt/pi),']'];
else
  ytstring = ['[',sprintf('%.3g ',yt),']'];
end
set(xrhan,'string',xrstring)
set(ythan,'string',ytstring)

% May want to fix up the canonical domain
axes(ax(2))
z = prevertex(data.map);
switch class(data.map)
  case {'diskmap','extermap','crdiskmap'}
  case 'hplmap'
    zf = z(~isinf(z));
    xlim = [min(zf);max(zf)];
    xlim = [1.1 -.1; -.1 1.1] * xlim;
    ylim = [0;max(zf)];
    ylim = [0 0; -.1 1.1]*ylim;
    axis([xlim',-0.05*ylim(2),ylim(2)])
  case 'stripmap'
    %%	zf = z(~isinf(z));
    %%	xlim = [min(zf);max(zf)];
    %%	xlim = [1.1 -.1; -.1 1.1] * xlim;
    %%	axis([xlim',-.1,1.1])
  case 'rectmap'
  case 'crrectmap'
end
% Want to do this so that the buttondown of the mesh lines is set up.
setview(obj)


function images = mappts(pts)
domain = get(gca,'tag');
data = guidata(gcbo);
source = pts;				% (given)
images = [];
if data.iscurrent
  title('Mapping...')
  drawnow
  
  if ~isempty(source)
    % Forward/inverse map, depending on plane in view
    if strcmp(domain,'PhysicalAxes')
      images = evalinv(data.map,source);
    elseif strcmp(domain,'CanonicalAxes')
      images = eval(data.map,source);
    end
  else
    images = [];
  end

  title('')
  drawnow
end


function addpt(varargin)
% Take no action unless it's a standard left-click. But DON'T just return,
% because that short-circuits context menu clicks.
if strcmp(get(gcf,'selectiontype'),'normal')
  data = guidata(gcbo);
  pt = get(gca,'currentpoint');

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -