📄 arrow3.m
字号:
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 + -