📄 crosshair.m
字号:
% Modified from Darren Weber's crosshair
% http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=
% 1038&objectType=FILE
function [Xpoint,Ypoint] = crosshair(action,Val)
% Retrieve Stored data (or store data if none is stored)
XHR_HANDLES.data = get_data;
% Set handle to the current axis
XHR_HANDLES.axis = gca;
% Set handle to the figure
action = lower(action);
switch action,
% Mouse Drag Motion
case 'move',
set(XHR_HANDLES.data.xline,'LineWidth',2);
set(XHR_HANDLES.data.yline,'LineWidth',2);
XHR_HANDLES = updateDATA(XHR_HANDLES);
Xpoint = XHR_HANDLES.data.xpoint;
Ypoint = XHR_HANDLES.data.ypoint;
case 'draw'
%set(XHR_HANDLES.data.xline,'LineWidth',1);
%set(XHR_HANDLES.data.yline,'LineWidth',1);
XHR_HANDLES = updateGUI(XHR_HANDLES);
Xpoint = XHR_HANDLES.data.xpoint;
Ypoint = XHR_HANDLES.data.ypoint;
case 'setx',
set(XHR_HANDLES.data.xline,'LineWidth',1);
set(XHR_HANDLES.data.yline,'LineWidth',1);
XHR_HANDLES.data.xpoint = Val;
AHandle = guidata(XHR_HANDLES.data.gui);
XHR_HANDLES.data.yindex = get(AHandle.TraceSwitch,'Value');
XHR_HANDLES = interpY(XHR_HANDLES);
XHR_HANDLES = checkdatarange(XHR_HANDLES);
XHR_HANDLES = updateGUI(XHR_HANDLES);
Xpoint = XHR_HANDLES.data.xpoint;
Ypoint = XHR_HANDLES.data.ypoint;
% ydata must be a single valued function which is monotonically increasing
% or decreasing
case 'sety',
set(XHR_HANDLES.data.xline,'LineWidth',1);
set(XHR_HANDLES.data.yline,'LineWidth',1);
AHandle = guidata(XHR_HANDLES.data.gui);
interp = get(AHandle.InterpSelect,'Value');
interps = {'none','nearest','linear','spline','cubic'};
interps = interps{interp};
XHR_HANDLES.data.ypoint = Val;
XHR_HANDLES = checkdatarange(XHR_HANDLES);
ydata = XHR_HANDLES.data.ydata;
xdata = XHR_HANDLES.data.xdata;
Sorted = sort(ydata);
index = find( Sorted >= Val);
if (isempty(index)) index = numel(Sorted); end
index = find( ydata == Sorted(index(1)) );
XHR_HANDLES.data.ypoint = ydata(index);
if interp >1
% Perform inverse interpolation...
if ydata(index)~= Val
[X,Y] = curveintersect(xdata,ydata,...
[xdata(1) xdata(size(xdata,1))],[Val Val],interps);
if isempty(X)
if Val >= max(ydata);
X = max(xdata);
Y = max(ydata);
else
X = xdata(1);
Y = ydata(1);
end
end
XHR_HANDLES.data.xpoint = X(1);
XHR_HANDLES.data.ypoint = Y(1);
else
XHR_HANDLES.data.xpoint = xdata(index(1));
end
else
XHR_HANDLES.data.xpoint = XHR_HANDLES.data.xdata(index(1));
end
XHR_HANDLES = updateGUI(XHR_HANDLES);
Xpoint = XHR_HANDLES.data.xpoint;
Ypoint = XHR_HANDLES.data.ypoint;
% Next or Previous X point
case {'nextx','prevx'},
XHR_HANDLES = moveXY(XHR_HANDLES,action);
Xpoint = XHR_HANDLES.data.xpoint;
Ypoint = XHR_HANDLES.data.ypoint;
case{'prevy','nexty'},
AHandle = guidata(XHR_HANDLES.data.gui);
Interval = get(AHandle.Interval,'Value');
Interp = get(AHandle.InterpSelect,'Value');
Ypoint = XHR_HANDLES.data.ypoint;
if (Interval ~= 0) & (Interp >= 1);
if action == 'prevy'
Ypoint = Ypoint - Interval;
elseif action == 'nexty'
Ypoint = Ypoint + Interval;
end
if Ypoint>max(XHR_HANDLES.data.ydata)
Ypoint = max(XHR_HANDLES.data.ydata);
elseif Ypoint < min(XHR_HANDLES.data.ydata)
Ypoint = min(XHR_HANDLES.data.ydata);
end
[Xpoint,Ypoint] = crosshair('sety',Ypoint);
else
set(AHandle.InterpSelect,'Value',1);
XHR_HANDLES = moveXY(XHR_HANDLES,action);
Xpoint = XHR_HANDLES.data.xpoint;
Ypoint = XHR_HANDLES.data.ypoint;
end
% Exit crosshairs GUI
case {'done','exit'},
XHR_HANDLES = get(gcbf,'userdata');
Xpoint = get(XHR_HANDLES.xvalue,'Value');
Ypoint = get(XHR_HANDLES.yvalue,'Value');
handles = fieldnames(XHR_HANDLES);
for i=1:length(handles),
switch handles{i},
case {'axis','datalines','gui'},
otherwise,
h = getfield(XHR_HANDLES,handles{i});
if ishandle(h), delete(h); end
end
end
if strcmp(action,'exit');
if ishandle(XHR_HANDLES.data.gui),
close(XHR_HANDLES.data.gui);
end
else
set(XHR_HANDLES.data.gui,'WindowButtonUpFcn','');
set(XHR_HANDLES.data.gui,'WindowButtonMotionFcn','');
set(XHR_HANDLES.data.gui,'WindowButtonDownFcn',XHR_HANDLES.button);
refresh(XHR_HANDLES.data.gui);
end
clear XHR_HANDLES;
return;
end
% set(XHR_HANDLES.data.gui,'userdata',XHR_HANDLES);
return;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [H] = moveXY(H,move)
AHandle = guidata(H.data.gui);
interp = get(AHandle.InterpSelect,'Value');
xinterp = get(AHandle.Interval,'Value');
if (xinterp > 0) & (interp > 1),
% Use incremental interpolation of x values
switch move,
case 'nexty',
%H.data.xindex = H.data.xindex + 1;
H.data.xpoint = H.data.xpoint + xinterp;
case 'prevy',
%H.data.xindex = H.data.xindex - 1;
H.data.xpoint = H.data.xpoint - xinterp;
case 'nextx',
H.data.xpoint = H.data.xpoint + xinterp;
case 'prevx',
H.data.xpoint = H.data.xpoint - xinterp;
end
H = checkdatarange(H);
H = interpY(H);
updateGUI(H);
return
end
% No interpolation of x values...
if (interp > 1)
xdata = H.data.xdata(:,H.data.yindex);
[H.data.xindex] = NearestXYArrayPoint( xdata, H.data.xpoint, move );
end
switch move,
case 'nextx',
% Increase current xindex by one
if(interp == 1), H.data.xindex = H.data.xindex + 1; end
case 'prevx',
% Decrease current xindex by one
if(interp == 1), H.data.xindex = H.data.xindex - 1; end
case 'nexty',
if interp == 1
H.data.xindex = H.data.xindex + 1;
end
case 'prevy',
if interp == 1
H.data.xindex = H.data.xindex - 1;
end
otherwise
end
H = checkdatarange(H);
% Get x/y value at new x/y index
H.data.xpoint = H.data.xdata(H.data.xindex,H.data.yindex);
H.data.ypoint = H.data.ydata(H.data.xindex,H.data.yindex);
set(AHandle.InterpSelect,'Value',1);
H = updateGUI(H);
return
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [ H ] = checkdatarange(H),
% Ensure that x/y index is within data range
s = size(H.data.xdata,1);
if( H.data.xindex < 1 ),
H.data.xindex = 1;
elseif( H.data.xindex >= s ),
H.data.xindex = s;
end
s = size(H.data.ydata,2);
if( H.data.yindex < 1 ),
H.data.yindex = 1;
elseif( H.data.yindex >= s ),
H.data.yindex = s;
end
return
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [ H ] = updateDATA( H )
% Only update if mouse pointer is in the
% axis limits
set(H.data.gui,'units','normalized');
set(H.axis,'units','normalized');
axpos = get(H.axis,'position');
figcp = get(H.data.gui,'Currentpoint');
axlim = axpos(1) + axpos(3);
aylim = axpos(2) + axpos(4);
if or(figcp(1) > (axlim+.01), figcp(1) < (axpos(1)-.01)),
return;
elseif or(figcp(2) > (aylim+.01), figcp(2) < (axpos(2)-.01)),
return;
end
CurrentPoint = get(H.axis,'Currentpoint');
H.data.xpoint = CurrentPoint(1,1);
H.data.ypoint = CurrentPoint(1,2);
AHandle = guidata(H.data.gui);
doNearTrace = get(AHandle.TraceNearest,'Value');
if (doNearTrace > 0)
% Get new yindex for nearest trace
[ H.data.xpoint, ...
H.data.xindex, ...
H.data.ypoint, ...
H.data.yindex ] = NearestXYMatrixPoint( H.data.xdata,...
H.data.ydata,...
H.data.xpoint,...
H.data.ypoint);
set(AHandle.TraceSwitch,'Value',H.data.yindex)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -