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