📄 arrow3.m
字号:
% transform Start points tmp1=[(start-axm)./axr;ones(1,narrows)]; if (oneax), X0=T*tmp1; else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=T.*tmp1; tmp2=zeros(4,4*narrows); tmp2(:)=tmp1(:); X0=zeros(4,narrows); X0(:)=sum(tmp2)'; end; X0=X0./(ones(4,1)*X0(4,:));% transform Stop points tmp1=[(stop-axm)./axr;ones(1,narrows)]; if (oneax), Xf=T*tmp1; else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=T.*tmp1; tmp2=zeros(4,4*narrows); tmp2(:)=tmp1(:); Xf=zeros(4,narrows); Xf(:)=sum(tmp2)'; end; Xf=Xf./(ones(4,1)*Xf(4,:));% compute pixel distance between points D = sqrt(sum(((Xf(1:2,:)-X0(1:2,:)).*(ap./limrange)).^2)); D = D + (D==0); %eaj new 2/24/98% compute and modify along-arrow distances len1 = len; len2 = len - (len.*tan(tipangle/180*pi)-wid/2).*tan((90-baseangle)/180*pi); slen0 = zeros(1,narrows); slen1 = len1 .* ((ends==2)|(ends==3)); slen2 = len2 .* ((ends==2)|(ends==3)); len0 = zeros(1,narrows); len1 = len1 .* ((ends==1)|(ends==3)); len2 = len2 .* ((ends==1)|(ends==3)); % for no start arrowhead ii=find((ends==1)&(D<len2)); if ~isempty(ii), slen0(ii) = D(ii)-len2(ii); end; % for no end arrowhead ii=find((ends==2)&(D<slen2)); if ~isempty(ii), len0(ii) = D(ii)-slen2(ii); end; len1 = len1 + len0; len2 = len2 + len0; slen1 = slen1 + slen0; slen2 = slen2 + slen0; % note: the division by D below will probably not be accurate if both % of the following are true: % 1. the ratio of the line length to the arrowhead % length is large % 2. the view is highly perspective.% compute stoppoints tmp1=X0.*(ones(4,1)*(len0./D))+Xf.*(ones(4,1)*(1-len0./D)); if (oneax), tmp3=invT*tmp1; else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=invT.*tmp1; tmp2=zeros(4,4*narrows); tmp2(:)=tmp1(:); tmp3=zeros(4,narrows); tmp3(:)=sum(tmp2)'; end; stoppoint = tmp3(1:3,:)./(ones(3,1)*tmp3(4,:)).*axr+axm;% compute tippoints tmp1=X0.*(ones(4,1)*(len1./D))+Xf.*(ones(4,1)*(1-len1./D)); if (oneax), tmp3=invT*tmp1; else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=invT.*tmp1; tmp2=zeros(4,4*narrows); tmp2(:)=tmp1(:); tmp3=zeros(4,narrows); tmp3(:)=sum(tmp2)'; end; tippoint = tmp3(1:3,:)./(ones(3,1)*tmp3(4,:)).*axr+axm;% compute basepoints tmp1=X0.*(ones(4,1)*(len2./D))+Xf.*(ones(4,1)*(1-len2./D)); if (oneax), tmp3=invT*tmp1; else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=invT.*tmp1; tmp2=zeros(4,4*narrows); tmp2(:)=tmp1(:); tmp3=zeros(4,narrows); tmp3(:)=sum(tmp2)'; end; basepoint = tmp3(1:3,:)./(ones(3,1)*tmp3(4,:)).*axr+axm;% compute startpoints tmp1=X0.*(ones(4,1)*(1-slen0./D))+Xf.*(ones(4,1)*(slen0./D)); if (oneax), tmp3=invT*tmp1; else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=invT.*tmp1; tmp2=zeros(4,4*narrows); tmp2(:)=tmp1(:); tmp3=zeros(4,narrows); tmp3(:)=sum(tmp2)'; end; startpoint = tmp3(1:3,:)./(ones(3,1)*tmp3(4,:)).*axr+axm;% compute stippoints tmp1=X0.*(ones(4,1)*(1-slen1./D))+Xf.*(ones(4,1)*(slen1./D)); if (oneax), tmp3=invT*tmp1; else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=invT.*tmp1; tmp2=zeros(4,4*narrows); tmp2(:)=tmp1(:); tmp3=zeros(4,narrows); tmp3(:)=sum(tmp2)'; end; stippoint = tmp3(1:3,:)./(ones(3,1)*tmp3(4,:)).*axr+axm;% compute sbasepoints tmp1=X0.*(ones(4,1)*(1-slen2./D))+Xf.*(ones(4,1)*(slen2./D)); if (oneax), tmp3=invT*tmp1; else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=invT.*tmp1; tmp2=zeros(4,4*narrows); tmp2(:)=tmp1(:); tmp3=zeros(4,narrows); tmp3(:)=sum(tmp2)'; end; sbasepoint = tmp3(1:3,:)./(ones(3,1)*tmp3(4,:)).*axr+axm;% compute cross-arrow directions for arrows with NormalDir specifiedif (any(imag(crossdir(:))~=0)), ii = find(any(imag(crossdir)~=0)); crossdir(:,ii) = cross((stop(:,ii)-start(:,ii))./axr(:,ii), ... imag(crossdir(:,ii))).*axr(:,ii);end;% compute cross-arrow directionsbasecross = crossdir + basepoint;tipcross = crossdir + tippoint;sbasecross = crossdir + sbasepoint;stipcross = crossdir + stippoint;ii = find(all(crossdir==0)|any(isnan(crossdir)));if ~isempty(ii), numii = length(ii); % transform start points tmp1 = [basepoint(:,ii) tippoint(:,ii) sbasepoint(:,ii) stippoint(:,ii)]; tmp1 = (tmp1-axm(:,[ii ii ii ii])) ./ axr(:,[ii ii ii ii]); tmp1 = [tmp1; ones(1,4*numii)]; if (oneax), X0=T*tmp1; else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=T(:,[ii ii ii ii]).*tmp1; tmp2=zeros(4,16*numii); tmp2(:)=tmp1(:); X0=zeros(4,4*numii); X0(:)=sum(tmp2)'; end; X0=X0./(ones(4,1)*X0(4,:)); % transform stop points tmp1 = [(2*stop(:,ii)-start(:,ii)-axm(:,ii))./axr(:,ii);ones(1,numii)]; tmp1 = [tmp1 tmp1 tmp1 tmp1]; if (oneax), Xf=T*tmp1; else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=T(:,[ii ii ii ii]).*tmp1; tmp2=zeros(4,16*numii); tmp2(:)=tmp1(:); Xf=zeros(4,4*numii); Xf(:)=sum(tmp2)'; end; Xf=Xf./(ones(4,1)*Xf(4,:)); % compute perpendicular directions pixfact = ((limrange(1,ii)./limrange(2,ii)).*(ap(2,ii)./ap(1,ii))).^2; pixfact = [pixfact pixfact pixfact pixfact]; pixfact = [pixfact;1./pixfact]; [dummyval,jj] = max(abs(Xf(1:2,:)-X0(1:2,:))); jj1 = ((1:4)'*ones(1,length(jj))==ones(4,1)*jj); jj2 = ((1:4)'*ones(1,length(jj))==ones(4,1)*(3-jj)); jj3 = jj1(1:2,:); Xf(jj1)=Xf(jj1)+(Xf(jj1)-X0(jj1)==0); %eaj new 2/24/98 Xp = X0; Xp(jj2) = X0(jj2) + ones(sum(jj2(:)),1); Xp(jj1) = X0(jj1) - (Xf(jj2)-X0(jj2))./(Xf(jj1)-X0(jj1)) .* pixfact(jj3); % inverse transform the cross points if (oneax), Xp=invT*Xp; else, tmp1=[Xp;Xp;Xp;Xp]; tmp1=invT(:,[ii ii ii ii]).*tmp1; tmp2=zeros(4,16*numii); tmp2(:)=tmp1(:); Xp=zeros(4,4*numii); Xp(:)=sum(tmp2)'; end; Xp=(Xp(1:3,:)./(ones(3,1)*Xp(4,:))).*axr(:,[ii ii ii ii])+axm(:,[ii ii ii ii]); basecross(:,ii) = Xp(:,0*numii+(1:numii)); tipcross(:,ii) = Xp(:,1*numii+(1:numii)); sbasecross(:,ii) = Xp(:,2*numii+(1:numii)); stipcross(:,ii) = Xp(:,3*numii+(1:numii));end;% compute all points% compute start points axm11 = [axm axm axm axm axm axm axm axm axm axm axm]; axr11 = [axr axr axr axr axr axr axr axr axr axr axr]; st = [stoppoint tippoint basepoint sbasepoint stippoint startpoint stippoint sbasepoint basepoint tippoint stoppoint]; tmp1 = (st - axm11) ./ axr11; tmp1 = [tmp1; ones(1,size(tmp1,2))]; if (oneax), X0=T*tmp1; else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=[T T T T T T T T T T T].*tmp1; tmp2=zeros(4,44*narrows); tmp2(:)=tmp1(:); X0=zeros(4,11*narrows); X0(:)=sum(tmp2)'; end; X0=X0./(ones(4,1)*X0(4,:));% compute stop points tmp1 = ([start tipcross basecross sbasecross stipcross stop stipcross sbasecross basecross tipcross start] ... - axm11) ./ axr11; tmp1 = [tmp1; ones(1,size(tmp1,2))]; if (oneax), Xf=T*tmp1; else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=[T T T T T T T T T T T].*tmp1; tmp2=zeros(4,44*narrows); tmp2(:)=tmp1(:); Xf=zeros(4,11*narrows); Xf(:)=sum(tmp2)'; end; Xf=Xf./(ones(4,1)*Xf(4,:));% compute lengths len0 = len.*((ends==1)|(ends==3)).*tan(tipangle/180*pi); slen0 = len.*((ends==2)|(ends==3)).*tan(tipangle/180*pi); le = [zeros(1,narrows) len0 wid/2 wid/2 slen0 zeros(1,narrows) -slen0 -wid/2 -wid/2 -len0 zeros(1,narrows)]; aprange = ap./limrange; aprange = [aprange aprange aprange aprange aprange aprange aprange aprange aprange aprange aprange]; D = sqrt(sum(((Xf(1:2,:)-X0(1:2,:)).*aprange).^2)); Dii=find(D==0); if ~isempty(Dii), D=D+(D==0); le(Dii)=zeros(1,length(Dii)); end; %should fix DivideByZero warnings tmp1 = X0.*(ones(4,1)*(1-le./D)) + Xf.*(ones(4,1)*(le./D));% inverse transform if (oneax), tmp3=invT*tmp1; else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=[invT invT invT invT invT invT invT invT invT invT invT].*tmp1; tmp2=zeros(4,44*narrows); tmp2(:)=tmp1(:); tmp3=zeros(4,11*narrows); tmp3(:)=sum(tmp2)'; end; pts = tmp3(1:3,:)./(ones(3,1)*tmp3(4,:)) .* axr11 + axm11;% correct for ones where the crossdir was specifiedii = find(~(all(crossdir==0)|any(isnan(crossdir))));if ~isempty(ii), D1 = [pts(:,1*narrows+ii)-pts(:,9*narrows+ii) ... pts(:,2*narrows+ii)-pts(:,8*narrows+ii) ... pts(:,3*narrows+ii)-pts(:,7*narrows+ii) ... pts(:,4*narrows+ii)-pts(:,6*narrows+ii) ... pts(:,6*narrows+ii)-pts(:,4*narrows+ii) ... pts(:,7*narrows+ii)-pts(:,3*narrows+ii) ... pts(:,8*narrows+ii)-pts(:,2*narrows+ii) ... pts(:,9*narrows+ii)-pts(:,1*narrows+ii)]/2; ii = ii'*ones(1,8) + ones(length(ii),1)*[1:4 6:9]*narrows; ii = ii(:)'; pts(:,ii) = st(:,ii) + D1;end;% readjust for reverse directionsiicols=(1:narrows)'; iicols=iicols(:,ones(1,11)); iicols=iicols(:).';tmp1=axrev(:,iicols);ii = find(tmp1(:)); if ~isempty(ii), pts(ii)=-pts(ii); end;% readjust for log scale on axestmp1=xyzlog(:,iicols);ii = find(tmp1(:)); if ~isempty(ii), pts(ii)=10.^pts(ii); end;% compute the x,y,z coordinates of the patches;ii = narrows*(0:10)'*ones(1,narrows) + ones(11,1)*(1:narrows);ii = ii(:)';x = zeros(11,narrows);y = zeros(11,narrows);z = zeros(11,narrows);x(:) = pts(1,ii)';y(:) = pts(2,ii)';z(:) = pts(3,ii)';% do the outputif (nargout<=1),% % create or modify the patches newpatch = trueornan(ispatch) & (isempty(oldh)|~strcmp(get(oldh,'Type'),'patch')); newline = ~trueornan(ispatch) & (isempty(oldh)|~strcmp(get(oldh,'Type'),'line')); if isempty(oldh), H=zeros(narrows,1); else, H=oldh; end;% % make or modify the arrows for k=1:narrows, if all(isnan(ud(k,[3 6])))&arrow_is2DXY(ax(k)), zz=[]; else, zz=z(:,k); end; % work around a MATLAB 6.x OpenGL bug -- 7/28/02 xx=x(:,k); yy=y(:,k); mask=any([ones(1,2+size(zz,2));diff([xx yy zz],[],1)],2); xx=xx(mask); yy=yy(mask); if ~isempty(zz), zz=zz(mask); end; % plot the patch or line xyz = {'XData',xx,'YData',yy,'ZData',zz,'Tag',ArrowTag}; if newpatch(k)|newline(k), if newpatch(k), H(k) = patch(xyz{:}); else, H(k) = line(xyz{:}); end; if ~isempty(oldh), arrow_copyprops(oldh(k),H(k)); end; else, if ispatch(k), xyz={xyz{:},'CData',[]}; end; set(H(k),xyz{:}); end; end; if ~isempty(oldh), delete(oldh(oldh~=H)); end;% % additional properties set(H,'Clipping','off'); set(H,{'UserData'},num2cell(ud,2)); if (length(extraprops)>0), set(H,extraprops{:}); end; % handle choosing arrow Start and/or Stop locations if unspecified [H,oldaxlims,errstr] = arrow_clicks(H,ud,x,y,z,ax,oldaxlims); if ~isempty(errstr), error([upper(mfilename) ' got ' errstr]); end; % set the output if (nargout>0), h=H; end; % make sure the axis limits did not change if isempty(oldaxlims), ARROW_AXLIMITS = []; else, lims = get(oldaxlims(:,1),{'XLim','YLim','ZLim'})'; lims = reshape(cat(2,lims{:}),6,size(lims,2)); mask = arrow_is2DXY(oldaxlims(:,1)); oldaxlims(mask,6:7) = lims(5:6,mask)'; ARROW_AXLIMITS = oldaxlims(find(any(oldaxlims(:,2:7)'~=lims)),:); if ~isempty(ARROW_AXLIMITS), warning(arrow_warnlimits(ARROW_AXLIMITS,narrows)); end; end;else, % don't create the patch, just return the data h=x; yy=y; zz=z;end;function out = arrow_defcheck(in,def,prop)% check if we got 'default' values out = in; if ~isstr(in), return; end; if size(in,1)==1 & strncmp(lower(in),'def',3), out = def; elseif ~isempty(prop), error([upper(mfilename) ' does not recognize ''' in(:)' ''' as a valid ''' prop ''' string.']); end;function [H,oldaxlims,errstr] = arrow_clicks(H,ud,x,y,z,ax,oldaxlims)% handle choosing arrow Start and/or Stop locations if necessary errstr = ''; if isempty(H)|isempty(ud)|isempty(x), return; end; % determine which (if any) need Start and/or Stop needStart = all(isnan(ud(:,1:3)'))'; needStop = all(isnan(ud(:,4:6)'))'; mask = any(needStart|needStop); if ~any(mask), return; end; ud(~mask,:)=[]; ax(:,~mask)=[]; x(:,~mask)=[]; y(:,~mask)=[]; z(:,~mask)=[]; % make them invisible for the time being set(H,'Visible','off'); % save the current axes and limits modes; set to manual for the time being oldAx = gca; limModes=get(ax(:),{'XLimMode','YLimMode','ZLimMode'}); set(ax(:),{'XLimMode','YLimMode','ZLimMode'},{'manual','manual','manual'}); % loop over each arrow that requires attention jj = find(mask); for ii=1:length(jj), h = H(jj(ii)); axes(ax(ii)); % figure out correct call if needStart(ii), prop='Start'; else, prop='Stop'; end; [wasInterrupted,errstr] = arrow_click(needStart(ii)&needStop(ii),h,prop,ax(ii)); % handle errors and control-C if wasInterrupted, delete(H(jj(ii:end))); H(jj(ii:end))=[]; oldaxlims(jj(ii:end),:)=[]; break; end; end; % restore the axes and limit modes axes(oldAx); set(ax(:),{'XLimMode','YLimMode','ZLimMode'},limModes);function [wasInterrupted,errstr] = arrow_click(lockStart,H,prop,ax)% handle the clicks for one arrow fig = get(ax,'Parent'); % save some things oldFigProps = {'Pointer','WindowButtonMotionFcn','WindowButtonUpFcn'}; oldFigValue = get(fig,oldFigProps); oldArrowProps = {'EraseMode'}; oldArrowValue = get(H,oldArrowProps); set(H,'EraseMode','background'); %because 'xor' makes shaft invisible unless Width>1 global ARROW_CLICK_H ARROW_CLICK_PROP ARROW_CLICK_AX ARROW_CLICK_USE_Z ARROW_CLICK_H=H; ARROW_CLICK_PROP=prop; ARROW_CLICK_AX=ax; ARROW_CLICK_USE_Z=~arrow_is2DXY(ax)|~arrow_planarkids(ax); set(fig,'Pointer','crosshair'); % set up the WindowButtonMotion so we can see the arrow while moving around set(fig,'WindowButtonUpFcn','set(gcf,''WindowButtonUpFcn'','''')', ...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -