function [H]=pfeil(iaxes)
% function to interaktivly draw arrows onto an existing plot
% First 2 points, the start and endpoints of the arrow have to be given
% using the mouse (ginput).
% The arrow can now be bend by giving a further point with the mouse button 1,
% the arrow passes through this point in an "nice" way.
% A click with the second button ends the arrow creation.
% with the third mouse button a menu oppens, where one can change the
% arrows settings (thickness, style, end-feathers, color, etc.)
%
% Interpolation: All points are mapped onto an x-achsis connecting the start
% and end point. This mapped x1/y1 points are then interoplated using
% interp1 onto N_pfeil (normally 200) equally spaced points. The tickness
% is put around this curve or in the rotated y1 coordinate (einfach) or
% around the curve which has been transformed back into normal coordinates 
% (Weg folgend)
%
% Input:
%    iaxes   1 means a new axes is used, spanning the whole window, other
%              axes are set to background none and not clickable
%            2 same as 1, only all other axes are clickable again
%  This can be uesed to paint arrors going from one subplot to another, etc.
% Output: the handles of the arrow, feathers and head.
%
if nargin<1; iaxes=0; end
if iaxes==1 | iaxes==2  % 
    HA0=gca;
    Haxes=findobj(gcf,'type','axes');
    for ii=1:length(Haxes)
        set(Haxes,'hittest','off','color','none')
    end
    HA1=findobj(gcf,'type','axes','tag','pfeil'); iHA1=0;
    for ii=1:length(HA1)
        P=get(HA1(ii),'position');
        if P==[0 0 1 1]; 
            set(HA1(ii),'hittest','on');
            axes(HA1(ii)); iHA1=1; break
        end
    end
    if iHA1==0;
        HA1=axes('position',[0 0 1 1],'xlim',[0 1],'xlimmode','manual',...
            'ylim',[0 1],'ylimmode','manual','visible','off','tag','pfeil');
        axes(HA1);
    end
    hold on
end

N_pfeil=200; % anzahl der Stuetzstellen
P.Feder.Pos=[1 5 9]; P.Feder.Laenge=1.5; P.Feder.shift=4; 
P.Spitze.art=1; P.Spitze.Laenge=1.5; P.Spitze.shift=5; 
P.linewidth=2;
P.Kerbe=4;
P.Farbe=[0 0 1];
P.Patch=1; P.jDicke=1;
P.Dicke=0.005;
AX=get(gca,'xlim'); DickeX=diff(AX)*P.Dicke;
AY=get(gca,'ylim'); DickeY=diff(AY)*P.Dicke;
P.INTERP=4; TP.INTERP={'nearest','linear','spline','pchip','cubic'};
hold on
[X,Y]=ginput(2);
if X(2)==X(1); X(2)=X(2)+diff(AX)*1e6; end  % genau senkrechte Pfeile
% gehen nicht!
a1=(Y(2)-Y(1))/(X(2)-X(1));
a2=-1/a1;
hyp1=sqrt(1+a1*a1); 
hyp2=sqrt(1+a2*a2);
b1=Y(1)-a1*X(1);
h1=plot(X,Y);
Tx=[0 hyp1*(X(2)-X(1))];
nachlinks=0; nachunten=0;
if Y(2)<Y(1); nachunten=1; end
if X(2)<X(1); nachlinks=1; X=fliplr(X); Y=fliplr(Y); end
Ty=[0 0]; Jxx=2;

if nachlinks==0
    Spitz=ones(1,N_pfeil);
    if P.Spitze.art==1; 
        P.Spitze.shift=ceil(P.Spitze.shift);
        Spitz(N_pfeil-P.Spitze.shift+1:N_pfeil)=[-P.Spitze.shift+1:0]/(-P.Spitze.shift);
    end
else
    Spitz=ones(1,N_pfeil);
    if P.Spitze.art==1; 
        P.Spitze.shift=ceil(P.Spitze.shift);
        Spitz(1:P.Spitze.shift)=[0:P.Spitze.shift-1]/P.Spitze.shift;
    end
end


while 1>0
    
    [xx,yy,butt]=ginput(1);
    if butt==2;
        if Jxx==2; xx=mean(X); yy=mean(Y); butt=1;
        else; break; end
    elseif butt==3; 
        [P]=uipfeil(P);
        DickeX=diff(AX)*P.Dicke;
        DickeY=diff(AY)*P.Dicke;
        
        if nachlinks==0
            Spitz=ones(1,N_pfeil);
            if P.Spitze.art==1; 
                P.Spitze.shift=ceil(P.Spitze.shift);
                Spitz(N_pfeil-P.Spitze.shift+1:N_pfeil)=[-P.Spitze.shift+1:0]/(-P.Spitze.shift);
            end
        else
            Spitz=ones(1,N_pfeil);
            if P.Spitze.art==1; 
                P.Spitze.shift=ceil(P.Spitze.shift);
                Spitz(1:P.Spitze.shift)=[0:P.Spitze.shift-1]/P.Spitze.shift;
            end
        end
        if Jxx==2; butt=1; end
    end
    if butt==1
        b2=yy-xx*a2;
        xx2=(b2-b1)/(a1-a2);
        yy2=xx2*a2+b2;
        % xx2 und yy2 ist jetzt der Punkt auf der Geraden 1
        % wo die senkrechte von dem extrapunkt faellt
        Jxx=Jxx+1;
        XX(Jxx)=xx; YY(Jxx)=yy;
        Tx(Jxx)=(xx2-X(1))*hyp1;
        Ty(Jxx)=(xx2-xx)*hyp2;
    end
    [Tx,ii]=sort(Tx); Ty=Ty(ii);
    Ixx=linspace(Tx(1),Tx(end),N_pfeil);
    
    %P=polyfit(Tx,Ty,2);Iyy=polyval(P,Ixx);
    Iyy0=interp1(Tx,Ty,Ixx,TP.INTERP{P.INTERP});
    if nachlinks==1; Iyy0=-Iyy0; end
    if nachunten==1; Iyy0=-Iyy0; end
    
    Pxx=X(1)+Ixx/hyp1;
    Pyy=Y(1)+(Pxx-X(1))*a1;
    
    % der Mittelweg des Pfeils
    Iyy=Iyy0;
    dx=-Iyy*a1/hyp1; Pxx0=Pxx+dx;
    dy= Iyy/hyp1;    Pyy0=Pyy+dy;
    
    % Die ausseren Wege
    if P.jDicke==1
        % einfache, einzelne Dicke. Einfachste Art, als erstes implementier 
        Iyy=Iyy0+Spitz*DickeX;
        dx=-Iyy*a1/hyp1; Pxx1=Pxx+dx;
        dy= Iyy/hyp1;    Pyy1=Pyy+dy;
        Iyy=Iyy0-Spitz*DickeX;
        dx=-Iyy*a1/hyp1; Pxx2=Pxx+dx;
        dy= Iyy/hyp1;    Pyy2=Pyy+dy;
    else
        % x/y Dicke verschieden, Dicke jeweils lokal
        for ii=1:N_pfeil
            ii1=max(1,ii-1); ii2=min(ii+1,N_pfeil);
            W=atan2(Pyy0(ii2)-Pyy0(ii1),Pxx0(ii2)-Pxx0(ii1));
            dy=abs(sin(W)*DickeY); dx=abs(cos(W)*DickeX);
            dx=-(sin(W)*DickeX)*Spitz(ii); dy=(cos(W)*DickeY)*Spitz(ii);
            Pxx1(ii)=Pxx0(ii)+dx; Pyy1(ii)=Pyy0(ii)+dy; 
            Pxx2(ii)=Pxx0(ii)-dx; Pyy2(ii)=Pyy0(ii)-dy;
        end
    end
    
    if exist('h3')==1; delete(h3); clear h3; end
    if exist('h4')==1; delete(h4); clear h4; end; 
    if exist('h5')==1; delete(h5); clear h5; end; 
    
    if nachlinks==0
        if P.Spitze.art==2;
            SPx=Pxx0(end)+P.Spitze.shift*(Pxx0(end)-Pxx0(end-1));
            SPy=Pyy0(end)+P.Spitze.shift*(Pyy0(end)-Pyy0(end-1));
            Pxx1=[Pxx1 SPx]; Pyy1=[Pyy1 SPy];
            Pxx0=[Pxx0 SPx]; Pyy0=[Pyy1 SPy];
        end
        Pxx=[Pxx0(P.Kerbe) Pxx1 fliplr(Pxx2) Pxx0(P.Kerbe)];
        Pyy=[Pyy0(P.Kerbe) Pyy1 fliplr(Pyy2) Pyy0(P.Kerbe)];
    else
        if P.Spitze.art==2;
            SPx=Pxx0(1)-P.Spitze.shift*(Pxx0(2)-Pxx0(1));
            SPy=Pyy0(1)-P.Spitze.shift*(Pyy0(2)-Pyy0(1));
            Pxx1=[SPx Pxx1]; Pyy1=[SPy Pyy1];
            Pxx0=[SPx Pxx0]; Pyy0=[SPy Pyy0];
        end
        Pxx=[Pxx1 Pxx0(N_pfeil+1-P.Kerbe)  fliplr(Pxx2) ];
        Pyy=[Pyy1 Pyy0(N_pfeil+1-P.Kerbe)  fliplr(Pyy2) ];
    end
    if P.Patch==1; 
        h3=patch(Pxx,Pyy,P.Farbe); 
    elseif P.Patch==2;  
        h3=plot(Pxx,Pyy,'color',P.Farbe,'linestyle','-',...
            'linewidth',P.linewidth); 
    elseif P.Patch==3;  
        h3=plot([Pxx NaN Pxx0],[Pyy NaN Pyy0],'color',P.Farbe,'linestyle','-',...
            'linewidth',P.linewidth); 
    else 
        h3=plot(Pxx0,Pyy0,'color',P.Farbe,'linestyle','-',...
            'linewidth',P.linewidth); 
    end
    if Jxx>3; delete(h2); end; h2=plot(XX,YY,'m+');
    
    % Zusatz Pfeilspitze Zeichnen
    if P.Spitze.Laenge>1;
        s=P.Spitze.shift; if P.Spitze.art==2; s=1; end  
        if nachlinks==0
            g1=N_pfeil; g2=N_pfeil+1-s;
        else
            g1=1; g2=s;
        end
        dx1=(Pxx1(g2)-Pxx0(g1))*P.Spitze.Laenge; dx2=(Pxx2(g2)-Pxx0(g1))*P.Spitze.Laenge; 
        dy1=(Pyy1(g2)-Pyy0(g1))*P.Spitze.Laenge; dy2=(Pyy2(g2)-Pyy0(g1))*P.Spitze.Laenge;
        %        h5=plot([Pxx1(g2)+dx1 Pxx0(g1) Pxx2(g2)+dx2],...
        %            [Pyy1(g2)+dy1 Pyy0(g1) Pyy2(g2)+dy2],...
        %            'color',P.Farbe,'linewidth',P.linewidth);
        h5=plot([Pxx0(g1)+dx1 Pxx0(g1) Pxx0(g1)+dx2],...
            [Pyy0(g1)+dy1 Pyy0(g1) Pyy0(g1)+dy2],...
            'color',P.Farbe,'linewidth',P.linewidth);
    end
    % Federn Zeichnen
    if P.Feder.Laenge>1;
        FederX=[];FederY=[];
        for ii=1:length(P.Feder.Pos)
            if nachlinks==0
                g1=P.Feder.Pos(ii); g2=g1+P.Feder.shift;
            else
                g1=N_pfeil+1-P.Feder.Pos(ii); g2=g1-P.Feder.shift;
            end
            dx1=(Pxx1(g1)-Pxx0(g2))*P.Feder.Laenge; dx2=(Pxx2(g1)-Pxx0(g2))*P.Feder.Laenge; 
            dy1=(Pyy1(g1)-Pyy0(g2))*P.Feder.Laenge; dy2=(Pyy2(g1)-Pyy0(g2))*P.Feder.Laenge;
            FederX=[FederX Pxx1(g1)+dx1 Pxx0(g2) Pxx2(g1)+dx2 NaN];
            FederY=[FederY Pyy1(g1)+dy1 Pyy0(g2) Pyy2(g1)+dy2 NaN];
        end
        if ~isempty(FederX); h4=plot(FederX,FederY,'color',P.Farbe,...
                'linewidth',P.linewidth); 
        end  
    end
    
end
delete(h1)
delete(h2)
if exist('h4')~=1; h4=[]; end
if exist('h5')~=1; h5=[]; end
H=[h3 h4 h5];

if iaxes==2; 
    axes(HA0);
    for ii=1:length(Haxes)
        set(Haxes,'hittest','on')
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [P]=uipfeil(P)
lang=1; % bisher nur deutsch
TEXT.Dicke={'Dicke','Width'};
prompt='Pfeil';
Farbauswahl={'r','g','b','c','m'};
TP.INTERP={'nearest','linear','spline','pchip','cubic'};
position=[130 130 600 400];
%'Color','y', ...
ui0 = figure('Name', 'Pfeil', ...
    'Position', position, ...
    'Color',[0.8 0.8 0.8],...
    'NumberTitle', 'off', ...
    'Resize', 'off',...
    'HandleVisibility','on',...
    'Menubar','none');

% Definition einer Achse um Abgrenzungslinien,etc zu zeichnen
axes('position',[0 0 1 1],'visible','off',...
    'Xlim',[0 600],'Xlimmode','manual',...
    'Ylim',[0 400],'Ylimmode','manual');

uiT=uicontrol('Style','text','tag','t_linewidth','Position',[10 270 200 20],...
    'string',['Liniendicke:' num2str(P.linewidth)]);
uilinewidth=uicontrol(ui0,'style','slider','position',[210 270 100 20],...
    'Tag','linewidth','min',1,'max',11,'value',P.linewidth,'sliderstep',[0.1 0.5],...
    'callback',...
    ['F=get(gco,''Value''); a=findobj(gcf,''Tag'',''t_linewidth'');' ...
        'set(a,''string'',[''Liniendicke:'' num2str(F)]);']);

%feder
uiT=uicontrol('Style','text','tag','t_federS','Position',[10 250 200 20],...
    'string',['Feder schraeg:' num2str(P.Feder.shift)]);
uifederS=uicontrol(ui0,'style','slider','position',[210 250 100 20],...
    'Tag','federS','min',1,'max',11,'value',P.Feder.shift,'sliderstep',[0.1 0.5],...
    'callback',...
    ['F=get(gco,''Value''); a=findobj(gcf,''Tag'',''t_federS'');' ...
        'set(a,''string'',[''Feder schraeg:'' num2str(F)]);']);
uiT=uicontrol('Style','text','tag','t_federL','Position',[10 230 200 20],...
    'string',['Feder Laenge:' num2str(P.Feder.Laenge)]);
uifederL=uicontrol(ui0,'style','slider','position',[210 230 100 20],...
    'Tag','federL','min',1,'max',11,'value',P.Feder.Laenge,...
    'sliderstep',[0.01 0.1],'callback',...
    ['F=get(gco,''Value''); a=findobj(gcf,''Tag'',''t_federL'');' ...
        'set(a,''string'',[''Feder Laenge:'' num2str(F)]);']);
%spitze
uiT=uicontrol('Style','text','tag','t_spitzeS','Position',[10 200 200 20],...
    'string',['spitze schraeg:' num2str(P.Spitze.shift)]);
uispitzeS=uicontrol(ui0,'style','slider','position',[210 200 100 20],...
    'Tag','spitzeS','min',1,'max',21,'value',P.Spitze.shift,'sliderstep',[0.05 0.2],...
    'callback',...
    ['F=get(gco,''Value''); a=findobj(gcf,''Tag'',''t_spitzeS'');' ...
        'set(a,''string'',[''spitze schraeg:'' num2str(F)]);']);
uiT=uicontrol('Style','text','tag','t_spitzeL','Position',[10 180 200 20],...
    'string',['spitze Laenge:' num2str(P.Spitze.Laenge)]);
uispitzeL=uicontrol(ui0,'style','slider','position',[210 180 180 20],...
    'Tag','spitzeL','min',1,'max',11,'value',P.Spitze.Laenge,...
    'sliderstep',[0.01 0.1],'callback',...
    ['F=get(gco,''Value''); a=findobj(gcf,''Tag'',''t_spitzeL'');' ...
        'set(a,''string'',[''spitze Laenge:'' num2str(F)]);']);
uispitzeA   =uicontrol(ui0,'style','popupmenu','Position',[400 180 200 20],...
    'Tag','spitzeA','String',{'Verdunnend','Herausragend'},'value',P.Spitze.art,...
    'FontSize',10,'BackgroundColor','w');

uiDicke  =uicontrol(ui0,'style','slider','position',[10 340 200 20],...
    'Tag','Dicke','BackgroundColor','w',...
    'min',0,'max',0.5,'value',P.Dicke,'sliderstep',[0.001 0.05],...
    'callback',['a=findobj(gcf,''Tag'',''DickeE'');' ...
        'D=get(gco,''value'');' ...
        'set(a,''String'',num2str(D));'] );  
uiT=uicontrol('Style','text','Position',[10 360 100 20],...
    'Tag','disk','String',TEXT.Dicke{lang},...
    'BackgroundColor',[0.8 0.8 0.8],'FontSize',10);
uiDickeE  =uicontrol(ui0,'style','edit','position',[110 360 100 20],...
    'Tag','DickeE','string',num2str(P.Dicke),...
    'BackgroundColor','w',...
    'callback',['a=findobj(gcf,''Tag'',''Dicke'');' ...
        'D=str2num(get(gco,''string''));' ...
        'set(a,''value'',D);']);
uijDicke   =uicontrol(ui0,'style','popupmenu','Position',[280 340 250 20],...
    'Tag','jDicke','String',{'einfach','Weg folgend'},'value',P.jDicke,...
    'FontSize',10,'BackgroundColor','w');


uiPatch   =uicontrol(ui0,'style','popupmenu','Position',[280 360 250 20],...
    'Tag','SectX','String',{'Patch','2 Linien','3 Linien','1 Linie'},'value',P.Patch,...
    'FontSize',10,'BackgroundColor','w');

uiT=uicontrol('Style','text','Position',[10 300 200 20],...
    'Tag','disk','String','Pfeilinterpolation','FontSize',10);
uiINTERP   =uicontrol(ui0,'style','popupmenu','Position',[210 300 300 20],...
    'Tag','SectX','String',TP.INTERP,'value',P.INTERP,...
    'FontSize',10,'BackgroundColor','w');

%%%%%%%%%%%%%%%% FARBAUSWAHL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
positx=10-50; posity=125; 
FF={[1 0 0],[0 1 0],[0 0 1],[0 1 1],[1 0 1],[1 1 0],[1 1 1],[0 0 0]}; 
FFt={'r','g','b','c','m','y','w','k'};
for ii=1:8
    positx=positx+50;
    if ii==5; positx=10; posity=posity-25; end
    uiT=uicontrol('Style','text','Position',[positx posity 20 20],'string',FFt{ii});
    uiFarbeR  =uicontrol(ui0,'style','radiobutton','Position',[positx+20 posity 20 20],...
        'Tag','Fr','value',0,'UserData',FF{ii},'callback',...
        ['D=get(gco,''UserData'');'...
            'a=findobj(gcf,''Tag'',''RGB_r''); set(a,''value'',D(1));' ...
            'a=findobj(gcf,''Tag'',''RGB_g''); set(a,''value'',D(2));' ...
            'a=findobj(gcf,''Tag'',''RGB_b''); set(a,''value'',D(3));' ...
            'a=findobj(gcf,''Tag'',''Farbe''); set(a,''BackgroundColor'',D);'...
            'set(a,''ForegroundColor'',''k'');']);
