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

📄 drawpoly.m

📁 computation of conformal maps to polygonally bounded regions
💻 M
📖 第 1 页 / 共 2 页
字号:
function [w,beta] = drawpoly(fig,cmd)
%DRAWPOLY Draw a polygon with the mouse.
%   P = DRAWPOLY allows the user to draw a polygon with the
%   mouse.  Use the mouse to position the crosshair and press the left
%   mouse button to create a vertex.  For use with other S-C Toolbox
%   functions, the vertices must be specified in a "positively oriented"
%   manner; i.e.  counterclockwise for interior polygons and clockwise
%   for exterior regions.  There are several GUI elements added to the
%   figure to help you snap vertices to a grid, get specfic angles, etc.
%   For the last vertex, use the middle or right mouse button, or double
%   click.  Upon return, P is a polygon object.
%
%   [W,BETA] = DRAWPOLY returns vectors of vertices and turning angles
%   instead of a polygon object.
%
%   See the user's guide for full details.
%	
%   See also POLYGON methods PLOT, EDIT, MODIFY.

%   Copyright 1998 by Toby Driscoll.
%   $Id: drawpoly.m 136 2001-05-11 19:49:16Z driscoll $

persistent youve_been_warned
if isempty(youve_been_warned)
  a = questdlg('DRAWPOLY is obsolete. Use POLYEDIT instead.','Obsolete function','Run DRAWPOLY','Run POLYEDIT','Run POLYEDIT');
  youve_been_warned = 1;
  if strcmp(a,'Run POLYEDIT')
    if nargin < 1
      w = polyedit;
    else
      w = polyedit(fig);
    end
    return
  end
end
  
% If called from the GUI, reroute to subfunction cback
if nargin > 1
  [w,beta] = cback(fig,cmd);
  return
end

if nargin < 1
  fig = gcf;
end

figure(fig);
turn_off_hold = ~ishold;

% Save current properties to be restored
figprops = {'unit';'pos';'resizefcn';'pointer';'windowbuttondown';...
    'windowbuttonup';'pointer'};
figstate = get(fig,figprops);
axprops = {'unit';'pos';'xgrid';'ygrid'};
axstate = get(gca,axprops);

% Get figure position and screen size
set(fig,'unit','point')
figpos = get(fig,'pos');
unit = get(0,'unit');
set(0,'unit','point')
maxpos = get(0,'screensize');
set(0,'unit',unit)

% Set up figure size
%figsize = [462 396];
%delta = figsize - figpos(3:4);
%figpos(1) = max(min(figpos(1),maxpos(3)-figsize(1)),0); % move left if needed
%figpos(2) = max(figpos(2)-delta(2),0); % move bottom down, not top up
%figpos(3:4) = figsize;
%set(fig,'resizefcn','')
%set(fig,'pos',figpos)
set(fig,'resizefcn','drawpoly(gcbo,''resize'');')

if ~ishold
  cla
  axis auto
end

% Reset axes limits?
if strcmp(get(gca,'xlimmode'),'auto') & strcmp(get(gca,'ylimmode'),'auto')
  axlim = [-4 4 -4 4];
else
  axlim = axis;
  axis(axlim)
end

view(2)
set(gca,'unit','point','box','on','xgrid','off','ygrid','off')
set(gca,'xlim',axlim(1:2),'ylim',axlim(3:4),'plotboxaspectratio',[1,1,1])
hold on

% Set up controls
dp_make_widgets(fig);
dp_resize_widgets(fig);

set(fig, 'pointer','crosshair');
preview = line(NaN,NaN,'linestyle','--','erasemode','xor',...
    'clipping','off','tag','preview');
vertices = line(NaN,NaN,'linesty','none','marker','.',...
    'markersize',12,'tag','vertices','erasemode','xor');
line(NaN,NaN,'visible','off','tag','DRP_PT');
  
% Preparation.
if ~strcmp(computer,'SUN4')
  % Kludge.  Draw preview line when button is pressed.
  set(fig,'windowbuttondownfcn','drawpoly(gcf,''move'');');
end
set(fig,'windowbuttonupfcn', 'drawpoly(gcf,''up'');');

set(preview,'user','first','xdata',[],'ydata',[]);
set(vertices,'xdata',[],'ydata',[],'zdata',[])
  
% Get vertices.
done = 0;
while ~done
  [x0,y0] = drawpoly(fig,'getpoint');
  x = get(vertices,'xdata');
  y = get(vertices,'ydata');
  atinf = get(vertices,'zdata');
  m = length(x);
  n = m - sum(atinf)/2;
  mode = get(preview,'user');
  axlim = axis;
  reflen = mean([diff(axlim(1:2)),diff(axlim(3:4))])/60;
  if m > 0 
    if norm([x0-x(1), y0-y(1)]) < reflen
      mode = 'done';
    end
  end
  x(m+1) = x0;  
  y(m+1) = y0;
  edges = findobj(fig,'tag','edges');
  
  switch mode
  case {'normal','first'}
    if n > 0
      edges(n) = plot(x(m:m+1),y(m:m+1),'-','erasemode','back');
      set(edges(n),'user',n)
    end
    if x0>=axlim(1) & x0<=axlim(2) & y0>=axlim(3) & y0<=axlim(4)
      % Finite vertex.
      atinf(m+1) = 0;
      set(preview,'user','normal')
    else
      atinf(m+1) = 1;
      set(preview,'user','infinite')
      set(fig,'pointer','cross')
    end
  case 'infinite'
    % Re-entry point for next edge.
    atinf(m+1) = 1;
    set(fig,'pointer','crosshair')
    set(preview,'user','return')
  case 'return'
    edges(n) = plot(x(m:m+1),y(m:m+1),'-','erasemode','back');
    set(edges(n),'user',n)
    atinf(m+1) = 0;
    set(preview,'user','normal')
  case 'done'
    x = x(1:m);
    y = y(1:m);
    done = 1;
  end  
  
  % Check buttonpress.
  if ~strcmp(get(fig,'selectiontype'),'normal') & (m > 0)
    done = 1;
  end
  
  set(vertices,'xdata',x,'ydata',y,'zdata',atinf);
  set(edges,'tag','edges')
  drawnow
end
  
m = length(x);
n = length(x) - sum(atinf)/2;
if n > 0
  edges(n) = plot(x([m,1]),y([m,1]),'-');
end
drawnow

w = x(:)+i*y(:);
beta = scangle(w);
s = sum(atinf);
if s > 0
  b = beta(logical(atinf));
  b(b>0) = b(b>0) - 2;
  b = sum(reshape(b,2,s/2))';
  idx = find(atinf);
  w(idx(1:2:s)) = Inf*ones(s/2,1);
  beta(idx(1:2:s)) = b;
  w(idx(2:2:s)) = [];
  beta(idx(2:2:s)) = [];
end

% Clean up the mess.
set(fig,figprops,figstate)
set(gca,axprops,axstate)
set(vertices,'erasemode','normal')
set(edges,'erasemode','normal')
frame(1) = findobj(fig,'tag','dp_settings');
frame(2) = findobj(fig,'tag','dp_actions');
delete(get(frame(1),'userdata'))
delete(get(frame(2),'userdata'))
delete(frame)
delete(preview)
delete(vertices)
delete(edges)
  
% Construct a polygon object
if sum(beta) < 0
  poly = polygon(w,1+beta);
else
  poly = polygon(flipud(w),1-flipud(beta));
end
if nargout < 2
  w = poly;
end

axis auto
if turn_off_hold
  hold off
end
plot(poly)
set(gca,'xtickmode','auto','ytickmode','auto')
set(gca,'xticklabelmode','auto','yticklabelmode','auto')


function [out1,out2] = cback(fig,cmd)

% Invocations as a callback
if nargout > 0
  out1 = [];
  if nargout > 1
    out2 = [];
  end
