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
   0.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 %   0.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 % E-mail: david.legland@inrae.fr
0041 % Created: 2004-11-11, from drawEdge
0042 % Copyright 2004-2024 INRA - TPV URPOI - BIA IMASTE
0043 
0044 % extract handle of axis to draw on
0045 if isAxisHandle(varargin{1})
0046     ax = varargin{1};
0047     varargin(1) = [];
0048 else
0049     ax = gca;
0050 end
0051 
0052 if isempty (varargin)
0053     error ('should specify at least one argument');
0054 end
0055 
0056 % parse arrow coordinates
0057 var = varargin{1};
0058 if size (var, 2) == 4
0059     x1 = var(:,1);
0060     y1 = var(:,2);
0061     x2 = var(:,3);
0062     y2 = var(:,4);
0063     varargin = varargin(2:end);
0064 
0065 elseif length (varargin) > 3
0066     x1 = varargin{1};
0067     y1 = varargin{2};
0068     x2 = varargin{3};
0069     y2 = varargin{4};
0070     varargin = varargin(5:end);
0071     
0072 else
0073     error ('MatGeom:drawArrow:invalidArgumentNumber', ...
0074         'wrong number of arguments, please read the doc');
0075 end
0076 N     = size (x1, 1);
0077 
0078 % default values
0079 l = 10  * ones (N, 1); % Body length
0080 w = 5   * ones (N, 1); % Head width
0081 r = 0.1 * ones (N, 1); % Head to body ratio
0082 h = zeros (N, 1);      % Head type
0083 
0084 if ~isempty (varargin)
0085     % Parse parameters
0086     k      = length (varargin);
0087     vartxt = 'lwrh';
0088     cmd    = ['%s = varargin{%d}; %s = %s(:);' ...
0089               'if length (%s) < N; %s = %s(1) * ones (N , 1); end'];
0090     for i = 1:k
0091         v = vartxt(i);
0092         eval (sprintf (cmd, v, i, v, v, v, v, v));
0093     end
0094 end
0095 
0096 hold on;
0097 oldHold = ishold(ax);
0098 if ~oldHold
0099     hold on;
0100 end
0101 
0102 % angle of the edge
0103 theta = atan2(y2-y1, x2-x1);
0104 
0105 rl = r .* l;
0106 rh = r .* h;
0107 cT = cos (theta);
0108 sT = sin (theta);
0109 % point on the 'left'
0110 xa1 = x2 - rl .* cT - w .* sT / 2;
0111 ya1 = y2 - rl .* sT + w .* cT / 2;
0112 % point on the 'right'
0113 xa2 = x2 - rl .* cT + w .* sT / 2;
0114 ya2 = y2 - rl .* sT - w .* cT / 2;
0115 % point on the middle of the arrow
0116 xa3 = x2 - rh .* cT;
0117 ya3 = y2 - rh .* sT;
0118 
0119 % draw main edge
0120 tmp         = line(ax, [x1.'; x2.'], [y1.'; y2.'], 'color', [0 0 1]);
0121 handle.body = tmp;
0122 
0123 % draw only 2 wings
0124 ind = find (h == 0);
0125 if ~isempty (ind)
0126     tmp              = line ([xa1(ind).'; x2(ind).'], [ya1(ind).'; y2(ind).'], ...
0127                              'color', [0 0 1]);
0128     handle.wing(:,1) = tmp;
0129 
0130     tmp              = line ([xa2(ind).'; x2(ind).'], [ya2(ind).'; y2(ind).'], ...
0131                              'color', [0 0 1]);
0132     handle.wing(:,2) = tmp;
0133 end
0134 
0135 % draw a full arrow
0136 ind = find (h ~= 0);
0137 if ~isempty(ind)
0138     tmp         = patch (ax, ...
0139         [x2(ind) xa1(ind) xa3(ind) xa2(ind) x2(ind)].', ...
0140         [y2(ind) ya1(ind) ya3(ind) ya2(ind) y2(ind)].', [0 0 1]);
0141     handle.head = tmp;
0142 end
0143 
0144 % format output arguments
0145 if nargout > 0
0146     varargout{1} = handle;
0147 end
0148 
0149 if ~oldHold
0150     hold off;
0151 end

Generated on Thu 21-Nov-2024 11:30:22 by m2html © 2003-2022