📄 arrow3.m
字号:
function [h,yy,zz] = arrow(varargin)% ARROW Draw a line with an arrowhead.%% ARROW(Start,Stop) draws a line with an arrow from Start to Stop (points% should be vectors of length 2 or 3, or matrices with 2 or 3% columns), and returns the graphics handle of the arrow(s).%% ARROW uses the mouse (click-drag) to create an arrow.%% ARROW DEMO & ARROW DEMO2 show 3-D & 2-D demos of the capabilities of ARROW.%% ARROW may be called with a normal argument list or a property-based list.% ARROW(Start,Stop,Length,BaseAngle,TipAngle,Width,Page,CrossDir) is% the full normal argument list, where all but the Start and Stop% points are optional. If you need to specify a later argument (e.g.,% Page) but want default values of earlier ones (e.g., TipAngle),% pass an empty matrix for the earlier ones (e.g., TipAngle=[]).%% ARROW('Property1',PropVal1,'Property2',PropVal2,...) creates arrows with the% given properties, using default values for any unspecified or given as% 'default' or NaN. Some properties used for line and patch objects are% used in a modified fashion, others are passed directly to LINE, PATCH,% or SET. For a detailed properties explanation, call ARROW PROPERTIES.%% Start The starting points. B% Stop The end points. /|\ ^% Length Length of the arrowhead in pixels. /|||\ |% BaseAngle Base angle in degrees (ADE). //|||\\ L|% TipAngle Tip angle in degrees (ABC). ///|||\\\ e|% Width Width of the base in pixels. ////|||\\\\ n|% Page Use hardcopy proportions. /////|D|\\\\\ g|% CrossDir Vector || to arrowhead plane. //// ||| \\\\ t|% NormalDir Vector out of arrowhead plane. /// ||| \\\ h|% Ends Which end has an arrowhead. //<----->|| \\ |% ObjectHandles Vector of handles to update. / base ||| \ V% E angle||<-------->C% ARROW(H,'Prop1',PropVal1,...), where H is a |||tipangle% vector of handles to previously-created arrows |||% and/or line objects, will update the previously- |||% created arrows according to the current view -->|A|<-- width% and any specified properties, and will convert% two-point line objects to corresponding arrows. ARROW(H) will update% the arrows if the current view has changed. Root, figure, or axes% handles included in H are replaced by all descendant Arrow objects.%% A property list can follow any specified normal argument list, e.g.,% ARROW([1 2 3],[0 0 0],36,'BaseAngle',60) creates an arrow from (1,2,3) to% the origin, with an arrowhead of length 36 pixels and 60-degree base angle.%% The basic arguments or properties can generally be vectorized to create% multiple arrows with the same call. This is done by passing a property% with one row per arrow, or, if all arrows are to have the same property% value, just one row may be specified.%% You may want to execute AXIS(AXIS) before calling ARROW so it doesn't change% the axes on you; ARROW determines the sizes of arrow components BEFORE the% arrow is plotted, so if ARROW changes axis limits, arrows may be malformed.%% This version of ARROW uses features of MATLAB 5 and is incompatible with% earlier MATLAB versions (ARROW for MATLAB 4.2c is available separately);% some problems with perspective plots still exist.% Copyright (c)1995-2002, Dr. Erik A. Johnson <JohnsonE@usc.edu>, 11/15/02% Revision history:% 11/15/02 EAJ Accomodate how MATLAB 6.5 handles NaN and logicals% 7/28/02 EAJ Tried (but failed) work-around for MATLAB 6.x / OpenGL bug% if zero 'Width' or not double-ended% 11/10/99 EAJ Add logical() to eliminate zero index problem in MATLAB 5.3.% 11/10/99 EAJ Corrected warning if axis limits changed on multiple axes.% 11/10/99 EAJ Update e-mail address.% 2/10/99 EAJ Some documentation updating.% 2/24/98 EAJ Fixed bug if Start~=Stop but both colinear with viewpoint.% 8/14/97 EAJ Added workaround for MATLAB 5.1 scalar logical transpose bug.% 7/21/97 EAJ Fixed a few misc bugs.% 7/14/97 EAJ Make arrow([],'Prop',...) do nothing (no old handles)% 6/23/97 EAJ MATLAB 5 compatible version, release.% 5/27/97 EAJ Added Line Arrows back in. Corrected a few bugs.% 5/26/97 EAJ Changed missing Start/Stop to mouse-selected arrows.% 5/19/97 EAJ MATLAB 5 compatible version, beta.% 4/13/97 EAJ MATLAB 5 compatible version, alpha.% 1/31/97 EAJ Fixed bug with multiple arrows and unspecified Z coords.% 12/05/96 EAJ Fixed one more bug with log plots and NormalDir specified% 10/24/96 EAJ Fixed bug with log plots and NormalDir specified% 11/13/95 EAJ Corrected handling for 'reverse' axis directions% 10/06/95 EAJ Corrected occasional conflict with SUBPLOT% 4/24/95 EAJ A major rewrite.% Fall 94 EAJ Original code.% Things to be done:% - segment parsing, computing, and plotting into separate subfunctions% - change computing from Xform to Camera paradigms% + this will help especially with 3-D perspective plots% + if the WarpToFill section works right, remove warning code% + when perpsective works properly, remove perspective warning code% - add cell property values and struct property name/values (like get/set)% - get rid of NaN as the "default" data label% + perhaps change userdata to a struct and don't include (or leave% empty) the values specified as default; or use a cell containing% an empty matrix for a default value% - add functionality of GET to retrieve current values of ARROW properties% Many thanks to Keith Rogers <kerog@ai.mit.com> for his many excellent% suggestions and beta testing. Check out his shareware package MATDRAW% (at ftp://ftp.mathworks.com/pub/contrib/v5/graphics/matdraw/) -- he has% permission to distribute ARROW with MATDRAW.% Permission is granted to distribute ARROW with the toolboxes for the book% "Solving Solid Mechanics Problems with MATLAB 5", by F. Golnaraghi et al.% (Prentice Hall, 1999).% global variable initializationglobal ARROW_PERSP_WARN ARROW_STRETCH_WARN ARROW_AXLIMITSif isempty(ARROW_PERSP_WARN ), ARROW_PERSP_WARN =1; end;if isempty(ARROW_STRETCH_WARN), ARROW_STRETCH_WARN=1; end;% Handle callbacksif (nargin>0 & isstr(varargin{1}) & strcmp(lower(varargin{1}),'callback')), arrow_callback(varargin{2:end}); return;end;% Are we doing the demo?c = sprintf('\n');if (nargin==1 & isstr(varargin{1})), arg1 = lower(varargin{1}); if strncmp(arg1,'prop',4), arrow_props; elseif strncmp(arg1,'demo',4) clf reset demo_info = arrow_demo; if ~strncmp(arg1,'demo2',5), hh=arrow_demo3(demo_info); else, hh=arrow_demo2(demo_info); end; if (nargout>=1), h=hh; end; elseif strncmp(arg1,'fixlimits',3), arrow_fixlimits(ARROW_AXLIMITS); ARROW_AXLIMITS=[]; elseif strncmp(arg1,'help',4), disp(help(mfilename)); else, error([upper(mfilename) ' got an unknown single-argument string ''' deblank(arg1) '''.']); end; return;end;% Check # of argumentsif (nargout>3), error([upper(mfilename) ' produces at most 3 output arguments.']); end;% find first property numberfirstprop = nargin+1;for k=1:length(varargin), if ~isnumeric(varargin{k}), firstprop=k; break; end; end;lastnumeric = firstprop-1;% check property listif (firstprop<=nargin), for k=firstprop:2:nargin, curarg = varargin{k}; if ~isstr(curarg) | sum(size(curarg)>1)>1, error([upper(mfilename) ' requires that a property name be a single string.']); end; end; if (rem(nargin-firstprop,2)~=1), error([upper(mfilename) ' requires that the property ''' ... varargin{nargin} ''' be paired with a property value.']); end;end;% default outputif (nargout>0), h=[]; end;if (nargout>1), yy=[]; end;if (nargout>2), zz=[]; end;% set values to empty matricesstart = [];stop = [];len = [];baseangle = [];tipangle = [];wid = [];page = [];crossdir = [];ends = [];ax = [];oldh = [];ispatch = [];defstart = [NaN NaN NaN];defstop = [NaN NaN NaN];deflen = 16;defbaseangle = 90;deftipangle = 16;defwid = 0;defpage = 0;defcrossdir = [NaN NaN NaN];defends = 1;defoldh = [];defispatch = 1;% The 'Tag' we'll put on our arrowsArrowTag = 'Arrow';% check for oldstyle argumentsif (firstprop==2), % assume arg1 is a set of handles oldh = varargin{1}(:); if isempty(oldh), return; end;elseif (firstprop>9), error([upper(mfilename) ' takes at most 8 non-property arguments.']);elseif (firstprop>2), s = str2mat('start','stop','len','baseangle','tipangle','wid','page','crossdir'); for k=1:firstprop-1, eval([deblank(s(k,:)) '=varargin{k};']); end;end;% parse property pairsextraprops={};for k=firstprop:2:nargin, prop = varargin{k}; val = varargin{k+1}; prop = [lower(prop(:)') ' ']; if strncmp(prop,'start' ,5), start = val; elseif strncmp(prop,'stop' ,4), stop = val; elseif strncmp(prop,'len' ,3), len = val(:); elseif strncmp(prop,'base' ,4), baseangle = val(:); elseif strncmp(prop,'tip' ,3), tipangle = val(:); elseif strncmp(prop,'wid' ,3), wid = val(:); elseif strncmp(prop,'page' ,4), page = val; elseif strncmp(prop,'cross' ,5), crossdir = val; elseif strncmp(prop,'norm' ,4), if (isstr(val)), crossdir=val; else, crossdir=val*sqrt(-1); end; elseif strncmp(prop,'end' ,3), ends = val; elseif strncmp(prop,'object',6), oldh = val(:); elseif strncmp(prop,'handle',6), oldh = val(:); elseif strncmp(prop,'type' ,4), ispatch = val; elseif strncmp(prop,'userd' ,5), %ignore it else, % make sure it is a valid patch or line property eval('get(0,[''DefaultPatch'' varargin{k}]);err=0;','err=1;'); errstr=lasterr; if (err), eval('get(0,[''DefaultLine'' varargin{k}]);err=0;','err=1;'); end; if (err), errstr(1:max(find(errstr==setstr(13)|errstr==setstr(10)))) = ''; error([upper(mfilename) ' got ' errstr]); end; extraprops={extraprops{:},varargin{k},val}; end;end;% Check if we got 'default' valuesstart = arrow_defcheck(start ,defstart ,'Start' );stop = arrow_defcheck(stop ,defstop ,'Stop' );len = arrow_defcheck(len ,deflen ,'Length' );baseangle = arrow_defcheck(baseangle,defbaseangle,'BaseAngle' );tipangle = arrow_defcheck(tipangle ,deftipangle ,'TipAngle' );wid = arrow_defcheck(wid ,defwid ,'Width' );crossdir = arrow_defcheck(crossdir ,defcrossdir ,'CrossDir' );page = arrow_defcheck(page ,defpage ,'Page' );ends = arrow_defcheck(ends ,defends ,'' );oldh = arrow_defcheck(oldh ,[] ,'ObjectHandles');ispatch = arrow_defcheck(ispatch ,defispatch ,'' );% check transpose on arguments[m,n]=size(start ); if any(m==[2 3])&(n==1|n>3), start = start'; end;[m,n]=size(stop ); if any(m==[2 3])&(n==1|n>3), stop = stop'; end;[m,n]=size(crossdir); if any(m==[2 3])&(n==1|n>3), crossdir = crossdir'; end;% convert strings to numbersif ~isempty(ends) & isstr(ends), endsorig = ends; [m,n] = size(ends); col = lower([ends(:,1:min(3,n)) ones(m,max(0,3-n))*' ']); ends = NaN*ones(m,1); oo = ones(1,m); ii=find(all(col'==['non']'*oo)'); if ~isempty(ii), ends(ii)=ones(length(ii),1)*0; end; ii=find(all(col'==['sto']'*oo)'); if ~isempty(ii), ends(ii)=ones(length(ii),1)*1; end; ii=find(all(col'==['sta']'*oo)'); if ~isempty(ii), ends(ii)=ones(length(ii),1)*2; end; ii=find(all(col'==['bot']'*oo)'); if ~isempty(ii), ends(ii)=ones(length(ii),1)*3; end; if any(isnan(ends)), ii = min(find(isnan(ends))); error([upper(mfilename) ' does not recognize ''' deblank(endsorig(ii,:)) ''' as a valid ''Ends'' value.']); end;else, ends = ends(:);end;if ~isempty(ispatch) & isstr(ispatch), col = lower(ispatch(:,1)); patchchar='p'; linechar='l'; defchar=' '; mask = col~=patchchar & col~=linechar & col~=defchar; if any(mask), error([upper(mfilename) ' does not recognize ''' deblank(ispatch(min(find(mask)),:)) ''' as a valid ''Type'' value.']); end; ispatch = (col==patchchar)*1 + (col==linechar)*0 + (col==defchar)*defispatch;else, ispatch = ispatch(:);end;oldh = oldh(:);% check object handlesif ~all(ishandle(oldh)), error([upper(mfilename) ' got invalid object handles.']); end;% expand root, figure, and axes handlesif ~isempty(oldh), ohtype = get(oldh,'Type'); mask = strcmp(ohtype,'root') | strcmp(ohtype,'figure') | strcmp(ohtype,'axes'); if any(mask), oldh = num2cell(oldh); for ii=find(mask)', oldh(ii) = {findobj(oldh{ii},'Tag',ArrowTag)}; end; oldh = cat(1,oldh{:}); if isempty(oldh), return; end; % no arrows to modify, so just leave end;end;% largest argument length[mstart,junk]=size(start); [mstop,junk]=size(stop); [mcrossdir,junk]=size(crossdir);argsizes = [length(oldh) mstart mstop ... length(len) length(baseangle) length(tipangle) ... length(wid) length(page) mcrossdir length(ends) ];args=['length(ObjectHandle) '; ... '#rows(Start) '; ... '#rows(Stop) '; ... 'length(Length) '; ... 'length(BaseAngle) '; ... 'length(TipAngle) '; ... 'length(Width) '; ... 'length(Page) '; ... '#rows(CrossDir) '; ... '#rows(Ends) '];if (any(imag(crossdir(:))~=0)), args(9,:) = '#rows(NormalDir) ';end;if isempty(oldh), narrows = max(argsizes);else, narrows = length(oldh);end;if (narrows<=0), narrows=1; end;% Check size of argumentsii = find((argsizes~=0)&(argsizes~=1)&(argsizes~=narrows));if ~isempty(ii), s = args(ii',:);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -