-
Notifications
You must be signed in to change notification settings - Fork 0
/
plot_arrow.m
121 lines (116 loc) · 5.03 KB
/
plot_arrow.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
function handles = plot_arrow( x1,y1,x2,y2,varargin )
%
% plot_arrow - plots an arrow to the current plot
%
% format: handles = plot_arrow( x1,y1,x2,y2 [,options...] )
%
% input: x1,y1 - starting point
% x2,y2 - end point
% options - come as pairs of "property","value" as defined for "line" and "patch"
% controls, see matlab help for listing of these properties.
% note that not all properties where added, one might add them at the end of this file.
%
% additional options are:
% 'headwidth': relative to complete arrow size, default value is 0.07
% 'headheight': relative to complete arrow size, default value is 0.15
% (encoded are maximal values if pixels, for the case that the arrow is very long)
%
% output: handles - handles of the graphical elements building the arrow
%
% Example: plot_arrow( -1,-1,15,12,'linewidth',2,'color',[0.5 0.5 0.5],'facecolor',[0.5 0.5 0.5] );
% plot_arrow( 0,0,5,4,'linewidth',2,'headwidth',0.25,'headheight',0.33 );
% plot_arrow; % will launch demo
% =============================================
% for debug - demo - can be erased
% =============================================
if (nargin==0)
figure;
axis;
set( gca,'nextplot','add' );
for x = 0:0.3:2*pi
color = [rand rand rand];
h = plot_arrow( 1,1,50*rand*cos(x),50*rand*sin(x),...
'color',color,'facecolor',color,'edgecolor',color );
set( h,'linewidth',2 );
end
hold off;
return
end
% =============================================
% end of for debug
% =============================================
% =============================================
% constants (can be edited)
% =============================================
alpha = 0.15; % head length
beta = 0.07; % head width
max_length = 22;
max_width = 10;
% =============================================
% check if head properties are given
% =============================================
% if ratio is always fixed, this section can be removed!
if ~isempty( varargin )
for c = 1:floor(length(varargin)/2)
try
switch lower(varargin{c*2-1})
% head properties - do nothing, since handled above already
case 'headheight',alpha = max( min( varargin{c*2},1 ),0.01 );
case 'headwidth', beta = max( min( varargin{c*2},1 ),0.01 );
end
catch
fprintf( 'unrecognized property or value for: %s\n',varargin{c*2-1} );
end
end
end
% =============================================
% calculate the arrow head coordinates
% =============================================
den = x2 - x1 + eps; % make sure no devision by zero occurs
teta = atan( (y2-y1)/den ) + pi*(x2<x1) - pi/2; % angle of arrow
cs = cos(teta); % rotation matrix
ss = sin(teta);
R = [cs -ss;ss cs];
line_length = sqrt( (y2-y1)^2 + (x2-x1)^2 ); % sizes
head_length = min( line_length*alpha,max_length );
head_width = min( line_length*beta,max_length );
x0 = x2*cs + y2*ss; % build head coordinats
y0 = -x2*ss + y2*cs;
coords = R*[x0 x0+head_width/2 x0-head_width/2; y0 y0-head_length y0-head_length];
% =============================================
% plot arrow (= line + patch of a triangle)
% =============================================
h1 = plot( [x1,x2],[y1,y2],'k' );
h2 = patch( coords(1,:),coords(2,:),[0 0 0] );
% =============================================
% return handles
% =============================================
handles = [h1 h2];
% =============================================
% check if styling is required
% =============================================
% if no styling, this section can be removed!
if ~isempty( varargin )
for c = 1:floor(length(varargin)/2)
try
switch lower(varargin{c*2-1})
% only patch properties
case 'edgecolor', set( h2,'EdgeColor',varargin{c*2} );
case 'facecolor', set( h2,'FaceColor',varargin{c*2} );
case 'facelighting',set( h2,'FaceLighting',varargin{c*2} );
case 'edgelighting',set( h2,'EdgeLighting',varargin{c*2} );
% only line properties
case 'color' , set( h1,'Color',varargin{c*2} );
% shared properties
case 'linestyle', set( handles,'LineStyle',varargin{c*2} );
case 'linewidth', set( handles,'LineWidth',varargin{c*2} );
case 'parent', set( handles,'parent',varargin{c*2} );
% head properties - do nothing, since handled above already
case 'headwidth',;
case 'headheight',;
end
catch
fprintf( 'unrecognized property or value for: %s\n',varargin{c*2-1} );
end
end
end