No BSD License  

Highlights from
Schwarz-Christoffel Toolbox

image thumbnail
from Schwarz-Christoffel Toolbox by Toby Driscoll
Computes conformal maps to polygons, allowing easy solution of Laplace's equation.

crrectmap(poly,varargin)
function M = crrectmap(poly,varargin)
%CRRECTMAP Schwarz-Christoffel cross-ratio disk map object.
%   CRRECTMAP(P) constructs a Schwarz-Christoffel crossratio rectified
%   map object for the polygon P. The parameter problem is solved, using
%   default options, for the crossratios of the prevertices on the
%   disk. Then you are required to graphically assign angles of the
%   rectified polygon. These angles determine the rectilinear polygon
%   that is considered the canonical domain.
%   
%   CRRECTMAP(P,OPTIONS) uses an options structure of the type created
%   by SCMAPOPT in solving the parameter problem.
%   
%   CRRECTMAP(P,ALPHAR) uses supplied angles for the rectified
%   polygon. Here ALPHAR is a vector having the same length as P. Each
%   element is an interior angle of the rectified polygon, normalized by
%   pi. The only valid entries are {.5,1,1.5,2}. An OPTIONS argument can
%   be added.
% 
%   CRRRECTMAP(M,ALPHAR) modifies the previously computed crrectmap M to
%   have rectified angles ALPHAR. Make ALPHAR the empty matrix to choose
%   new angles graphically. 
%   
%   CRRECTMAP(M,P), CRRECTMAP(M,P,ALPHAR) and CRRECTMAP(M,P,OPTIONS) use
%   continutation to go from the polygon in crrectmap M to P.
%   
%   CRRECTMAP(M), where M is a crrectmap object, just returns M.
%   
%   CRRECTMAP(MD), where MD is a crdiskmap object, uses the polygon and
%   prevertex crossratios already specified in MD, and requests angle
%   selection. CRRECTMAP(MD,ALPHAR) is also valid. 
%   
%   Use CRRECTMAP instead of RECTMAP when the polygon has multiple
%   elongations, or when RECTMAP fails to converge.
%   
%   See also SCMAPOPT, classes POLYGON, CRDISKMAP, RECTMAP.

%   Copyright 1998 by Toby Driscoll.
%   $Id: crrectmap.m 7 1998-05-10 04:37:19Z tad $

superiorto('double');

if nargin==0
  M.diskmap = crdiskmap;
  M.rectpolygon = [];
  M.rectaffine = [];
  M.rectqdata = [];
  M_sc = scmap;
  M = class(M,'crrectmap',M_sc);
  return
end

% Assign empties to optional args
alphar = [];
opt = [];
MD = [];

% Branch based on class of first argument
switch class(poly)

  case 'crrectmap'
    if nargin == 1
      % Self-return
      M = poly;
      return
    else
      M0 = poly;
      if isa(varargin{1},'double')
	% New alphar
	MD = M0.diskmap;
	alphar = varargin{1};
      elseif isa(varargin{1},'polygon')
	% Continuation
	MD = crdiskmap(M0.diskmap,varargin{1});
	if nargin > 2
	  if isstruct(varargin{2})
	    opt = varargin{2};
	    alphar = [];
	  else
	    alphar = varargin{2};
	  end
	else
	  alphar = angle(M0.rectpolygon);
	end
      else
	error('Invalid continuation syntax.')
      end
      poly = polygon(MD);
      opt = scmapopt(MD);
    end
  
  case 'crdiskmap'
    MD = poly;
    poly = polygon(MD);
    if nargin > 1
      alphar = varargin{1};
    end
    
  case 'polygon'
    % Parse optional arguments
    for j = 1:length(varargin)
      arg = varargin{j};
      % Each arg is an options struct or alphar
      if isa(arg,'struct')
	opt = arg;
      elseif length(arg) == length(poly)
	alphar = arg(:);
      else
	msg = 'Unable to parse argument ''%s''.';
      error(sprintf(msg,inputname(j+1)))
    end
  end
  
otherwise
  msg = 'Expected ''%s'' to be of class polygon, crrectmap, or crdiskmap.';
  error(sprintf(msg,inputname(1)))
  
end % switch


% Retrieve options
opt = scmapopt(opt);

% Get data for the low-level functions
w = vertex(poly);
beta = angle(poly) - 1;

% Find prevertex crossratios if necessary
if isempty(MD)
  MD = crdiskmap(poly,opt);
  param = parameters(MD);
  orig = param.original;
  poly = polygon(MD);
  w = vertex(poly);
  beta = angle(poly) - 1;
else
  param = parameters(MD);
  orig = logical(ones(size(w)));
  opt = scmapopt(MD);
end

M.diskmap = MD;

cr = param.crossratio;
aff = param.affine;
Q = param.qlgraph;

% Open rectified angle selection if necessary
if isempty(alphar)
  [wr,betar,affr] = crrect(w,beta,cr,aff,Q);
else
  % Check entries for validity
  if any(~ismember(alphar,[.5 1 1.5 2])) | abs(sum(alphar-1)+2) > 1e-12
    error('Invalid rectified angles supplied.')
  end
  % Convert alphas to betas, expanding if polygon was split
  betar = zeros(size(w));
  betar(orig) = alphar - 1;
  [wr,betar,affr] = crrect(w,beta,cr,aff,Q,betar);
end

polyr = polygon(wr,betar+1);
M.rectpolygon = polyr;
M.rectaffine = affr;
M.rectqdata = scqdata(betar,ceil(-log10(opt.Tolerance)));

% Make a parent scmap object
M_sc = scmap(poly,opt);

% Create object. Even though MD is a field, we're not really a child.
M = class(M,'crrectmap',M_sc);

Contact us at files@mathworks.com