function shiftline(f1)
%shiftline(f1)
% Permit to interactively shift a line when clicking it.
% When released, the amount of shifting is displayed in the
% workspace
% Key for special behaviour:
% k: keep the line in the graph at the end
% +: zoom in
% -: zoom out
% x: block displacement in x direction
% y: block displacement in y direction
% f: restore total freedom in both x an y direction
%
% B. Valley, 31.08.2006
% modified after the function magnify of Rick Hindman - 7/29/04
if (nargin == 0), f1 = gcf; end; % --------------------------------------------------------------------------------------
figure(f1);
set(f1, ...
'WindowButtonDownFcn', @ButtonDownCallback, ...
'WindowButtonUpFcn', @ButtonUpCallback, ...
'WindowButtonMotionFcn', @ButtonMotionCallback, ...
'KeyPressFcn', @KeyPressCallback,...
'Pointer','fleur');
return;
function ButtonDownCallback(src,eventdata) % -----------------------------------------------------------------------------
f1 = src;
a1 = get(f1,'CurrentAxes');
[f_cp, a1_cp] = pointer2d(f1,a1);
l1=get(a1,'Children');
l2=findobj('Type','Line');
l = intersect(l1, l2);
if isempty(l)
warning('nothing to shift')
set(f1, ...
'WindowButtonDownFcn', '', ...
'WindowButtonUpFcn', '', ...
'WindowButtonMotionFcn', '', ...
'KeyPressFcn', '',...
'Pointer','arrow');
return;
elseif length(l)==1
thel=l;
else
thel=chooseclosestline(a1_cp(1),a1_cp(2),l);
end
% backup initial condition of axes -----
myuserdata.initXLimMode=get(a1,'XLimMode');
myuserdata.initYLimMode=get(a1,'YLimMode');
myuserdata.initXLim=get(a1,'XLim');
myuserdata.initYLim=get(a1,'YLim');
myuserdata.keepongraph=0;
myuserdata.freedom=2; % 2=free in xy; 1=free in x only; 0=free in y only;
% set some working condition of axes ----
set(a1,...
'XLimMode','Manual',...
'YLimMode','Manual');
newl=copyobj(thel,a1);
t_C=get(thel,'Color');
t_C=t_C+0.5;
t_C(find(t_C>1))=1;
set(newl,...
'Color',t_C);
clear t_C;
set(f1, ...
'UserData',[f1,a1,thel,newl]);
myuserdata.param=[a1_cp(1) a1_cp(2) 0 0]; % start and shift value
set(a1, ...
'UserData',myuserdata);
set(f1, ...
'CurrentAxes',a1);
ButtonMotionCallback(src);
return;
function ButtonUpCallback(src,eventdata) % --------------------------------------------------------------------------------------------
H = get(src,'UserData');
f1 = H(1); a1 = H(2); thel = H(3); newl = H(4);
set(f1, ...
'UserData',[],...
'CurrentAxes',a1);
myuserdata=get(a1,'UserData');
t_S=sprintf('shift is x: %1.5f, y: %1.5f',myuserdata.param(3), myuserdata.param(4));
disp(t_S);
set(a1,'UserData',[]);
clear t_*
if myuserdata.keepongraph==0
delete(newl);
end;
set(a1,...
'XLim',myuserdata.initXLim,...
'YLim',myuserdata.initYLim,...
'XLimMode',myuserdata.initXLimMode,...
'YLimMode',myuserdata.initYLimMode);
set(f1, ...
'WindowButtonDownFcn', '', ...
'WindowButtonUpFcn', '', ...
'WindowButtonMotionFcn', '', ...
'KeyPressFcn', '',...
'Pointer','arrow');
return;
function ButtonMotionCallback(src,eventdata) % -------------------------------------------------------------------------------------------
H = get(src,'UserData');
if ~isempty(H)
f1 = H(1); a1 = H(2); thel = H(3); newl = H(4);
myuserdata = get(a1,'UserData');
a1_param=myuserdata.param;
f_pos = get(f1,'Position');
a1_pos = get(a1,'Position');
nl_xdata=get(thel,'XData');
nl_ydata=get(thel,'YData');
if myuserdata.freedom==2
freex=1;
freey=1;
elseif myuserdata.freedom==1
freex=1;
freey=0;
else
freex=0;
freey=1;
end
[f_cp, a1_cp] = pointer2d(f1,a1);
a1_param=[a1_param(1) a1_param(2) (a1_cp(1)-a1_param(1))*freex (a1_cp(2)-a1_param(2))*freey];
myuserdata.param=a1_param;
set(a1, 'UserData', myuserdata);
nl_xdata=nl_xdata+a1_param(3);
nl_ydata=nl_ydata+a1_param(4);
set(newl,...
'XData',nl_xdata,...
'YData',nl_ydata);
end;
return;
function KeyPressCallback(src,eventdata) % ---------------------------------------------------------------------------------------------------
H = get(gcf,'UserData');
if ~isempty(H)
f1 = H(1); a1 = H(2); thel = H(3); newl = H(4);
myuserdata = get(a1,'UserData');
if strcmp(get(f1,'CurrentCharacter'),'+') % zoom in
[f_cp, a1_cp] = pointer2d(f1,a1);
axlim=get(a1,'XLim');
aylim=get(a1,'YLim');
axlim(1)=a1_cp(1)-(axlim(2)-axlim(1))*0.4;
axlim(2)=a1_cp(1)+(axlim(2)-axlim(1))*0.4;
aylim(1)=a1_cp(2)-(aylim(2)-aylim(1))*0.4;
aylim(2)=a1_cp(2)+(aylim(2)-aylim(1))*0.4;
set(a1,...
'XLim',axlim,...
'YLim',aylim);
end
if strcmp(get(f1,'CurrentCharacter'),'-') % zoom out
[f_cp, a1_cp] = pointer2d(f1,a1);
axlim=get(a1,'XLim');
aylim=get(a1,'YLim');
axlim(1)=a1_cp(1)-(axlim(2)-axlim(1))*0.6;
axlim(2)=a1_cp(1)+(axlim(2)-axlim(1))*0.6;
aylim(1)=a1_cp(2)-(aylim(2)-aylim(1))*0.6;
aylim(2)=a1_cp(2)+(aylim(2)-aylim(1))*0.6;
set(a1,...
'XLim',axlim,...
'YLim',aylim);
end
if strcmp(get(f1,'CurrentCharacter'),'k') % keep on graph
myuserdata.keepongraph=1;
end
if strcmp(get(f1,'CurrentCharacter'),'x') % fix on x
myuserdata.freedom=1;
end
if strcmp(get(f1,'CurrentCharacter'),'y') % fix on x
myuserdata.freedom=0;
end
if strcmp(get(f1,'CurrentCharacter'),'f') % put full freedom
myuserdata.freedom=2;
end
set(a1,'UserData',myuserdata);
ButtonMotionCallback(src);
end;
return;
% Included for completeness (usually in own file) -----------------------------------------------------------------------------------------------
function [fig_pointer_pos, axes_pointer_val] = pointer2d(fig_hndl,axes_hndl) % ------------------------------------------------------------------
%
%pointer2d(fig_hndl,axes_hndl)
%
% Returns the coordinates of the pointer (in pixels)
% in the desired figure (fig_hndl) and the coordinates
% in the desired axis (axes coordinates)
%
% Example:
% figure(1),
% hold on,
% for i = 1:1000,
% [figp,axp]=pointer2d;
% plot(axp(1),axp(2),'.','EraseMode','none');
% drawnow;
% end;
% hold off
% Rick Hindman - 4/18/01
if (nargin == 0), fig_hndl = gcf; axes_hndl = gca; end;
if (nargin == 1), axes_hndl = get(fig_hndl,'CurrentAxes'); end;
set(fig_hndl,'Units','pixels');
pointer_pos = get(0,'PointerLocation'); %pixels {0,0} lower left
fig_pos = get(fig_hndl,'Position'); %pixels {l,b,w,h}
fig_pointer_pos = pointer_pos - fig_pos([1,2]);
set(fig_hndl,'CurrentPoint',fig_pointer_pos);
if (isempty(axes_hndl)),
axes_pointer_val = [];
elseif (nargout == 2),
axes_pointer_line = get(axes_hndl,'CurrentPoint');
axes_pointer_val = sum(axes_pointer_line)/2;
end;
function thel=chooseclosestline(x,y,l) % -------------------------------------------------------------------------------------------------------
ldata=[];
xdata=[];
ydata=[];
for i=1:length(l)
ix=get(l(i),'XData')';
iy=get(l(i),'YData')';
ldata=[ldata; ones(length(ix),1)*i];
xdata=[xdata; ix];
ydata=[ydata; iy];
end
clear i ix iy
d=(xdata-x).^2+(ydata-y).^2;
[m i]=min(d); i=i(1);
thel=l(ldata(i));