end

uiT=uicontrol('Style','text','Position',[300 posity 30 20],'string','r');
uiRGB_r=uicontrol(ui0,'style','slider','position',[330 posity-20 100 20],...
    'Tag','RGB_r','min',0,'max',1,'value',P.Farbe(1),'sliderstep',[0.01 0.1],...
    'callback',...
    ['F=get(gco,''Value''); a=findobj(gcf,''Tag'',''Farbe'');' ...
        'D=get(a,''BackgroundColor''); D(1)=F;' ...
        'set(a,''BackgroundColor'',D);']);
uiT=uicontrol('Style','text','Position',[300 posity+20 30 20],'string','g');
uiRGB_g=uicontrol(ui0,'style','slider','position',[330 posity   100 20],...
    'Tag','RGB_g','min',0,'max',1,'value',P.Farbe(2),'sliderstep',[0.01 0.1],...
    'callback',...
    ['F=get(gco,''Value''); a=findobj(gcf,''Tag'',''Farbe'');' ...
        'D=get(a,''BackgroundColor''); D(2)=F;' ...
        'set(a,''BackgroundColor'',D);']);
uiT=uicontrol('Style','text','Position',[300 posity+40 30 20],'string','b');
uiRGB_b=uicontrol(ui0,'style','slider','position',[330 posity+20 100 20],...
    'Tag','RGB_b','min',0,'max',1,'value',P.Farbe(3),'sliderstep',[0.01 0.1],...
    'callback',...
    ['F=get(gco,''Value''); a=findobj(gcf,''Tag'',''Farbe'');' ...
        'D=get(a,''BackgroundColor''); D(3)=F;' ...
        'set(a,''BackgroundColor'',D);']);

uiFarbe   =uicontrol(ui0,'style','pushbutton','Position',[10 posity-20 290 20],...
    'Tag','Farbe','String','Farbauswahl',...
    'FontSize',10,'BackgroundColor',P.Farbe,'callback',...
    ['F=uisetcolor; set(gco,''backgroundcolor'',F);'...
        'a=findobj(gcf,''Tag'',''RGB_r''); set(a,''value'',F(1));' ...
        'a=findobj(gcf,''Tag'',''RGB_g''); set(a,''value'',F(2));' ...
        'a=findobj(gcf,''Tag'',''RGB_b''); set(a,''value'',F(3));'] );


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
uiENDE=uicontrol(ui0,'Style','pushbutton','Position',[440 10 90 40],...
    'String','OK',...
    'Callback','uiresume(gcf);');
uiwait(ui0)

if gcf==ui0
    P.Dicke=str2num(get(uiDickeE,'string'));
    P.jDicke=get(uijDicke,'value');
    P.linewidth=get(uilinewidth,'value');
    P.Feder.Laenge=get(uifederL,'value');
    P.Feder.shift=get(uifederS,'value');
    P.Kerbe=round(P.Feder.shift);
    P.Spitze.Art=get(uispitzeA,'value');
    P.Spitze.Laenge=get(uispitzeL,'value');
    P.Spitze.shift=get(uispitzeS,'value');
    if P.Spitze.shift==0; P.Spitze.shift=-1; end
    P.Patch=get(uiPatch,'value');
    P.INTERP=get(uiINTERP,'value');
    P.Farbe=get(uiFarbe,'Backgroundcolor');
    close(gcf)
end


