function ReturnVal=TranLine(fn,arg)

%    TranLine: This program illustrates translating a line with a vector
%    Copyright (C) 1996  Brad North

%    This program is free software; you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation; either version 2 of the License, or
%    (at your option) any later version.

%    This program is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.

%    You should have received a copy of the GNU General Public License
%    along with this program; if not, write to the Free Software
%    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

%    Problems, Comments, and Suggestions can be sent to 
%            northbh@nextwork.rose-hulman.edu

if nargin == 0
	fn = 'init';

end;

Figure_Name='Translation of a Line';

%Activates the figure and makes sure it has been properly initialized

if ~strcmp(fn,'init')
	h_MainFig = gcf;

%If the current figure is not named Figure_Name then find 
%the figure that is and put its handle in h_MainFig. This will 
%be found by checking the children of root.

	if ~strcmp(get(h_MainFig,'name'),Figure_Name)
		h_figs=get(0,'children');
		h_MainFig = findobj(h_figs,'flat',...
				    'name',Figure_Name);

	%If the figure does not exist, initialize it and then
	%run the function that was originally intended

		if length(h_MainFig)==0
			TranLine('init');
			TranLine(fn);
			return;
		end;
	end;
end;
%____________________________________________________________________________
%Function: arrow

%Have 1 vector and pass it to the arg string as:
%h_vector

%(1)	h_vector:	plot in left window


if strcmp(fn,'arrow')

	h_vector=arg;
	h_axis=get(h_vector,'Parent');
	xlim=get(h_axis,'xlim');
	ylim=get(h_axis,'ylim');
	
	xdat=get(h_vector,'Xdata');
	ydat=get(h_vector,'Ydata');
	
	x=xdat(length(xdat))/(xlim(2)-xlim(1));
	y=ydat(length(ydat))/(ylim(2)-ylim(1));
	
	sine=sin(9*pi/8);
	cosine=cos(9*pi/8);

	a1=([cosine (-sine);sine cosine]*[x;y]).*.1+[x;y];
	a2=([cosine sine;-sine cosine]*[x;y]).*.1+[x;y];
	

	set(h_vector,'xdata',[0 x NaN a1(1) x a2(1)].*(xlim(2)-xlim(1)),...
		    'ydata',[0 y NaN a1(2) y a2(2)].*(ylim(2)-ylim(1)));
	drawnow;	

	return;
end;
%____________________________________________________________________________

%Function: BeginDrag

if strcmp(fn,'BeginDrag')

	set(h_MainFig,'WindowButtonUpFcn','TranLine(''EndDrag'');',...
		      'WindowButtonMotionFcn','TranLine(''Drag'');');

	return;

end;

%____________________________________________________________________________

%Function: Drag

if strcmp(fn,'Drag')

	h_data=get(h_MainFig,'user');

	h_axis=h_data(1);
	h_line=h_data(2);
	h_vector=h_data(3);
	h_vector2=h_data(4);
	h_trailer=h_data(5);
	h_VectorStayPut=h_data(6);
	h_LineVect=h_data(7);

	CurPoint=get(h_axis,'CurrentPoint');
	xlim=get(h_axis,'xlim');
	ylim=get(h_axis,'ylim');

	if CurPoint(1,1) < xlim(1)

		CurPoint(1,1) = xlim(1);

	elseif CurPoint(1,1) > xlim(2)

		CurPoint(1,1) = xlim(2);

	end;

	if CurPoint(1,2) < ylim(1)

		CurPoint(1,2) = ylim(1);

	elseif CurPoint(1,2) > ylim(2)

		CurPoint(1,2) = ylim(2);

	end;

	VectorData=[get(h_vector,'xdata');get(h_vector,'ydata')];
	RawVector=VectorData(1:2,2)-VectorData(1:2,1);

	LineData=[get(h_line,'xdata');get(h_line,'ydata')];
	LineInt=-RawVector(2)*CurPoint(1,1)+RawVector(1)*CurPoint(1,2);

	a=[-RawVector(2) RawVector(1);-LineData(2,1) LineData(1,1)];
	b=[LineInt;0];
	Intersection=a\b;
	
	
	xdata=VectorData(1,1:6)-VectorData(1,1)+Intersection(1);
	ydata=VectorData(2,1:6)-VectorData(2,1)+Intersection(2);
	
	set(h_vector,'xdata',xdata,'ydata',ydata);

	set(h_LineVect,'xdata',[0 xdata(1)],...
		       'ydata',[0 ydata(1)]);

	TranLine('arrow',h_LineVect);

	TrailPoints=get(h_trailer,'User');
	
	if xdata(2) > TrailPoints(1,2)

		TrailPoints(1,2) = xdata(2);
		TrailPoints(2,2) = ydata(2);
		set(h_trailer,'xdata',TrailPoints(1,1:2),...
		      'ydata',TrailPoints(2,1:2));


	elseif xdata(2) < TrailPoints(1,1)

		TrailPoints(1,1) = xdata(2);
		TrailPoints(2,1) = ydata(2);	
		set(h_trailer,'xdata',TrailPoints(1,1:2),...
		      'ydata',TrailPoints(2,1:2));


	end;


	
	set(h_vector2,'xdata',[0 xdata(2)],...
		      'ydata',[0 ydata(2)]);

	TranLine('arrow',h_vector2);

	set(h_trailer,'user',TrailPoints);

	return;

end;

%____________________________________________________________________________

%Function: EndDrag

if strcmp(fn,'EndDrag')

	set(h_MainFig,'WindowButtonUpFcn','',...
		      'WindowButtonMotionFcn','');

	return;

end;
%____________________________________________________________________________

%Function: SetVect

if strcmp(fn,'SetVect')

	h_data=get(h_MainFig,'User');
	h_axis=h_data(1);
	h_line=h_data(2);

	axes(h_axis);
	CurPoint=get(h_axis,'CurrentPoint');
	
	h_VectorStayPut=plot([0 CurPoint(1,1)],[0 CurPoint(1,2)]);

	h_vector=plot([0 CurPoint(1,1)],[0 CurPoint(1,2)],'k',...
	'Button','TranLine(''BeginDrag'');',...
	'erasemode','xor',...
	'visible','off');

	TranLine('arrow',h_VectorStayPut);

	set(h_line,'Button','tranline(''BeginDrag'');');

	h_vector2=plot([0 0],[0 0],'g',...
	'erasemode','xor');

	h_trailer=plot([0 0],[0 0],'c',...
	'erasemode','xor',...
	'User',[CurPoint(1,1) CurPoint(1,1);CurPoint(1,2) CurPoint(1,2)]);

	h_LineVect=plot([0 0],[0 0],'r',...
	'linewidth',2,...
	'erasemode','xor',...
	'Button','TranLine(''BeginDrag'');');
	
	TranLine('arrow',h_vector);
	title('Drag vector to form the line');
	
	refresh;
	set(h_MainFig,'pos',get(h_MainFig,'pos')+.05);
	set(h_MainFig,'pos',get(h_MainFig,'pos')-.05);

	set(h_axis,'Button','');
	h_data(3)=h_vector;
	h_data(4)=h_vector2;
	h_data(5)=h_trailer;
	h_data(6)=h_VectorStayPut;
	h_data(7)=h_LineVect;

	set(h_MainFig,'User',h_data);
	
end;
%____________________________________________________________________________

%Function: SetLine

if strcmp(fn,'SetLine')

	h_data=get(h_MainFig,'User');

	h_axis=h_data(1);
	CurPoint=get(h_axis,'CurrentPoint');
	xlim=get(h_axis,'xlim');
	ylim=get(h_axis,'ylim');

	y=CurPoint(1,2)/CurPoint(1,1).*xlim;
	h_line=plot(xlim,y,'w:','linewidth',2,...
		'user',[0 0;0 0]);

	set(h_axis,'Button','TranLine(''SetVect'');');
	title('Now click to define a vector');

	h_data(2)=h_line;
	set(h_axis,'xlim',xlim,...
		   'ylim',ylim);
	set(h_MainFig,'user',h_data);
	return;

end;
	

%____________________________________________________________________________

%Function: Reset

if strcmp(fn,'Reset')

	h_data=get(h_MainFig,'User');
	h_axis=h_data(1);
	
	TranLine('EndDrag');
	for index=2:7

		if h_data(index)~=0
			delete(h_data(index));
		end;
	end;

	title('Click to define a line throught the origin');
	set(h_axis,'ButtonDownFcn','TranLine(''SetLine'');');

	h_data(2:7)=zeros(1,6);
	set(h_MainFig,'User',h_data);
	return;

end;

%____________________________________________________________________________

%Function: init

if strcmp(fn,'init')


	delete(findobj('Name',Figure_Name));

	h_MainFig=figure('NumberTitle','off',...
			 'Name',Figure_Name,...
			 'Menu','none');

	h_RootActions=uimenu(h_MainFig,...
				'label','&Actions');

	uimenu(h_RootActions,...
		'label','&Reset',...
		'CallBack','TranLine(''Reset'');');
	
	h_axis=axes('xlim',[-1 1],...
		    'ylim',[-1 1]);

	set(h_axis,'drawmode','fast');
	plot(0,0,'wo','linewidth',2);
	hold on;
	title('Click to define a line through the origin');

	set(h_axis,'ButtonDownFcn','TranLine(''SetLine'');');



	h_data(1)=h_axis;
	h_data(2:7)=zeros(1,6);

	set(h_MainFig,'User',h_data,...
		'tag','vla');
end;
