function varargout = Annotate_2D(varargin)
% ANNOTATE_2D M-file for Annotate_2D.fig
% ANNOTATE_2D, by itself, creates a new ANNOTATE_2D or raises the existing
% singleton*.
%
% H = ANNOTATE_2D returns the handle to a new ANNOTATE_2D or the handle to
% the existing singleton*.
%
% ANNOTATE_2D('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in ANNOTATE_2D.M with the given input arguments.
%
% ANNOTATE_2D('Property','Value',...) creates a new ANNOTATE_2D or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before Annotate_2D_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to Annotate_2D_OpeningFcn via varargin.
%
% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
% instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help Annotate_2D
% Last Modified by GUIDE v2.5 21-Jun-2009 05:18:56
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @Annotate_2D_OpeningFcn, ...
'gui_OutputFcn', @Annotate_2D_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
function Annotate_2D_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
set(gcf,'DeleteFcn',@RemoveAppData); % To remove all temp vars from workspace
setappdata(0,'Clicked',0);
t = 0:0.01:2*pi;
cos_t = cos(t) ;
sin_t = sin(t) ;
setappdata(0,'cos_t' ,cos_t );
setappdata(0,'sin_t' ,sin_t );
setappdata(0,'handles' ,handles);
setappdata(0,'DrawMode',0 );
setappdata(0,'points',[0,0,1;1,0,1]');
if isempty(findall(0,'Type','axes')) % if no axes, create one
figure(1);
axis([-1 1 -1 1]);
end
if ~isempty(findall(0,'Type','axes'))
set(handles.Axes_Menu,'Enable','On');
set(handles.Axes_Menu,'String',findall(0,'Type','axes'));
else
set(handles.Axes_Menu,'Enable','Off');
end
set(handles.HelpWindow,'Visible','off');
set(handles.AspectRatioText ,'Visible','off');
set(handles.EllipseAngleText ,'Visible','off');
set(handles.Aspect_Slider ,'Visible','off');
set(handles.Ellipse_Angle_Slider,'Visible','off');
guidata(hObject, handles);
function varargout = Annotate_2D_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
function Axes_Menu_Callback(hObject, eventdata, handles)
axes1=findall(0,'type','axes');
axes(axes1(get(hObject,'Value')));
function Axes_Menu_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function Axes_Menu_Refresh_Callback(hObject, eventdata, handles)
if ~isempty(findall(0,'Type','axes'))
set(handles.Axes_Menu,'Enable','On');
set(handles.Axes_Menu,'String',findall(0,'Type','axes'));
else
set(handles.Axes_Menu,'Enable','Off');
end
function Start_Annotate_Callback(hObject, eventdata, handles)
set(gcf,'WindowButtonDownFcn',@Button_Down);
set(gcf,'WindowButtonUpFcn' ,@Button_Up );
set(gcf,'DeleteFcn' , @Deleting);
set(gcf,'WindowButtonMotionFcn',@Button_Motion);
set(gcf,'KeyPressFcn',@Key_Press);
axes(gca);
hold on;
function End_Annotate_Callback(hObject, eventdata, handles)
Deleting(hObject,eventdata);
function Aspect_Slider_Callback(hObject, eventdata, handles)
if ~isempty(getappdata(0,'drawhandle'))&&get(handles.PostProcess,'value')
Button_Up(hObject,hObject); % junk arguments, not required
end
function Aspect_Slider_CreateFcn(hObject, eventdata, handles)
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor',[.9 .9 .9]);
end
function LineWidth_Slider_Callback(hObject, eventdata, handles)
if get(handles.PostProcess,'value')
drawhandle=getappdata(0,'drawhandle');
if ~isempty(drawhandle)
set(drawhandle,'LineWidth',get(hObject,'Value'));
end
end
function LineWidth_Slider_CreateFcn(hObject, eventdata, handles)
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor',[.9 .9 .9]);
end
function Ellipse_Angle_Slider_Callback(hObject, eventdata, handles)
if ~isempty(getappdata(0,'drawhandle'))&&get(handles.PostProcess,'value')
Button_Up(hObject,hObject); % junk arguments, not required
end
function Ellipse_Angle_Slider_CreateFcn(hObject, eventdata, handles)
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor',[.9 .9 .9]);
end
function LineStyle_Menu_Callback(hObject, eventdata, handles)
if get(handles.PostProcess,'value')
drawhandle=getappdata(0,'drawhandle');
if ~isempty(drawhandle)
linestyles=[' -';'--';' :';'-.'];
set(drawhandle,'LineStyle',linestyles(get(handles.LineStyle_Menu,'value'),:));
end
end
function LineStyle_Menu_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function LineColor_Menu_Callback(hObject, eventdata, handles)
if get(handles.PostProcess,'value')
drawhandle=getappdata(0,'drawhandle');
if ~isempty(drawhandle)
linecolors='rbkgcymw';
set(drawhandle,'Color',linecolors(get(handles.LineColor_Menu,'value')));
end
end
function LineColor_Menu_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function HelpButton_Callback(hObject, eventdata, handles)
if strcmp(get(handles.HelpWindow,'Visible'),'off')
set(handles.HelpWindow,'Visible','on');
else
set(handles.HelpWindow,'Visible','off');
end
function Key_Press(src,evnt) % to handle the delete functionality
Clicked=getappdata(0,'Clicked');
if Clicked==0 % check if the mouse is clicked, if yes, dont proceed
if strcmp(evnt.Key,'delete') % check if the delete key is pressed
drawhandle=getappdata(0,'drawhandle');
if(~isempty(drawhandle))
delete(drawhandle); % to erase the last plotted annotation
setappdata(0,'drawhandle',[]); % to indicate that no plot is available
end
end
end
function Button_Down(src,evnt)
handles=getappdata(0,'handles');
point1=get(gca,'CurrentPoint');
linestyles=[' -';'--';' :';'-.'];
linecolors='rbkgcymw';
txt=[linestyles(get(handles.LineStyle_Menu,'value'),:),linecolors(get(handles.LineColor_Menu,'value'))];
linewidth=get(handles.LineWidth_Slider,'value');
drawhandle=plot(point1(1),point1(2),txt,'EraseMode','xor','LineWidth',linewidth,'Clipping','on');
setappdata(0,'PointDown' ,point1);
setappdata(0,'PointUp' ,point1);
setappdata(0,'drawhandle',drawhandle);
setappdata(0,'Clicked' ,1);
function Button_Motion(src,evnt)
DrawMode=getappdata(0,'DrawMode');
handles=getappdata(0,'handles');
Clicked=getappdata(0,'Clicked');
if Clicked
point1=getappdata(0,'PointDown');
point2=get(gca,'CurrentPoint');
setappdata(0,'PointUp',point2);
drawhandle=getappdata(0,'drawhandle');
rad=sqrt((point2(1,1)-point1(1,1))^2+(point2(1,2)-point1(1,2))^2);
if DrawMode
aspect=get(handles.Aspect_Slider,'value');
ell_an=get(handles.Ellipse_Angle_Slider,'value')*pi/180;
cos_t=getappdata(0,'cos_t');
sin_t=getappdata(0,'sin_t');
set(drawhandle,'Xdata',point1(1,1)+aspect*rad*cos_t*cos(ell_an)+rad*sin_t*sin(ell_an),...
'YData',point1(1,2)+rad*sin_t*cos(ell_an)-aspect*rad*cos_t*sin(ell_an));
else
al=atan2(point2(1,2)-point1(1,2),...
point2(1,1)-point1(1,1));
T=[rad*cos(al) -rad*sin(al) point1(1,1);
rad*sin(al) rad*cos(al) point1(1,2);
0 0 1];
points=getappdata(0,'points');
points=T*points;
set(drawhandle,'Xdata',points(1,:),...
'YData',points(2,:));
end
end
function Button_Up(src,evnt)
handles=getappdata(0,'handles');
point1=getappdata(0,'PointDown');
point2=getappdata(0,'PointUp' );
rad=sqrt((point2(1,1)-point1(1,1))^2+(point2(1,2)-point1(1,2))^2);
DrawMode=getappdata(0,'DrawMode');
drawhandle=getappdata(0,'drawhandle');
if DrawMode
aspect=get(handles.Aspect_Slider,'value');
ell_an=get(handles.Ellipse_Angle_Slider,'value')*pi/180;
cos_t=getappdata(0,'cos_t');
sin_t=getappdata(0,'sin_t');
set(drawhandle,'Xdata',point1(1,1)+aspect*rad*cos_t*cos(ell_an)+rad*sin_t*sin(ell_an),...
'YData',point1(1,2)+rad*sin_t*cos(ell_an)-aspect*rad*cos_t*sin(ell_an),...
'EraseMode','normal');
else
al=atan2(point2(1,2)-point1(1,2),...
point2(1,1)-point1(1,1));
T=[rad*cos(al) -rad*sin(al) point1(1,1);
rad*sin(al) rad*cos(al) point1(1,2);
0 0 1];
points=getappdata(0,'points');
points=T*points;
set(drawhandle,'Xdata',points(1,:),...
'YData',points(2,:),...
'EraseMode','normal');
end
setappdata(0,'Clicked',0);
setappdata(0,'drawhandle',drawhandle);
function Deleting(src,evnt) % important function, deletes the temporary variables from MATLAB workspace
drawhandle=getappdata(0,'drawhandle');
if ~isempty(drawhandle)
set(drawhandle,'EraseMode','normal');
setappdata(0,'drawhandle',[]);
end
fig=get(gca,'parent');
set(fig,'WindowButtonDownFcn' ,[]);
set(fig,'WindowButtonUpFcn' ,[]);
set(fig,'DeleteFcn' ,[]);
set(fig,'WindowButtonMotionFcn',[]);
set(fig,'KeyPressFcn' ,[]);
function RemoveAppData(src,evnt) % removes temporary variables in workspace
fig=get(gca,'parent');
if isempty(get(fig,'parent'))
set(fig,'WindowButtonDownFcn' ,[]);
set(fig,'WindowButtonUpFcn' ,[]);
set(fig,'DeleteFcn' ,[]);
set(fig,'WindowButtonMotionFcn',[]);
set(fig,'KeyPressFcn' ,[]);
end
if ~isempty(getappdata(0,'drawhandle'))
rmappdata(0,'PointDown' );
rmappdata(0,'PointUp' );
rmappdata(0,'drawhandle');
end
rmappdata(0,'Clicked' );
rmappdata(0,'cos_t' );
rmappdata(0,'sin_t' );
rmappdata(0,'handles' );
rmappdata(0,'DrawMode');
rmappdata(0,'points' );
function ShapePanel_SelectionChangeFcn(hObject, eventdata, handles)
switch get(hObject,'Tag');
case 'DrawArrow'
setappdata(0,'DrawMode',0);
set(handles.ArrowType ,'Visible','on' );
set(handles.ArrowTypeText ,'Visible','on' );
set(handles.AspectRatioText ,'Visible','off');
set(handles.EllipseAngleText ,'Visible','off');
set(handles.Aspect_Slider ,'Visible','off');
set(handles.Ellipse_Angle_Slider,'Visible','off');
otherwise
setappdata(0,'DrawMode',1);
set(handles.ArrowType ,'Visible','off');
set(handles.ArrowTypeText ,'Visible','off');
set(handles.AspectRatioText ,'Visible','on' );
set(handles.EllipseAngleText ,'Visible','on' );
set(handles.Aspect_Slider ,'Visible','on' );
set(handles.Ellipse_Angle_Slider,'Visible','on' );
end
function ArrowType_Callback(hObject, eventdata, handles)
% define the normalized length and breadth of arrowhead
l=0.2; b=0.05;
switch get(hObject,'value')
case 1
laxes=[0 1];
waxes=[0 0];
case 2
laxes=[0 1-l 1-l 1 1-l 1-l];
waxes=[0 0 b 0 -b 0];
case 3
laxes=[l l 0 l l 1];
waxes=[0 -b 0 b 0 0];
otherwise
laxes=[l l 0 l l 1-l 1-l 1 1-l 1-l];
waxes=[0 -b 0 b 0 0 b 0 -b 0];
end
points=[laxes;waxes;ones(1,length(laxes))];
setappdata(0,'points',points);
if ~isempty(getappdata(0,'drawhandle'))&&get(handles.PostProcess,'value')
Button_Up(hObject,hObject); % junk arguments, not required
end
function ArrowType_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function PostProcess_Callback(hObject, eventdata, handles)
switch get(hObject,'value')
case 0
set(hObject,'string','Disabled');
otherwise
set(hObject,'string','Enabled');
end
function DeleteLast_Callback(hObject, eventdata, handles)
Clicked=getappdata(0,'Clicked');
if Clicked==0 % check if the mouse is clicked, if yes, dont proceed
drawhandle=getappdata(0,'drawhandle');
if(~isempty(drawhandle))
delete(drawhandle); % to erase the last plotted annotation
setappdata(0,'drawhandle',[]); % to indicate that no plot is available
end
end