program kurv;  {zeichnet Kurven in ein PIC-file, das
                mit TeXcad und LaTeX bearbeitet werden kann}

const maxfunkzahl=5;         {Maximalanzahl der Teilfunktionen}
      punktoffset:integer=0; {Nummerierung der \emline-Punkte
                              beginnt mit diesem Wert}
      strichlaenge:real=1.0; {L„nge einer Linie im Bild in mm}
      xgross:integer=120;    {Bildgr”áe X- und Y-Wert}
      ygross:integer=100;
      masstab:real=10;       {Vergr”áerung: 10 entspricht 1mm pro Einheit}
      phasemax:array [1..4] of integer=(1,0,0,0);
                             {L„ngen von abwechselnd gezeichneten und nicht
                              gezeichneten Strichelementen}
      paramstart:array [1..maxfunkzahl] of real=(0.0,0.0,-1.0,0.0,0.0);
                             {Anfangswerte der Parametrisierungen}
      paramend:array [1..maxfunkzahl] of real=(6.28,6.28,1.0,6.28,0.0);
                             {Endwerte der Parametrisierungen}

function x(teil:integer; p:real):real;
begin
   case teil of  {hier die einzelnen Funktionen eintragen}
      1: x:=cos(p);
      2: x:=1+cos(p)+0.3*cos(5*p);
      3: x:=2+p;
      4: x:=0;
      5: x:=0;
   end
end;

function y(teil:integer; p:real):real;
begin
   case teil of
      1: y:=sin(p);
      2: y:=1+sin(p)+0.3*sin(5*p);
      3: y:=p*p-1;
      4: y:=0;
      5: y:=0;
   end
end;


var picfile:text;
    name:string[8];
    punktnr:integer;

procedure prolog;
begin
   write('Name des Bildes: [.PIC] ');
   readln(name);
   assign(picfile,name+'.PIC');
   rewrite(picfile);
   writeln(picfile,'\unitlength 1mm');
   writeln(picfile,'\begin{picture}(',xgross,',',ygross,')');
   punktnr:=punktoffset;
end;  {prolog}

procedure epilog;
begin
   writeln(picfile,'\end{picture}');
   close(picfile);
end;  {epilog}


procedure zeichne(teil:integer);

var fertig,schrittok,phaseok:boolean;
    disthilf,distalt,schritthilf,
    xplotalt,xplotneu,yplotalt,yplotneu,
    xalt,yalt,xneu,yneu,
    schritt,schrittalt,para,paraneu:real;
    schrittzaehler,phase,phasenzaehler:integer;

function dist(delta:real):real;  {berechnet den Abstand zum letzten Punkt}
begin
   paraneu:=para+delta;
   xneu:=x(teil,paraneu);
   yneu:=y(teil,paraneu);
   dist:=masstab*sqrt((xneu-xalt)*(xneu-xalt)+(yneu-yalt)*(yneu-yalt));
end;  {dist}

begin {zeichne}
   write('Teil ',teil);
   phase:=1;
   phasenzaehler:=0;
   schritt:=0.1;
   para:=paramstart[teil];
   xalt:=x(teil,para);
   yalt:=y(teil,para);
   xplotalt:=xalt*masstab;
   yplotalt:=yalt*masstab;
   fertig:=false;
   schrittalt:=0.0;

   repeat
      schrittzaehler:=0;
      while abs(dist(schritt)-strichlaenge) > 0.1*strichlaenge do begin
         schritthilf:=schritt;
         disthilf:=dist(schritthilf);
         distalt:=dist(schrittalt);
         schritt:=schrittalt+
            (strichlaenge-distalt)/(disthilf-distalt)*(schritthilf-schrittalt);
         schrittzaehler:=schrittzaehler+1;
         if schrittzaehler>50 then begin
            writeln('Regula Falsi konvergiert nicht in Funktion ',teil);
            writeln('x = ',xalt:1:2,'y = ',yalt:1:2);
            halt(2);
         end;
         schrittalt:=schritthilf;
      end;

      write('.');
      para:=para+schritt;
      if para>paramend[teil] then begin
         para:=paramend[teil];
         fertig:=true;
      end;

      xneu:=x(teil,para);
      yneu:=y(teil,para);
      xplotneu:=xneu*masstab;
      yplotneu:=yneu*masstab;

      phaseok:=false;    {Phasenzaehler erh”hen}
      repeat
         if phasenzaehler < phasemax[phase] then begin
            phasenzaehler:=phasenzaehler+1;
            phaseok:=true
         end else begin
            phasenzaehler:=0;
            if phase=4 then phase:=1 else phase:=phase+1;
         end;
      until phaseok;

      if (phase=1) or (phase=3) then begin
         writeln(picfile,'\emline{',xplotalt:5:2,'}{',yplotalt:5:2,'}{',
            punktnr,'}{',xplotneu:5:2,'}{',yplotneu:5:2,'}{',punktnr+1,'}');
         punktnr:=punktnr+2;
      end;

      xalt:=xneu;
      yalt:=yneu;
      xplotalt:=xplotneu;
      yplotalt:=yplotneu;

      if abs(para-paramend[teil])<0.001 then fertig:=true;
   until fertig;
   writeln;
end; {zeichne}

procedure glatt;
begin
   phasemax[1]:=1;
   phasemax[2]:=0;
   phasemax[3]:=0;
   phasemax[4]:=0;
end;

procedure stricheln1;
begin
   phasemax[1]:=1;
   phasemax[2]:=1;
   phasemax[3]:=1;
   phasemax[4]:=1;
end;

procedure stricheln2;
begin
   phasemax[1]:=3;
   phasemax[2]:=1;
   phasemax[3]:=1;
   phasemax[4]:=1;
end;


begin {kurv}
   prolog;
   glatt;
   zeichne(1);
   stricheln1;
   zeichne(2);
   stricheln2;
   zeichne(3);
   epilog;
   writeln(punktnr,' Punkte benutzt');
end.
