Home > matGeom > geom2d > drawArrow.m

drawArrow

PURPOSE ^

DRAWARROW Draw an arrow on the current axis.

SYNOPSIS ^

function varargout = drawArrow(varargin)

DESCRIPTION ^

DRAWARROW Draw an arrow on the current axis.
   
   drawArrow(x1, y1, x2, y2) 
   draws an arrow between the points (x1 y1) and (x2 y2).

   drawArrow([x1 y1 x2 y2])
   gives argument as a single array.

   drawArrow(..., L, W)
   specifies length and width of the arrow.

   drawArrow(..., L, W, TYPE)
   also specifies arrow type. TYPE can be one of the following :
   0: draw only two strokes
   1: fill a triangle
   .5: draw a half arrow (try it to see ...)
   
   Arguments can be single values or array of size N-by-1. In this case,
   the function draws multiple arrows.

   H = drawArrow(...) 
   return handle(s) to created arrow elements.
   The handles are returned in a structure with the fields
   'body', 'wing' and 'head' containing the handles to the different
   parts of the arrow(s).

   Example
     t = linspace(0, 2*pi, 200);
     figure; hold on;
     plot(t, sin(t)); 
     drawArrow([2 -1 pi 0], .1, .05, .5)
 
   See also
     drawEdge

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function varargout = drawArrow(varargin)
0002 %DRAWARROW Draw an arrow on the current axis.
0003 %
0004 %   drawArrow(x1, y1, x2, y2)
0005 %   draws an arrow between the points (x1 y1) and (x2 y2).
0006 %
0007 %   drawArrow([x1 y1 x2 y2])
0008 %   gives argument as a single array.
0009 %
0010 %   drawArrow(..., L, W)
0011 %   specifies length and width of the arrow.
0012 %
0013 %   drawArrow(..., L, W, TYPE)
0014 %   also specifies arrow type. TYPE can be one of the following :
0015 %   0: draw only two strokes
0016 %   1: fill a triangle
0017 %   .5: draw a half arrow (try it to see ...)
0018 %
0019 %   Arguments can be single values or array of size N-by-1. In this case,
0020 %   the function draws multiple arrows.
0021 %
0022 %   H = drawArrow(...)
0023 %   return handle(s) to created arrow elements.
0024 %   The handles are returned in a structure with the fields
0025 %   'body', 'wing' and 'head' containing the handles to the different
0026 %   parts of the arrow(s).
0027 %
0028 %   Example
0029 %     t = linspace(0, 2*pi, 200);
0030 %     figure; hold on;
0031 %     plot(t, sin(t));
0032 %     drawArrow([2 -1 pi 0], .1, .05, .5)
0033 %
0034 %   See also
0035 %     drawEdge
0036 %
0037 
0038 %   ---------
0039 %   author : David Legland
0040 %   INRA - TPV URPOI - BIA IMASTE
0041 %   created the 11/11/2004 from drawEdge
0042 %
0043 
0044 %   HISTORY
0045 %   2014-09-17 fix managment of handle values as suggested by Benoit Botton
0046 %   2016-05-23 Improve codee and reduce calculations (by JuanPi Carbajal)
0047 
0048 if isempty (varargin)
0049     error ('should specify at least one argument');
0050 end
0051 
0052 % parse arrow coordinates
0053 var = varargin{1};
0054 if size (var, 2) == 4
0055     x1 = var(:,1);
0056     y1 = var(:,2);
0057     x2 = var(:,3);
0058     y2 = var(:,4);
0059     varargin = varargin(2:end);
0060 
0061 elseif length (varargin) > 3
0062     x1 = varargin{1};
0063     y1 = varargin{2};
0064     x2 = varargin{3};
0065     y2 = varargin{4};
0066     varargin = varargin(5:end);
0067     
0068 else
0069     error ('MatGeom:drawArrow:invalidArgumentNumber', ...
0070         'wrong number of arguments, please read the doc');
0071 end
0072 N     = size (x1, 1);
0073 
0074 % default values
0075 l = 10  * ones (N, 1); % Body length
0076 w = 5   * ones (N, 1); % Head width
0077 r = 0.1 * ones (N, 1); % Head to body ratio
0078 h = zeros (N, 1);      % Head type
0079 
0080 if ~isempty (varargin)
0081     % Parse parameters
0082     k      = length (varargin);
0083     vartxt = 'lwrh';
0084     cmd    = ['%s = varargin{%d}; %s = %s(:);' ...
0085               'if length (%s) < N; %s = %s(1) * ones (N , 1); end'];
0086     for i = 1:k
0087         v = vartxt(i);
0088         eval (sprintf (cmd, v, i, v, v, v, v, v));
0089     end
0090 end
0091 
0092 hold on;
0093 oldHold = ishold (gca);
0094 if ~oldHold
0095     hold on;
0096 end
0097 axis equal;
0098 
0099 % angle of the edge
0100 theta = atan2 (y2-y1, x2-x1);
0101 
0102 rl = r .* l;
0103 rh = r .* h;
0104 cT = cos (theta);
0105 sT = sin (theta);
0106 % point on the 'left'
0107 xa1 = x2 - rl .* cT - w .* sT / 2;
0108 ya1 = y2 - rl .* sT + w .* cT / 2;
0109 % point on the 'right'
0110 xa2 = x2 - rl .* cT + w .* sT / 2;
0111 ya2 = y2 - rl .* sT - w .* cT / 2;
0112 % point on the middle of the arrow
0113 xa3 = x2 - rh .* cT;
0114 ya3 = y2 - rh .* sT;
0115 
0116 % draw main edge
0117 tmp         = line ([x1.'; x2.'], [y1.'; y2.'], 'color', [0 0 1]);
0118 handle.body = tmp;
0119 
0120 % draw only 2 wings
0121 ind = find (h == 0);
0122 if ~isempty (ind)
0123     tmp              = line ([xa1(ind).'; x2(ind).'], [ya1(ind).'; y2(ind).'], ...
0124                              'color', [0 0 1]);
0125     handle.wing(:,1) = tmp;
0126 
0127     tmp              = line ([xa2(ind).'; x2(ind).'], [ya2(ind).'; y2(ind).'], ...
0128                              'color', [0 0 1]);
0129     handle.wing(:,2) = tmp;
0130 end
0131 
0132 % draw a full arrow
0133 ind = find (h ~= 0);
0134 if ~isempty (ind)
0135     tmp         = patch ([x2(ind) xa1(ind) xa3(ind) xa2(ind) x2(ind)].', ...
0136                          [y2(ind) ya1(ind) ya3(ind) ya2(ind) y2(ind)].', [0 0 1]);
0137     handle.head = tmp;
0138 end
0139 
0140 % format output arguments
0141 if nargout > 0
0142     varargout{1} = handle;
0143 end
0144 
0145 if ~oldHold
0146     hold off;
0147 end

Generated on Wed 16-Feb-2022 15:10:47 by m2html © 2003-2019