1 |
function [x, y] = sticksafe(x0, y0, theLength, theAngle) |
---|
2 |
|
---|
3 |
% sticksafe -- Intelligent, oriented sticks. |
---|
4 |
% sticksafe('demo') demonstrates itself with sticks centered |
---|
5 |
% on the origin, each one-unit long. |
---|
6 |
% sticksafe(N) demonstrates itself with N sticks. |
---|
7 |
% sticksafe(x0, y0, theLength, theAngle) draws sticks that |
---|
8 |
% start at (x0, y0), with theLength (in y-axis units), and |
---|
9 |
% theAngle (degrees, counter-clockwise from +x). The |
---|
10 |
% variables should be the same size, but any can be a scalar, |
---|
11 |
% just so long as the x0 and/or y0 array is the full size. |
---|
12 |
% The "ResizeFcn" of the figure is set to update the sticks |
---|
13 |
% automatically. The "Tag" of each stick is the mfilename. |
---|
14 |
% Properties of the arrows, such as "color", can be adjusted |
---|
15 |
% at any time. The arrows are Matlab "patch" objects. |
---|
16 |
% h = sticksafe(...) draws the sticks and returns the handle. |
---|
17 |
% [x, y] = sticksafe(...) returns the (x, y) data for such |
---|
18 |
% sticks, one row per arrow, but does not draw them. |
---|
19 |
% sticksafe (no argument) redraws existing sticks. This is |
---|
20 |
% useful whenever the window is resized or the x or y limits |
---|
21 |
% change. (Recall that printing causes the "ResizeFcn" to |
---|
22 |
% be called twice.) |
---|
23 |
% |
---|
24 |
% Note: this routine leaves the axes in "manual" mode. Use |
---|
25 |
% "axis auto" to revert to automatic axis limits. |
---|
26 |
% |
---|
27 |
% Calls: none |
---|
28 |
|
---|
29 |
% Copyright (C) 2000 Dr. Charles R. Denham, ZYDECO. |
---|
30 |
% All Rights Reserved. |
---|
31 |
% Disclosure without explicit written consent from the |
---|
32 |
% copyright owner does not constitute publication. |
---|
33 |
|
---|
34 |
% Version of 12-Jan-2000 14:22:59. |
---|
35 |
% Updated 27-Jul-2001 15:01:56. |
---|
36 |
|
---|
37 |
RCF = 180 / pi; |
---|
38 |
|
---|
39 |
% Resize. |
---|
40 |
|
---|
41 |
if nargin < 1 |
---|
42 |
oldGCA = gca; |
---|
43 |
h = findobj(gcf, 'Type', 'line', 'Tag', mfilename); |
---|
44 |
for i = 1:length(h) |
---|
45 |
p = get(h(i), 'Parent'); |
---|
46 |
axes(p) |
---|
47 |
u = get(h(i), 'UserData'); |
---|
48 |
[xx, yy] = feval(mfilename, u(:, 1), u(:, 2), u(:, 3), u(:, 4)); |
---|
49 |
set(h(i), 'XData', xx(:), 'YData', yy(:)); |
---|
50 |
end |
---|
51 |
axes(oldGCA) |
---|
52 |
return |
---|
53 |
end |
---|
54 |
|
---|
55 |
% Demonstration. |
---|
56 |
|
---|
57 |
if nargin == 1 |
---|
58 |
if isequal(x0, 'demo') |
---|
59 |
help(mfilename) |
---|
60 |
x0 = 16; |
---|
61 |
elseif ischar(x0) |
---|
62 |
x0 = eval(x0); |
---|
63 |
end |
---|
64 |
theName = [mfilename ' demo']; |
---|
65 |
f = findobj('Type', 'figure', 'Name', theName); |
---|
66 |
if ~any(f) |
---|
67 |
f = figure('Name', theName); |
---|
68 |
end |
---|
69 |
figure(max(f)) |
---|
70 |
delete(get(f, 'Children')) |
---|
71 |
n = max(1, round(x0)); |
---|
72 |
x0 = zeros(1, n); |
---|
73 |
ang = linspace(0, 360, length(x0)+1); |
---|
74 |
ang(end) = []; |
---|
75 |
h = feval(mfilename, x0, 0, 1, ang); |
---|
76 |
set(gca, 'Xlim', [-n n], 'YLim', [-2 2]) |
---|
77 |
feval(mfilename) |
---|
78 |
set(gcf, 'WindowButtonDownFcn', ... |
---|
79 |
['if zoomsafe(''down''), ' mfilename ', end']) |
---|
80 |
if nargout > 0, x = h; end |
---|
81 |
return |
---|
82 |
end |
---|
83 |
|
---|
84 |
% Initialize. |
---|
85 |
|
---|
86 |
if nargin > 1 |
---|
87 |
if nargout == 2, x = []; y = []; end |
---|
88 |
if length(x0) == 1 |
---|
89 |
x0 = x0 * ones(size(y0)); |
---|
90 |
elseif length(y0) == 1 |
---|
91 |
y0 = y0 * ones(size(x0)); |
---|
92 |
end |
---|
93 |
x0 = reshape(x0, [1 prod(size(x0))]); |
---|
94 |
y0 = reshape(y0, size(x0)); |
---|
95 |
if nargin < 3, theLength = 1; end |
---|
96 |
if nargin < 4, theAngle = 0; end |
---|
97 |
if length(theLength) == 1 |
---|
98 |
theLength = theLength * ones(size(x0)); |
---|
99 |
end |
---|
100 |
if length(theAngle) == 1 |
---|
101 |
theAngle = theAngle * ones(size(x0)); |
---|
102 |
end |
---|
103 |
|
---|
104 |
theLength = reshape(theLength, size(x0)); |
---|
105 |
theAngle = reshape(theAngle, size(x0)); |
---|
106 |
|
---|
107 |
axes(gca) |
---|
108 |
oldUnits = get(gca, 'Units'); |
---|
109 |
set(gca, 'Units', 'pixels') |
---|
110 |
thePosition = get(gca, 'Position'); |
---|
111 |
set(gca, 'Units', oldUnits) |
---|
112 |
theWidth = thePosition(3); % pixels. |
---|
113 |
theHeight = thePosition(4); % pixels. |
---|
114 |
|
---|
115 |
axis('manual') |
---|
116 |
dx = diff(get(gca, 'XLim')); |
---|
117 |
dy = diff(get(gca, 'YLim')); |
---|
118 |
dydx = dy / dx; % Not used. |
---|
119 |
dxdp = dx / theWidth; % sci/pixel. |
---|
120 |
dydp = dy / theHeight; % sci/pixel. |
---|
121 |
scale = dxdp / dydp; |
---|
122 |
|
---|
123 |
zz = exp(sqrt(-1) .* theAngle ./ RCF) .* theLength; |
---|
124 |
|
---|
125 |
xx = zeros(3, prod(size(x0))); |
---|
126 |
xx(1, :) = x0; |
---|
127 |
xx(2, :) = x0 + real(zz)*scale; |
---|
128 |
xx(3, :) = NaN; |
---|
129 |
|
---|
130 |
yy = zeros(size(xx)); |
---|
131 |
yy(1, :) = y0; |
---|
132 |
yy(2, :) = y0 + imag(zz); |
---|
133 |
yy(3, :) = NaN; |
---|
134 |
|
---|
135 |
if nargout < 2 |
---|
136 |
h = line(xx(:), yy(:), ... |
---|
137 |
'Tag', mfilename, ... |
---|
138 |
'UserData', [x0(:) y0(:) theLength(:) theAngle(:)]); |
---|
139 |
if nargout > 1, x = h; end |
---|
140 |
elseif nargout == 2 |
---|
141 |
x = xx; |
---|
142 |
y = yy; |
---|
143 |
end |
---|
144 |
set(gcf, 'ResizeFcn', mfilename) |
---|
145 |
|
---|
146 |
if nargout == 1, x = h; end |
---|
147 |
end |
---|