end

switch cmd

case 'getpoint'
  DRP_PT = findobj(fig,'tag','DRP_PT');
  set(fig,'windowbuttonmotionfcn','drawpoly(gcf,''move'');');
  drawnow
  waitfor(DRP_PT,'user')
  data = get(DRP_PT,'user');
  out1 = data(1);
  out2 = data(2);
  
case 'move'
  ptrpos = get(gca,'currentpoint');
  P = ptrpos(1,1:2);
  axlim = axis;
  preview = findobj(fig,'tag','preview');
  vertices = findobj(fig,'tag','vertices');
  x = get(vertices,'xdata');
  y = get(vertices,'ydata');
  pts = [x(:),y(:)];
  m = size(pts,1);
  mode = get(preview,'user');
  grid = str2num(get(findobj(fig,'tag','grid_space'),'string'));
  grid = grid * get(findobj(fig,'tag','snap'),'value');
  qang = 1/str2num(get(findobj(fig,'tag','ang_quant'),'string'));
  qang = qang * get(findobj(fig,'tag','qang'),'value');
  qlen = str2num(get(findobj(fig,'tag','len_quant'),'string'));
  qlen = qlen * get(findobj(fig,'tag','qlen'),'value');
  
  % Modify point to meet mode constraints.
  if strcmp(mode,'normal')
    % No constraints.
    mode = 0;
  elseif strcmp(mode,'first')
    % Point may not be outside axes box.
    P(1) = min(max(P(1),axlim(1)),axlim(2));
    P(2) = min(max(P(2),axlim(3)),axlim(4));
    mode = 0;
  elseif strcmp(mode,'infinite')
    % Point may not be inside axes box.
    if all(P>axlim([1,3])) & all(P<axlim([2,4]))
      [junk,j] = min(abs([P(1)-axlim(1:2);P(2)-axlim(3:4)]'));
      P = axlim(j);
    end
    mode = 1;
  elseif strcmp(mode,'return')
    % Point may not be outside axes box.
    P(1) = min(max(P(1),axlim(1)),axlim(2));
    P(2) = min(max(P(2),axlim(3)),axlim(4));
    ang = scangle([pts(m-2:m,1);P(1)]+i*[pts(m-2:m,2);P(2)]);
    ang = ang(2:3);
    ang(ang>0) = ang(ang>0) - 2;
    ang = sum(ang);
    mode = 2;
  end

  % Modify point to meet angle, length, or grid constraints.
  
  if any(mode==[0,2]) & qang & (m > 0)	% quantized angle
    % Find arg of new side which meets quantization requirements. 
    if m==1
      % No reference side, so refer to positive real axis
      ang = angle(P(1)-pts(m,1)+i*(P(2)-pts(m,2)))/pi;
      theta = qang*round(ang/qang)*pi;
    elseif mode==0
      ang = scangle([pts(m-1:m,1);P(1)]+i*[pts(m-1:m,2);P(2)]);
      ang = qang*round(ang(2)/qang);
      theta = atan2(pts(m,2)-pts(m-1,2),pts(m,1)-pts(m-1,1))-pi*ang;
    elseif mode==2
      % ang was computed above
      ang = qang*round(ang/qang);
      theta = atan2(pts(m-1,2)-pts(m-2,2),pts(m-1,1)-pts(m-2,1))-pi*ang;
    end
    % Project P to correct angle.
    A = pts(m,:);
    BA = [cos(theta),sin(theta)];
    P = A + ((BA)*(P-A)')*(BA);
    grid = 0;
  end
  if (mode==0) & qlen & (m > 0)		% quantized length
    A = pts(m,:);
    len = norm(P-A);
    fixlen = qlen*(round(len/qlen));
    P = A + fixlen/len*(P-A);
    grid = 0;
  end
  if any(mode==[0,1,2]) & grid	        % snap to grid
    grid = [grid,grid];
    minxy = axlim([1,3]);

⌨️ 快捷键说明

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