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

📄 rect2grid.m

📁 一些制作正交曲线网格的matlab源程序
💻 M
字号:
function [result, error_norm] = rect2grid(z, zrect, theCorners, theSize)% rect2grid -- Orthogonal grid from RECT result.%  [result, error_norm] = rect2grid(z, zrect, theCorners, theSize)%   produces a curvilinear orthogonal grid by interpolating the%   complex contour z, using zrect, the result of applying the%   conformal mapper RECT to z for theCorners (indices).  If zrect%   is empty, the RECT routine is called to compute it.  If zrect%   is a scalar, that number of RECT iterations will be performed.%   The size of the w output grid (complex matrix), including the%   perimeter, is determined by theSize.  The returned error_norm%   is the norm of the respective laplacians.%  rect2grid(nPoints) demonstrates itself with a random z contour%   of nPoints (default = 20). % Copyright (C) 1998 Dr. Charles R. Denham, ZYDECO.%  All Rights Reserved.%   Disclosure without explicit written consent from the%    copyright owner does not constitute publication. % Version of 21-Oct-1998 20:50:16.% Updated    23-Jun-2000 14:29:17.% Note: The splined interpolations tend to be too wild%  for general use here.  The safest method is to sample%  the z curve at very fine intervals, then use linear%  interpolation.%% Note: Presently, we apply rect to the existing boundary%  at equal-intervals along the edges, then interpolate%  to even-intervals in the rect domain, then solve the%  Poisson system, then interpolate back to the original%  spacing.  It might make better sense to iteratively%  apply rect, then resample the original boundary, until%  the rect-domain itself shows more or less equal-spacing%  along all edges.  We would adjust one edge before moving%  to the next.  Then, we would solve the Poisson system,%  then interpolate backwards as before.  The aim is to avoid%  crowding of mapped points in the rect-domain, where things%  are often not very smooth.  If we have to interpolate,%  let it be restricted to the original domain.		% Note: The rectangular mapping itself is based on a boundary%  composed of linear segments, which implies that any subsequent%  interpolations within the Poisson solution-grid should be done%  bi-linearly, rather than via splines.  (The bilinear interpolants%  of a rectangular grid have Laplacian = 0 automatically.)  By%  extension, the best way to interpolate a Poisson grid is%  linearly if we are taking the FFT approach.% Note: We should think about an iterative scheme is which the%  points to be mapped are adjusted until the mapping yields%  a more-or-less equally-spaced distribution.  It will be%  tricky, because interated-splines are badly behaved.if (0)	theInterpFcn = 'splineq';   % Interpolation function.	theInterpMethod = 1;   % interpolation method.else	theInterpFcn = 'interp1';   % Interpolation function.	theInterpMethod = 'linear';   % interpolation method.endif nargin < 1, help(mfilename), z = 'demo'; endif isequal(z, 'demo'), z = 20; endif ischar(z), z = eval(z); endif length(z) == 1	n = max(z, 4);	z = rand(n, 1) + sqrt(-1)*rand(n, 1);	z = z - mean(z);	a = angle(z);	[a, i] = sort(a);	jitter = 0.1;	z = (1 + jitter * rand(size(a))) .* exp(sqrt(-1)*a);	[ignore, nn] = sort(rand(1, length(z)-1));	theCorners = sort([1 nn(1:3)+1]);		k = 1; ktest = n*sqrt(n);	while k < ktest		k = 2*k;	end	theSize = [k k] + 1;		ztemp = z;	ztemp(end+1) = z(1);	z = [];	c = [theCorners length(ztemp)];	theCorners = [];		zplot = [];		for i = 1:4		j = c(i):c(i+1);		[ji, pp] = splineq(j, ztemp(j), n, 1);		zitemp = ppval(pp, ji);		zitemp(end) = [];		theCorners = [theCorners length(z)+1];		z = [z zitemp];	end		if (0)   % Set to 1 to see orthogonality.		z = rect(z, ceil(sqrt(n)), theCorners);	end		tic	FLAG = 0;		zrect = [];		if FLAG		zrect = rect(z, ceil(sqrt(n)), theCorners);	end		[w, err] = rect2grid(z, zrect, theCorners, ceil(theSize/2));		disp([' ## Elapsed time: ' num2str(toc) ' seconds.'])		if ~isempty(w)		u = real(w); v = imag(w);		u_err = real(err); v_err = imag(err);		subplot(1, 1, 1)		if FLAG, subplot(1, 2, 1), end		hold off		h = plot(u, v, 'g-', u.', v.', 'b-');		hold on		z(end+1) = z(1);		x = real(z); y = imag(z);		plot(x, y, 'bo', ...				x(theCorners), y(theCorners), 'ro', ...				x(theCorners(1)), y(theCorners(1)), 'r*')		hold off		xlabel('x'), ylabel('y')		theCommand = [mfilename ' ( ' int2str(n) ' )'];		title(theCommand)		set(gcf, 'ButtonDownFcn', theCommand)		figure(gcf)		axis equal		zoomsafe 0.9, zoomsafe		if FLAG			subplot(1, 2, 2)			plot(real(zrect), imag(zrect), '-o')			axis equal			zoomsafe 0.9, zoomsafe		end	end	error_norm = [real(err) imag(err)];	if nargout > 0		result = w;	else		disp([' ## error_norm = ' sprintf('%0.4g %0.4gi', error_norm)])	end	returnend% Check for mex-files "mexrect" and "mexsepeli".hasMex = (exist('mexrect', 'file') == 3) & ...			(exist('mexsepeli', 'file') == 3);			hasMex = 0;   % Note this override.% If no actual "zrect" is given, apply RECT until%  the straightness of the result deviates from%  1.0 by no more than 0.1 percent.if length(zrect) < 2	if length(zrect) == 1		ntimes = zrect;	else		ntimes = ceil(sqrt(length(z)));	end	zrect = z(:);		tolerance = 0.001;	tolerance = 0.00001;		for i = 1:ntimes		if ~hasMex			[zrect, straight] = feval('rect', zrect, 1, theCorners);		else			zrect = feval('mexrect', zrect, length(zrect), ...				theCorners(1), theCorners(2), theCorners(3), theCorners(4));			ztemp = zrect;			ztemp(end+1) = ztemp(1);			ctemp = theCorners;			ctemp(end+1) = ctemp(1);			num = sum(abs(diff(ztemp(ctemp))));			den = sum(abs(diff(ztemp)));			straight = num./den;		end		if norm(1-straight) <= tolerance, break, end		disp([' ## RECT Iteration ' int2str(i) ...				': straightness = ' num2str(straight*100) ' percent.'])	end		% Verbose quality of mapping.	if (0)		hello rect2grid line 150		non_straight_percent = 100*(1-straight)		d13 = abs(diff(zrect(theCorners([1 3]))));		d24 = abs(diff(zrect(theCorners([2 4]))));		non_rect_percent = 100*2*abs((d13-d24)/(d13+d24))		fig = gcf;		f = findobj('Type', 'figure', 'Tag', mfilename);		if isempty(f)			f = figure('Name', mfilename', 'Tag', mfilename);		end		figure(f)		plot(real(zrect), imag(zrect), '-o', ...			real(zrect(theCorners(1))), imag(zrect(theCorners(1))), '*')		set(gca, 'XLim', [-0.1 1.1]*max(real(zrect)), ...				'YLim', [-0.1 1.1]*max(imag(zrect)))		figure(fig)		drawnow	end	if norm(1-straight) > tolerance		disp([' ## rect2grid: Conformal mapping not successful'])		disp(['               after ' int2str(ntimes) ' iterations.'])		if nargout > 0, result = []; error_norm = []; end		return	endend% Make zrect perfectly rectangular: not necessary.if (0)	x = real(zrect); x = [x(:); x(1)];	y = imag(zrect); y = [y(:); y(1)];	c = [theCorners(:); length(x)].';	y(c(1):c(2)) = 0;	x(c(2):c(3)) = 1;	y(c(3):c(4)) = mean(y(c(3):c(4)));	x(c(4):c(5)) = 0;	zrect = x(1:end-1) + sqrt(-1)*y(1:end-1);end% Desired size.if length(theSize) == 1, theSize = theSize * [1 1]; endm = theSize(1); n = theSize(2);% Get indices of matrix perimeter.temp = zeros(theSize);temp(:) = 1:prod(theSize);ind = [];ind = [ind; temp(1:m-1, 1)];ind = [ind; temp(m, 1:n-1).'];ind = [ind; temp(m:-1:2, n)];ind = [ind; temp(1, n:-1:1).'];% Interpolate around the "zrect" boundary%  as a function of distance along the physical%  boundary.rdist = [0; cumsum(abs(diff([zrect(:); zrect(1)])))];rdist = rdist - min(rdist); rdist = rdist / max(rdist);z(end+1) = z(1);x = real(z);y = imag(z);c = [theCorners(:); length(x)].';   % Physical and mapped corners.d = cumsum([1 m-1 n-1 m-1 n-1]);    % Corners around the matrix.xi = zeros(size(ind));yi = zeros(size(ind));for i = 1:4	j = c(i):c(i+1);	k = d(i):d(i+1);	rd = rdist(j); rd = rd - min(rd); rd = rd / max(rd);	xx = x(j);	yy = y(j);	dd = k; dd = dd - min(dd); dd = dd / max(dd);		TESTING = 1;   % <== NOTE.	TESTING = 0;   % <== NOTE.		if TESTING		[ki, pp] = splineq(j, z(j), length(k), 1);		zi = ppval(pp, ki);		xi(k) = real(zi);		yi(k) = imag(zi);	else		xi(k) = feval(theInterpFcn, rd, xx, dd, theInterpMethod).';		yi(k) = feval(theInterpFcn, rd, yy, dd, theInterpMethod).';	end	endif (0)	hello(mfilename)	c, y, d = diff(y);end% Sprinkle interpolated values along the perimeter.u = zeros(theSize); v = zeros(theSize);u(ind) = xi; v(ind) = yi;% Aspect ratio of the rectangle.if (1)	dx = 1; dy = 1;   % Square.else	dx = abs(zrect(2)-zrect(1)) / m;   % Rectangle.	dy = abs(zrect(3)-zrect(2)) / n;   % Rectangle.end% Solve Laplace's equation inside the boundary.  At this%  stage, it is slightly advantageous to use arrays u and%  v whose sizes are a power-of-two plus one.if ~hasMex	isSlope = 0;	u = fps(u, isSlope, dx, dy);	v = fps(v, isSlope, dx, dy);else   % Use MEXSEPELI.	l2 = m-1;	m2 = n-1;	seta = linspace(0, 1, n);	sxi = linspace(0, 1, m);	[u, v] = feval('mexsepeli', u, v, l2, m2, seta, sxi);endw = u + sqrt(-1).*v;if nargout > 0	result = w;else	disp(w)endif nargout > 1	del2_u = 4*del2(u);	err_norm_u = norm(del2_u(2:end-1, 2:end-1));	del2_v = 4*del2(v);	err_norm_v = norm(del2_v(2:end-1, 2:end-1));	error_norm = err_norm_u + sqrt(-1).*err_norm_v;end

⌨️ 快捷键说明

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