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

📄 arrow3.m

📁 Matlab作一维、二维和三维箭头的源代码。
💻 M
📖 第 1 页 / 共 4 页
字号:
	while ((size(s,2)>1)&((abs(s(:,size(s,2)))==0)|(abs(s(:,size(s,2)))==abs(' ')))),		s = s(:,1:size(s,2)-1);	end;	s = [ones(length(ii),1)*[upper(mfilename) ' requires that  '] s ...	     ones(length(ii),1)*['  equal the # of arrows (' num2str(narrows) ').' c]];	s = s';	s = s(:)';	s = s(1:length(s)-1);	error(setstr(s));end;% check element length in Start, Stop, and CrossDirif ~isempty(start),	[m,n] = size(start);	if (n==2),		start = [start NaN*ones(m,1)];	elseif (n~=3),		error([upper(mfilename) ' requires 2- or 3-element Start points.']);	end;end;if ~isempty(stop),	[m,n] = size(stop);	if (n==2),		stop = [stop NaN*ones(m,1)];	elseif (n~=3),		error([upper(mfilename) ' requires 2- or 3-element Stop points.']);	end;end;if ~isempty(crossdir),	[m,n] = size(crossdir);	if (n<3),		crossdir = [crossdir NaN*ones(m,3-n)];	elseif (n~=3),		if (all(imag(crossdir(:))==0)),			error([upper(mfilename) ' requires 2- or 3-element CrossDir vectors.']);		else,			error([upper(mfilename) ' requires 2- or 3-element NormalDir vectors.']);		end;	end;end;% fill empty argumentsif isempty(start     ),   start      = [Inf Inf Inf];      end;if isempty(stop      ),   stop       = [Inf Inf Inf];      end;if isempty(len       ),   len        = Inf;                end;if isempty(baseangle ),   baseangle  = Inf;                end;if isempty(tipangle  ),   tipangle   = Inf;                end;if isempty(wid       ),   wid        = Inf;                end;if isempty(page      ),   page       = Inf;                end;if isempty(crossdir  ),   crossdir   = [Inf Inf Inf];      end;if isempty(ends      ),   ends       = Inf;                end;if isempty(ispatch   ),   ispatch    = Inf;                end;% expand single-column argumentso = ones(narrows,1);if (size(start     ,1)==1),   start      = o * start     ;   end;if (size(stop      ,1)==1),   stop       = o * stop      ;   end;if (length(len       )==1),   len        = o * len       ;   end;if (length(baseangle )==1),   baseangle  = o * baseangle ;   end;if (length(tipangle  )==1),   tipangle   = o * tipangle  ;   end;if (length(wid       )==1),   wid        = o * wid       ;   end;if (length(page      )==1),   page       = o * page      ;   end;if (size(crossdir  ,1)==1),   crossdir   = o * crossdir  ;   end;if (length(ends      )==1),   ends       = o * ends      ;   end;if (length(ispatch   )==1),   ispatch    = o * ispatch   ;   end;ax = o * gca;% if we've got handles, get the defaults from the handlesif ~isempty(oldh),	for k=1:narrows,		oh = oldh(k);		ud = get(oh,'UserData');		ax(k) = get(oh,'Parent');		ohtype = get(oh,'Type');		if strcmp(get(oh,'Tag'),ArrowTag), % if it's an arrow already			if isinf(ispatch(k)), ispatch(k)=strcmp(ohtype,'patch'); end;			% arrow UserData format: [start' stop' len base tip wid page crossdir' ends]			start0 = ud(1:3);			stop0  = ud(4:6);			if (isinf(len(k))),           len(k)        = ud( 7);   end;			if (isinf(baseangle(k))),     baseangle(k)  = ud( 8);   end;			if (isinf(tipangle(k))),      tipangle(k)   = ud( 9);   end;			if (isinf(wid(k))),           wid(k)        = ud(10);   end;			if (isinf(page(k))),          page(k)       = ud(11);   end;			if (isinf(crossdir(k,1))),    crossdir(k,1) = ud(12);   end;			if (isinf(crossdir(k,2))),    crossdir(k,2) = ud(13);   end;			if (isinf(crossdir(k,3))),    crossdir(k,3) = ud(14);   end;			if (isinf(ends(k))),          ends(k)       = ud(15);   end;		elseif strcmp(ohtype,'line')|strcmp(ohtype,'patch'), % it's a non-arrow line or patch			convLineToPatch = 1; %set to make arrow patches when converting from lines.			if isinf(ispatch(k)), ispatch(k)=convLineToPatch|strcmp(ohtype,'patch'); end;			x=get(oh,'XData');  x=x(~isnan(x(:)));  if isempty(x), x=NaN; end;			y=get(oh,'YData');  y=y(~isnan(y(:)));  if isempty(y), y=NaN; end;			z=get(oh,'ZData');  z=z(~isnan(z(:)));  if isempty(z), z=NaN; end;			start0 = [x(1)   y(1)   z(1)  ];			stop0  = [x(end) y(end) z(end)];		else,			error([upper(mfilename) ' cannot convert ' ohtype ' objects.']);		end;		ii=find(isinf(start(k,:)));  if ~isempty(ii),  start(k,ii)=start0(ii);  end;		ii=find(isinf(stop( k,:)));  if ~isempty(ii),  stop( k,ii)=stop0( ii);  end;	end;end;% convert Inf's to NaN'sstart(     isinf(start    )) = NaN;stop(      isinf(stop     )) = NaN;len(       isinf(len      )) = NaN;baseangle( isinf(baseangle)) = NaN;tipangle(  isinf(tipangle )) = NaN;wid(       isinf(wid      )) = NaN;page(      isinf(page     )) = NaN;crossdir(  isinf(crossdir )) = NaN;ends(      isinf(ends     )) = NaN;ispatch(   isinf(ispatch  )) = NaN;% set up the UserData data (here so not corrupted by log10's and such)ud = [start stop len baseangle tipangle wid page crossdir ends];% Set Page defaultspage = ~isnan(page) & trueornan(page);% Get axes limits, range, min; correct for aspect ratio and log scaleaxm       = zeros(3,narrows);axr       = zeros(3,narrows);axrev     = zeros(3,narrows);ap        = zeros(2,narrows);xyzlog    = zeros(3,narrows);limmin    = zeros(2,narrows);limrange  = zeros(2,narrows);oldaxlims = zeros(narrows,7);oneax = all(ax==ax(1));if (oneax),	T    = zeros(4,4);	invT = zeros(4,4);else,	T    = zeros(16,narrows);	invT = zeros(16,narrows);end;axnotdone = logical(ones(size(ax)));while (any(axnotdone)),	ii = min(find(axnotdone));	curax = ax(ii);	curpage = page(ii);	% get axes limits and aspect ratio	axl = [get(curax,'XLim'); get(curax,'YLim'); get(curax,'ZLim')];	oldaxlims(min(find(oldaxlims(:,1)==0)),:) = [curax reshape(axl',1,6)];	% get axes size in pixels (points)	u = get(curax,'Units');	axposoldunits = get(curax,'Position');	really_curpage = curpage & strcmp(u,'normalized');	if (really_curpage),		curfig = get(curax,'Parent');		pu = get(curfig,'PaperUnits');		set(curfig,'PaperUnits','points');		pp = get(curfig,'PaperPosition');		set(curfig,'PaperUnits',pu);		set(curax,'Units','pixels');		curapscreen = get(curax,'Position');		set(curax,'Units','normalized');		curap = pp.*get(curax,'Position');	else,		set(curax,'Units','pixels');		curapscreen = get(curax,'Position');		curap = curapscreen;	end;	set(curax,'Units',u);	set(curax,'Position',axposoldunits);	% handle non-stretched axes position	str_stretch = { 'DataAspectRatioMode'    ; ...	                'PlotBoxAspectRatioMode' ; ...	                'CameraViewAngleMode'      };	str_camera  = { 'CameraPositionMode'  ; ...	                'CameraTargetMode'    ; ...	                'CameraViewAngleMode' ; ...	                'CameraUpVectorMode'    };	notstretched = strcmp(get(curax,str_stretch),'manual');	manualcamera = strcmp(get(curax,str_camera),'manual');	if ~arrow_WarpToFill(notstretched,manualcamera,curax),		% give a warning that this has not been thoroughly tested		if 0 & ARROW_STRETCH_WARN,			ARROW_STRETCH_WARN = 0;			strs = {str_stretch{1:2},str_camera{:}};			strs = [char(ones(length(strs),1)*sprintf('\n    ')) char(strs)]';			warning([upper(mfilename) ' may not yet work quite right ' ...			         'if any of the following are ''manual'':' strs(:).']);		end;		% find the true pixel size of the actual axes		texttmp = text(axl(1,[1 2 2 1 1 2 2 1]), ...		               axl(2,[1 1 2 2 1 1 2 2]), ...		               axl(3,[1 1 1 1 2 2 2 2]),'');		set(texttmp,'Units','points');		textpos = get(texttmp,'Position');		delete(texttmp);		textpos = cat(1,textpos{:});		textpos = max(textpos(:,1:2)) - min(textpos(:,1:2));		% adjust the axes position		if (really_curpage),			% adjust to printed size			textpos = textpos * min(curap(3:4)./textpos);			curap = [curap(1:2)+(curap(3:4)-textpos)/2 textpos];		else,			% adjust for pixel roundoff			textpos = textpos * min(curapscreen(3:4)./textpos);			curap = [curap(1:2)+(curap(3:4)-textpos)/2 textpos];		end;	end;	if ARROW_PERSP_WARN & ~strcmp(get(curax,'Projection'),'orthographic'),		ARROW_PERSP_WARN = 0;		warning([upper(mfilename) ' does not yet work right for 3-D perspective projection.']);	end;	% adjust limits for log scale on axes	curxyzlog = [strcmp(get(curax,'XScale'),'log'); ...	             strcmp(get(curax,'YScale'),'log'); ...	             strcmp(get(curax,'ZScale'),'log')];	if (any(curxyzlog)),		ii = find([curxyzlog;curxyzlog]);		if (any(axl(ii)<=0)),			error([upper(mfilename) ' does not support non-positive limits on log-scaled axes.']);		else,			axl(ii) = log10(axl(ii));		end;	end;	% correct for 'reverse' direction on axes;	curreverse = [strcmp(get(curax,'XDir'),'reverse'); ...	              strcmp(get(curax,'YDir'),'reverse'); ...	              strcmp(get(curax,'ZDir'),'reverse')];	ii = find(curreverse);	if ~isempty(ii),		axl(ii,[1 2])=-axl(ii,[2 1]);	end;	% compute the range of 2-D values	curT = get(curax,'Xform');	lim = curT*[0 1 0 1 0 1 0 1;0 0 1 1 0 0 1 1;0 0 0 0 1 1 1 1;1 1 1 1 1 1 1 1];	lim = lim(1:2,:)./([1;1]*lim(4,:));	curlimmin = min(lim')';	curlimrange = max(lim')' - curlimmin;	curinvT = inv(curT);	if (~oneax),		curT = curT.';		curinvT = curinvT.';		curT = curT(:);		curinvT = curinvT(:);	end;	% check which arrows to which cur corresponds	ii = find((ax==curax)&(page==curpage));	oo = ones(1,length(ii));	axr(:,ii)      = diff(axl')' * oo;	axm(:,ii)      = axl(:,1)    * oo;	axrev(:,ii)    = curreverse  * oo;	ap(:,ii)       = curap(3:4)' * oo;	xyzlog(:,ii)   = curxyzlog   * oo;	limmin(:,ii)   = curlimmin   * oo;	limrange(:,ii) = curlimrange * oo;	if (oneax),		T    = curT;		invT = curinvT;	else,		T(:,ii)    = curT    * oo;		invT(:,ii) = curinvT * oo;	end;	axnotdone(ii) = zeros(1,length(ii));end;oldaxlims(oldaxlims(:,1)==0,:)=[];% correct for log scalescurxyzlog = xyzlog.';ii = find(curxyzlog(:));if ~isempty(ii),	start(   ii) = real(log10(start(   ii)));	stop(    ii) = real(log10(stop(    ii)));	if (all(imag(crossdir)==0)), % pulled (ii) subscript on crossdir, 12/5/96 eaj		crossdir(ii) = real(log10(crossdir(ii)));	end;end;% correct for reverse directionsii = find(axrev.');if ~isempty(ii),	start(   ii) = -start(   ii);	stop(    ii) = -stop(    ii);	crossdir(ii) = -crossdir(ii);end;% transpose start/stop valuesstart     = start.';stop      = stop.';% take care of defaults, page was done aboveii=find(isnan(start(:)       ));  if ~isempty(ii),  start(ii)       = axm(ii)+axr(ii)/2;                end;ii=find(isnan(stop(:)        ));  if ~isempty(ii),  stop(ii)        = axm(ii)+axr(ii)/2;                end;ii=find(isnan(crossdir(:)    ));  if ~isempty(ii),  crossdir(ii)    = zeros(length(ii),1);              end;ii=find(isnan(len            ));  if ~isempty(ii),  len(ii)         = ones(length(ii),1)*deflen;        end;ii=find(isnan(baseangle      ));  if ~isempty(ii),  baseangle(ii)   = ones(length(ii),1)*defbaseangle;  end;ii=find(isnan(tipangle       ));  if ~isempty(ii),  tipangle(ii)    = ones(length(ii),1)*deftipangle;   end;ii=find(isnan(wid            ));  if ~isempty(ii),  wid(ii)         = ones(length(ii),1)*defwid;        end;ii=find(isnan(ends           ));  if ~isempty(ii),  ends(ii)        = ones(length(ii),1)*defends;       end;% transpose rest of valueslen       = len.';baseangle = baseangle.';tipangle  = tipangle.';wid       = wid.';page      = page.';crossdir  = crossdir.';ends      = ends.';ax        = ax.';% given x, a 3xN matrix of points in 3-space;% want to convert to X, the corresponding 4xN 2-space matrix%%   tmp1=[(x-axm)./axr; ones(1,size(x,1))];%   if (oneax), X=T*tmp1;%   else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=T.*tmp1;%         tmp2=zeros(4,4*N); tmp2(:)=tmp1(:);%         X=zeros(4,N); X(:)=sum(tmp2)'; end;%   X = X ./ (ones(4,1)*X(4,:));% for all points with start==stop, start=stop-(verysmallvalue)*(up-direction);ii = find(all(start==stop));if ~isempty(ii),	% find an arrowdir vertical on screen and perpendicular to viewer	%	transform to 2-D		tmp1 = [(stop(:,ii)-axm(:,ii))./axr(:,ii);ones(1,length(ii))];		if (oneax), twoD=T*tmp1;		else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=T(:,ii).*tmp1;		      tmp2=zeros(4,4*length(ii)); tmp2(:)=tmp1(:);		      twoD=zeros(4,length(ii)); twoD(:)=sum(tmp2)'; end;		twoD=twoD./(ones(4,1)*twoD(4,:));	%	move the start point down just slightly		tmp1 = twoD + [0;-1/1000;0;0]*(limrange(2,ii)./ap(2,ii));	%	transform back to 3-D		if (oneax), threeD=invT*tmp1;		else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=invT(:,ii).*tmp1;		      tmp2=zeros(4,4*length(ii)); tmp2(:)=tmp1(:);		      threeD=zeros(4,length(ii)); threeD(:)=sum(tmp2)'; end;		start(:,ii) = (threeD(1:3,:)./(ones(3,1)*threeD(4,:))).*axr(:,ii)+axm(:,ii);end;% compute along-arrow points

⌨️ 快捷键说明

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