📄 arrow3.m
字号:
'WindowButtonMotionFcn',''); if ~lockStart, set(H,'Visible','on'); set(fig,'WindowButtonMotionFcn',[mfilename '(''callback'',''motion'');']); end; % wait for the button to be pressed [wasKeyPress,wasInterrupted,errstr] = arrow_wfbdown(fig); % if we wanted to click-drag, set the Start point if lockStart & ~wasInterrupted, pt = arrow_point(ARROW_CLICK_AX,ARROW_CLICK_USE_Z); feval(mfilename,H,'Start',pt,'Stop',pt); set(H,'Visible','on'); ARROW_CLICK_PROP='Stop'; set(fig,'WindowButtonMotionFcn',[mfilename '(''callback'',''motion'');']); % wait for the mouse button to be released eval('waitfor(fig,''WindowButtonUpFcn'','''');','wasInterrupted=1;'); if wasInterrupted, errstr=lasterr; end; end; if ~wasInterrupted, feval(mfilename,'callback','motion'); end; % restore some things set(gcf,oldFigProps,oldFigValue); set(H,oldArrowProps,oldArrowValue);function arrow_callback(varargin)% handle redrawing callbacks if nargin==0, return; end; str = varargin{1}; if ~isstr(str), error([upper(mfilename) ' got an invalid Callback command.']); end; s = lower(str); if strcmp(s,'motion'), % motion callback global ARROW_CLICK_H ARROW_CLICK_PROP ARROW_CLICK_AX ARROW_CLICK_USE_Z feval(mfilename,ARROW_CLICK_H,ARROW_CLICK_PROP,arrow_point(ARROW_CLICK_AX,ARROW_CLICK_USE_Z)); drawnow; else, error([upper(mfilename) ' does not recognize ''' str(:).' ''' as a valid Callback option.']); end;function out = arrow_point(ax,use_z)% return the point on the given axes if nargin==0, ax=gca; end; if nargin<2, use_z=~arrow_is2DXY(ax)|~arrow_planarkids(ax); end; out = get(ax,'CurrentPoint'); out = out(1,:); if ~use_z, out=out(1:2); end;function [wasKeyPress,wasInterrupted,errstr] = arrow_wfbdown(fig)% wait for button down ignoring object ButtonDownFcn's if nargin==0, fig=gcf; end; errstr = ''; % save ButtonDownFcn values objs = findobj(fig); buttonDownFcns = get(objs,'ButtonDownFcn'); mask=~strcmp(buttonDownFcns,''); objs=objs(mask); buttonDownFcns=buttonDownFcns(mask); set(objs,'ButtonDownFcn',''); % save other figure values figProps = {'KeyPressFcn','WindowButtonDownFcn'}; figValue = get(fig,figProps); % do the real work set(fig,'KeyPressFcn','set(gcf,''KeyPressFcn'','''',''WindowButtonDownFcn'','''');', ... 'WindowButtonDownFcn','set(gcf,''WindowButtonDownFcn'','''')'); lasterr(''); wasInterrupted=0; eval('waitfor(fig,''WindowButtonDownFcn'','''');','wasInterrupted=1;'); wasKeyPress = ~wasInterrupted & strcmp(get(fig,'KeyPressFcn'),''); if wasInterrupted, errstr=lasterr; end; % restore ButtonDownFcn and other figure values set(objs,'ButtonDownFcn',buttonDownFcns); set(fig,figProps,figValue);function [out,is2D] = arrow_is2DXY(ax)% check if axes are 2-D X-Y plots % may not work for modified camera angles, etc. out = logical(zeros(size(ax))); % 2-D X-Y plots is2D = out; % any 2-D plots views = get(ax(:),{'View'}); views = cat(1,views{:}); out(:) = abs(views(:,2))==90; is2D(:) = out(:) | all(rem(views',90)==0)';function out = arrow_planarkids(ax)% check if axes descendents all have empty ZData (lines,patches,surfaces) out = logical(ones(size(ax))); allkids = get(ax(:),{'Children'}); for k=1:length(allkids), kids = get([findobj(allkids{k},'flat','Type','line') findobj(allkids{k},'flat','Type','patch') findobj(allkids{k},'flat','Type','surface')],{'ZData'}); for j=1:length(kids), if ~isempty(kids{j}), out(k)=logical(0); break; end; end; end;function arrow_fixlimits(axlimits)% reset the axis limits as necessary if isempty(axlimits), disp([upper(mfilename) ' does not remember any axis limits to reset.']); end; for k=1:size(axlimits,1), if any(get(axlimits(k,1),'XLim')~=axlimits(k,2:3)), set(axlimits(k,1),'XLim',axlimits(k,2:3)); end; if any(get(axlimits(k,1),'YLim')~=axlimits(k,4:5)), set(axlimits(k,1),'YLim',axlimits(k,4:5)); end; if any(get(axlimits(k,1),'ZLim')~=axlimits(k,6:7)), set(axlimits(k,1),'ZLim',axlimits(k,6:7)); end; end;function out = arrow_WarpToFill(notstretched,manualcamera,curax)% check if we are in "WarpToFill" mode. out = strcmp(get(curax,'WarpToFill'),'on'); % 'WarpToFill' is undocumented, so may need to replace this by % out = ~( any(notstretched) & any(manualcamera) );function out = arrow_warnlimits(axlimits,narrows)% create a warning message if we've changed the axis limits msg = ''; switch (size(axlimits,1)) case 1, msg=''; case 2, msg='on two axes '; otherwise, msg='on several axes '; end; msg = [upper(mfilename) ' changed the axis limits ' msg ... 'when adding the arrow']; if (narrows>1), msg=[msg 's']; end; out = [msg '.' sprintf('\n') ' Call ' upper(mfilename) ... ' FIXLIMITS to reset them now.'];function arrow_copyprops(fm,to)% copy line properties to patches props = {'EraseMode','LineStyle','LineWidth','Marker','MarkerSize',... 'MarkerEdgeColor','MarkerFaceColor','ButtonDownFcn', ... 'Clipping','DeleteFcn','BusyAction','HandleVisibility', ... 'Selected','SelectionHighlight','Visible'}; lineprops = {'Color', props{:}}; patchprops = {'EdgeColor',props{:}}; patch2props = {'FaceColor',patchprops{:}}; fmpatch = strcmp(get(fm,'Type'),'patch'); topatch = strcmp(get(to,'Type'),'patch'); set(to( fmpatch& topatch),patch2props,get(fm( fmpatch& topatch),patch2props)); %p->p set(to(~fmpatch&~topatch),lineprops, get(fm(~fmpatch&~topatch),lineprops )); %l->l set(to( fmpatch&~topatch),lineprops, get(fm( fmpatch&~topatch),patchprops )); %p->l set(to(~fmpatch& topatch),patchprops, get(fm(~fmpatch& topatch),lineprops) ,'FaceColor','none'); %l->pfunction arrow_props% display further help info about ARROW properties c = sprintf('\n'); disp([c ... 'ARROW Properties: Default values are given in [square brackets], and other' c ... ' acceptable equivalent property names are in (parenthesis).' c c ... ' Start The starting points. For N arrows, B' c ... ' this should be a Nx2 or Nx3 matrix. /|\ ^' c ... ' Stop The end points. For N arrows, this /|||\ |' c ... ' should be a Nx2 or Nx3 matrix. //|||\\ L|' c ... ' Length Length of the arrowhead (in pixels on ///|||\\\ e|' c ... ' screen, points on a page). [16] (Len) ////|||\\\\ n|' c ... ' BaseAngle Angle (degrees) of the base angle /////|D|\\\\\ g|' c ... ' ADE. For a simple stick arrow, use //// ||| \\\\ t|' c ... ' BaseAngle=TipAngle. [90] (Base) /// ||| \\\ h|' c ... ' TipAngle Angle (degrees) of tip angle ABC. //<----->|| \\ |' c ... ' [16] (Tip) / base ||| \ V' c ... ' Width Width of the base in pixels. Not E angle ||<-------->C' c ... ' the ''LineWidth'' prop. [0] (Wid) |||tipangle' c ... ' Page If provided, non-empty, and not NaN, |||' c ... ' this causes ARROW to use hardcopy |||' c ... ' rather than onscreen proportions. A' c ... ' This is important if screen aspect --> <-- width' c ... ' ratio and hardcopy aspect ratio are ----CrossDir---->' c ... ' vastly different. []' c... ' CrossDir A vector giving the direction towards which the fletches' c ... ' on the arrow should go. [computed such that it is perpen-' c ... ' dicular to both the arrow direction and the view direction' c ... ' (i.e., as if it was pasted on a normal 2-D graph)] (Note' c ... ' that CrossDir is a vector. Also note that if an axis is' c ... ' plotted on a log scale, then the corresponding component' c ... ' of CrossDir must also be set appropriately, i.e., to 1 for' c ... ' no change in that direction, >1 for a positive change, >0' c ... ' and <1 for negative change.)' c ... ' NormalDir A vector normal to the fletch direction (CrossDir is then' c ... ' computed by the vector cross product [Line]x[NormalDir]). []' c ... ' (Note that NormalDir is a vector. Unlike CrossDir,' c ... ' NormalDir is used as is regardless of log-scaled axes.)' c ... ' Ends Set which end has an arrowhead. Valid values are ''none'',' c ... ' ''stop'', ''start'', and ''both''. [''stop''] (End)' c... ' ObjectHandles Vector of handles to previously-created arrows to be' c ... ' updated or line objects to be converted to arrows.' c ... ' [] (Object,Handle)' c ]);function out = arrow_demo % demo % create the data [x,y,z] = peaks; [ddd,out.iii]=max(z(:)); out.axlim = [min(x(:)) max(x(:)) min(y(:)) max(y(:)) min(z(:)) max(z(:))]; % modify it by inserting some NaN's [m,n] = size(z); m = floor(m/2); n = floor(n/2); z(1:m,1:n) = NaN*ones(m,n); % graph it clf('reset'); out.hs=surf(x,y,z); out.x=x; out.y=y; out.z=z; xlabel('x'); ylabel('y'); function h = arrow_demo3(in) % set the view axlim = in.axlim; axis(axlim); zlabel('z'); %set(in.hs,'FaceColor','interp'); view(viewmtx(-37.5,30,20)); title(['Demo of the capabilities of the ARROW function in 3-D']); % Normal blue arrow h1 = feval(mfilename,[axlim(1) axlim(4) 4],[-.8 1.2 4], ... 'EdgeColor','b','FaceColor','b'); % Normal white arrow, clipped by the surface h2 = feval(mfilename,axlim([1 4 6]),[0 2 4]); t=text(-2.4,2.7,7.7,'arrow clipped by surf'); % Baseangle<90 h3 = feval(mfilename,[3 .125 3.5],[1.375 0.125 3.5],30,50); t2=text(3.1,.125,3.5,'local maximum'); % Baseangle<90, fill and edge colors different h4 = feval(mfilename,axlim(1:2:5)*.5,[0 0 0],36,60,25, ... 'EdgeColor','b','FaceColor','c'); t3=text(axlim(1)*.5,axlim(3)*.5,axlim(5)*.5-.75,'origin'); set(t3,'HorizontalAlignment','center'); % Baseangle>90, black fill h5 = feval(mfilename,[-2.9 2.9 3],[-1.3 .4 3.2],30,120,[],6, ... 'EdgeColor','r','FaceColor','k','LineWidth',2); % Baseangle>90, no fill h6 = feval(mfilename,[-2.9 2.9 1.3],[-1.3 .4 1.5],30,120,[],6, ... 'EdgeColor','r','FaceColor','none','LineWidth',2); % Stick arrow h7 = feval(mfilename,[-1.6 -1.65 -6.5],[0 -1.65 -6.5],[],16,16); t4=text(-1.5,-1.65,-7.25,'global mininum'); set(t4,'HorizontalAlignment','center'); % Normal, black fill h8 = feval(mfilename,[-1.4 0 -7.2],[-1.4 0 -3],'FaceColor','k'); t5=text(-1.5,0,-7.75,'local minimum'); set(t5,'HorizontalAlignment','center'); % Gray fill, crossdir specified, 'LineStyle' -- h9 = feval(mfilename,[-3 2.2 -6],[-3 2.2 -.05],36,[],27,6,[],[0 -1 0], ... 'EdgeColor','k','FaceColor',.75*[1 1 1],'LineStyle','--'); % a series of normal arrows, linearly spaced, crossdir specified h10y=(0:4)'/3; h10 = feval(mfilename,[-3*ones(size(h10y)) h10y -6.5*ones(size(h10y))], ... [-3*ones(size(h10y)) h10y -.05*ones(size(h10y))], ... 12,[],[],[],[],[0 -1 0]); % a series of normal arrows, linearly spaced h11x=(1:.33:2.8)'; h11 = feval(mfilename,[h11x -3*ones(size(h11x)) 6.5*ones(size(h11x))], ... [h11x -3*ones(size(h11x)) -.05*ones(size(h11x))]); % series of magenta arrows, radially oriented, crossdir specified h12x=2; h12y=-3; h12z=axlim(5)/2; h12xr=1; h12zr=h12z; ir=.15;or=.81; h12t=(0:11)'/6*pi; h12 = feval(mfilename, ... [h12x+h12xr*cos(h12t)*ir h12y*ones(size(h12t)) ... h12z+h12zr*sin(h12t)*ir],[h12x+h12xr*cos(h12t)*or ... h12y*ones(size(h12t)) h12z+h12zr*sin(h12t)*or], ... 10,[],[],[],[], ... [-h12xr*sin(h12t) zeros(size(h12t)) h12zr*cos(h12t)],... 'FaceColor','none','EdgeColor','m'); % series of normal arrows, tangentially oriented, crossdir specified or13=.91; h13t=(0:.5:12)'/6*pi; locs = [h12x+h12xr*cos(h13t)*or13 h12y*ones(size(h13t)) h12z+h12zr*sin(h13t)*or13]; h13 = feval(mfilename,locs(1:end-1,:),locs(2:end,:),6); % arrow with no line ==> oriented downwards h14 = feval(mfilename,[3 3 .100001],[3 3 .1],30); t6=text(3,3,3.6,'no line'); set(t6,'HorizontalAlignment','center'); % arrow with arrowheads at both ends h15 = feval(mfilename,[-.5 -3 -3],[1 -3 -3],'Ends','both','FaceColor','g', ... 'Length',20,'Width',3,'CrossDir',[0 0 1],'TipAngle',25); h=[h1;h2;h3;h4;h5;h6;h7;h8;h9;h10;h11;h12;h13;h14;h15];function h = arrow_demo2(in) axlim = in.axlim; dolog = 1; if (dolog), set(in.hs,'YData',10.^get(in.hs,'YData')); end; shading('interp'); view(2); title(['Demo of the capabilities of the ARROW function in 2-D']); hold on; [C,H]=contour(in.x,in.y,in.z,20,'-'); hold off; for k=H', set(k,'ZData',(axlim(6)+1)*ones(size(get(k,'XData'))),'Color','k'); if (dolog), set(k,'YData',10.^get(k,'YData')); end; end; if (dolog), axis([axlim(1:2) 10.^axlim(3:4)]); set(gca,'YScale','log'); else, axis(axlim(1:4)); end; % Normal blue arrow start = [axlim(1) axlim(4) axlim(6)+2]; stop = [in.x(in.iii) in.y(in.iii) axlim(6)+2]; if (dolog), start(:,2)=10.^start(:,2); stop(:,2)=10.^stop(:,2); end; h1 = feval(mfilename,start,stop,'EdgeColor','b','FaceColor','b'); % three arrows with varying fill, width, and baseangle start = [-3 -3 10; -3 -1.5 10; -1.5 -3 10]; stop = [-.03 -.03 10; -.03 -1.5 10; -1.5 -.03 10]; if (dolog), start(:,2)=10.^start(:,2); stop(:,2)=10.^stop(:,2); end; h2 = feval(mfilename,start,stop,24,[90;60;120],[],[0;0;4],'Ends',str2mat('both','stop','stop')); set(h2(2),'EdgeColor',[0 .35 0],'FaceColor',[0 .85 .85]); set(h2(3),'EdgeColor','r','FaceColor',[1 .5 1]); h=[h1;h2];function out = trueornan(x)if isempty(x), out=x;else, out = isnan(x); out(~out) = x(~out);end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -