1 |
function [H,H2]=extclabel(CS,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,... |
---|
2 |
arg12,arg13,arg14,arg15,arg16,arg17,arg18,arg19); |
---|
3 |
% EXTCLABEL *Real* Contour labelling |
---|
4 |
% EXTCLABEL(CS) draw the contours in contour structure CS |
---|
5 |
% adding real, rotated, line-broken labels. |
---|
6 |
% |
---|
7 |
% text and line property values are specified by the usual |
---|
8 |
% property/value pairs, for text properties (beginning |
---|
9 |
% with 'Font...' or 'Rotation') or line properties (beginning |
---|
10 |
% with 'line...' or 'color'), |
---|
11 |
% e.g., EXTCLABEL(...,'fontsize',8,'linewidth',3); |
---|
12 |
% |
---|
13 |
% The default rotation is aligned with the contours. Label |
---|
14 |
% intervals (in 'points') are set using a 'label' property. |
---|
15 |
% |
---|
16 |
% See also EXTCONTOUR |
---|
17 |
|
---|
18 |
|
---|
19 |
% Author: R. Pawlowicz IOS rich@ios.bc.ca |
---|
20 |
% 12/12/94 |
---|
21 |
|
---|
22 |
|
---|
23 |
lab_int=72*2; % label interval (points) |
---|
24 |
|
---|
25 |
linarg_for_call=[]; |
---|
26 |
textarg_for_call=[]; |
---|
27 |
|
---|
28 |
ii=2; |
---|
29 |
while (ii<=nargin), |
---|
30 |
arg=eval(['arg' int2str(ii)]); |
---|
31 |
if (lower(arg(1:3))=='lin' | lower(arg(1:3))=='col'), |
---|
32 |
ii=ii+1; |
---|
33 |
linarg_for_call=[linarg_for_call ',''' arg ''',arg' int2str(ii) ]; |
---|
34 |
elseif (lower(arg(1:3))=='fon' | lower(arg(1:3))=='rot'), |
---|
35 |
ii=ii+1; |
---|
36 |
textarg_for_call=[textarg_for_call ',''' arg ''',arg' int2str(ii) ]; |
---|
37 |
elseif (lower(arg(1:3))=='lab' ), |
---|
38 |
ii=ii+1; |
---|
39 |
lab_int=eval(['arg' int2str(ii) ]); |
---|
40 |
else |
---|
41 |
error(['Unknown option: ' arg ]); |
---|
42 |
end; |
---|
43 |
ii=ii+1; |
---|
44 |
end; |
---|
45 |
|
---|
46 |
% Compute scaling to make sure printed output looks OK. We have to go via |
---|
47 |
% the figure's 'paperposition', rather than the the absolute units of the |
---|
48 |
% axes 'position' since those would be absolute only if we kept the 'units' |
---|
49 |
% property in some absolute units (like 'points') rather than the default |
---|
50 |
% 'normalized'. |
---|
51 |
|
---|
52 |
UN=get(gca,'units'); |
---|
53 |
if (UN(1:3)=='nor'), |
---|
54 |
UN=get(gcf,'paperunits'); |
---|
55 |
set(gcf,'paperunits','points'); |
---|
56 |
PA=get(gcf,'paperpos'); |
---|
57 |
set(gcf,'paperunits',UN); |
---|
58 |
PA=PA.*[get(gca,'position')]; |
---|
59 |
else |
---|
60 |
set(gcf,'units','points'); |
---|
61 |
PA=get(gca,'pos'); |
---|
62 |
set(gca,'units',UN); |
---|
63 |
end; |
---|
64 |
|
---|
65 |
% Find beginning of all lines |
---|
66 |
|
---|
67 |
lCS=size(CS,2); |
---|
68 |
|
---|
69 |
if (ishold), |
---|
70 |
XL=get(gca,'xlim'); |
---|
71 |
YL=get(gca,'ylim'); |
---|
72 |
else |
---|
73 |
iL=[]; |
---|
74 |
k=1; |
---|
75 |
XL=[Inf -Inf]; |
---|
76 |
YL=[Inf -Inf]; |
---|
77 |
while (k<lCS), |
---|
78 |
x=CS(1,k+[1:CS(2,k)]); |
---|
79 |
y=CS(2,k+[1:CS(2,k)]); |
---|
80 |
XL=[ min([XL(1),x]) max([XL(2),x]) ]; |
---|
81 |
YL=[ min([YL(1),y]) max([YL(2),y]) ]; |
---|
82 |
iL=[iL k]; |
---|
83 |
k=k+CS(2,k)+1; |
---|
84 |
end; |
---|
85 |
plot(XL(1),YL(1)); |
---|
86 |
set(gca,'xlim',XL,'ylim',YL); |
---|
87 |
end; |
---|
88 |
|
---|
89 |
|
---|
90 |
Aspx=PA(3)/diff(XL); % To convert data coordinates to paper (we need to do this |
---|
91 |
Aspy=PA(4)/diff(YL); % to get the gaps for text the correct size) |
---|
92 |
|
---|
93 |
H=[]; |
---|
94 |
|
---|
95 |
% Set up a dummy text object from which you can get text extent info |
---|
96 |
eval(['H1=text(XL(1),YL(1),''dummyarg'',''units'',''points'' ' textarg_for_call ');']); |
---|
97 |
|
---|
98 |
ii=1; |
---|
99 |
while (ii<lCS), |
---|
100 |
|
---|
101 |
l=CS(2,ii); |
---|
102 |
x=CS(1,ii+[1:l]); |
---|
103 |
y=CS(2,ii+[1:l]); |
---|
104 |
|
---|
105 |
lvl=CS(1,ii); |
---|
106 |
lab=num2str(lvl); |
---|
107 |
|
---|
108 |
% Get the size of the label |
---|
109 |
set(H1,'string',lab); |
---|
110 |
EX=get(H1,'extent'); |
---|
111 |
% len_lab=EX(3)/2; |
---|
112 |
len_lab=EX(3); |
---|
113 |
|
---|
114 |
sx=x*Aspx; |
---|
115 |
sy=y*Aspy; |
---|
116 |
d=cumsum([0 sqrt(diff(sx).^2 +diff(sy).^2) ]); |
---|
117 |
% psn=[max(len_lab,lab_int+lab_int*(rand(1)-.5)):lab_int:d(l)-len_lab]; |
---|
118 |
if d(l)>=4*len_lab & d(l) <=14*len_lab |
---|
119 |
dint=2; |
---|
120 |
elseif d(l) > 14*len_lab |
---|
121 |
dint=4; |
---|
122 |
else |
---|
123 |
dint=1; |
---|
124 |
end |
---|
125 |
psn=[max(len_lab,d(l)/dint):d(l)/dint:d(l)-len_lab]; |
---|
126 |
lp=size(psn,2); |
---|
127 |
|
---|
128 |
if (lp>0 & finite(lvl) ), |
---|
129 |
|
---|
130 |
Ic=sum( d(ones(1,lp),:)' < psn(ones(1,l),:) ); |
---|
131 |
Il=sum( d(ones(1,lp),:)' < psn(ones(1,l),:)-len_lab ); |
---|
132 |
Ir=sum( d(ones(1,lp),:)' < psn(ones(1,l),:)+len_lab ); |
---|
133 |
|
---|
134 |
% This is a fix to get around Matlabs sort-of-inconsistency with |
---|
135 |
% what [1 1 1] indexing means... |
---|
136 |
if ( ~any(Il~=1) & lp==l ), |
---|
137 |
d=[d,d(l)]; |
---|
138 |
x=[x,x(l)]; |
---|
139 |
y=[y,y(l)]; |
---|
140 |
end; |
---|
141 |
|
---|
142 |
% Endpoints of text in data coordinates |
---|
143 |
wl=(d(Il+1)-psn+len_lab)./(d(Il+1)-d(Il)); |
---|
144 |
wr=(psn-len_lab-d(Il) )./(d(Il+1)-d(Il)); |
---|
145 |
xl=x(Il).*wl+x(Il+1).*wr; |
---|
146 |
yl=y(Il).*wl+y(Il+1).*wr; |
---|
147 |
|
---|
148 |
wl=(d(Ir+1)-psn-len_lab)./(d(Ir+1)-d(Ir)); |
---|
149 |
wr=(psn+len_lab-d(Ir) )./(d(Ir+1)-d(Ir)); |
---|
150 |
xr=x(Ir).*wl+x(Ir+1).*wr; |
---|
151 |
yr=y(Ir).*wl+y(Ir+1).*wr; |
---|
152 |
|
---|
153 |
trot=atan2( (yr-yl)*Aspy, (xr-xl)*Aspx )*180/pi; |
---|
154 |
backang=abs(trot)>90; |
---|
155 |
trot(backang)=trot(backang)+180; |
---|
156 |
|
---|
157 |
% Text location in data coordinates |
---|
158 |
|
---|
159 |
wl=(d(Ic+1)-psn)./(d(Ic+1)-d(Ic)); |
---|
160 |
wr=(psn-d(Ic) )./(d(Ic+1)-d(Ic)); |
---|
161 |
xc=x(Ic).*wl+x(Ic+1).*wr; |
---|
162 |
yc=y(Ic).*wl+y(Ic+1).*wr; |
---|
163 |
|
---|
164 |
% Shift label over a little if in a curvy area |
---|
165 |
shiftfrac=.5; |
---|
166 |
|
---|
167 |
xc=xc*(1-shiftfrac)+(xr+xl)/2*shiftfrac; |
---|
168 |
yc=yc*(1-shiftfrac)+(yr+yl)/2*shiftfrac; |
---|
169 |
|
---|
170 |
|
---|
171 |
% Remove data points under the label... |
---|
172 |
% First, find endpoint locations as distances along lines |
---|
173 |
|
---|
174 |
dr=d(Ir)+sqrt( ((xr-x(Ir))*Aspx).^2 + ((yr-y(Ir))*Aspy).^2 ); |
---|
175 |
dl=d(Il)+sqrt( ((xl-x(Il))*Aspx).^2 + ((yl-y(Il))*Aspy).^2 ); |
---|
176 |
|
---|
177 |
% Now, remove the data points in those gaps using that |
---|
178 |
% ole' Matlab magic |
---|
179 |
|
---|
180 |
f1=zeros(1,l); f1(Il)=ones(1,lp); |
---|
181 |
f2=zeros(1,l); f2(Ir)=ones(1,lp); |
---|
182 |
irem=find(cumsum(f1)-cumsum(f2))+1; |
---|
183 |
x(irem)=[]; |
---|
184 |
y(irem)=[]; |
---|
185 |
d(irem)=[]; |
---|
186 |
l=l-size(irem,2); |
---|
187 |
|
---|
188 |
% Put the points in the correct order... |
---|
189 |
|
---|
190 |
xf=[x(1:l),xl,xc+NaN,xr]; |
---|
191 |
yf=[y(1:l),yl,yc,yr]; |
---|
192 |
[df,If]=sort([d(1:l),dl,psn,dr]); |
---|
193 |
|
---|
194 |
% ...and draw. |
---|
195 |
|
---|
196 |
eval(['H=[H;line(xf(If),yf(If)' linarg_for_call ')];']); |
---|
197 |
|
---|
198 |
for jj=1:lp, |
---|
199 |
eval(['H2=text(xc(jj),yc(jj),lab,''rotation'',trot(jj),' ... |
---|
200 |
' ''vertical'',''middle'',''horizo'',''center'' ' textarg_for_call ');']); |
---|
201 |
set(H2,'Clipping','on'); |
---|
202 |
end; |
---|
203 |
else |
---|
204 |
eval(['H=[H;line(x,y' linarg_for_call ')];']); |
---|
205 |
end; |
---|
206 |
|
---|
207 |
ii=ii+1+CS(2,ii); |
---|
208 |
end; |
---|
209 |
|
---|
210 |
% delete dummy string |
---|
211 |
delete(H1); |
---|
212 |
|
---|
213 |
|
---|