Program dreiecke_am_bildschirm(input,output);

uses
    graph;

const
     treiber_pfad='C:\TP\BGI\';         (* Pfad zu den BGI-Treibern *)

     wait_for_key=false;                (* bei jedem Neuaufruf der rekursiven Funktion auf Return warten *)
     wait_for_key_at_the_end=true;      (* Am Ende auf Return warten *)
     check_inside_screen=true;          (* Rekursion auch beim Verlassen des Bildschirms abbrechen *)
     show_triangle=true;                (* Dreiecke zeichnen *)
     show_square=true;                  (* Quadrate zeichnen (eigentlich: 2 Linien) *)
     show_at_entry=true;                (* Beim Betreten oder beim Verlassen der Funktion zeichnen? *)
     minlen=0.5;                        (* minimale Seitenl³nge des Dreiecks *)

     breite=70;                         (* Laenge der unteren Seite des Startdreiecks *)
     winkel=30;                         (* (0 < winkel < 90) Winkel beim linken unteren Punkt *)

var
    treiber,modus : integer;

procedure show_dreieck(xa,ya,xb,yb,xc,yc:real);
begin
    if show_triangle then begin
        moveto(trunc(xa),getmaxy-trunc(ya));
        lineto(trunc(xb),getmaxy-trunc(yb));
        lineto(trunc(xc),getmaxy-trunc(yc));
        lineto(trunc(xa),getmaxy-trunc(ya))
    end
end;

procedure show_line(xa,ya,xe,ye:real);
begin
    if show_square then begin
        moveto(trunc(xa),getmaxy-trunc(ya));
        lineto(trunc(xe),getmaxy-trunc(ye));
    end
end;

procedure dreieck(xa,ya,xb,yb,xc,yc:real);
var
    a,b,c : real;
    nxa,nya,nxb,nyb,nxc,nyc : real;
    alpha : real;

begin
    if show_at_entry then
        show_dreieck(xa,ya,xb,yb,xc,yc);

    if wait_for_key then
        readln;

    a:=sqrt(sqr((xb-xc)/1)+sqr((yb-yc)/1));
    b:=sqrt(sqr((xc-xa)/1)+sqr((yc-ya)/1));
    c:=sqrt(sqr((xb-xa)/1)+sqr((yb-ya)/1));

    (* Berechnen des linken Teiles *)
    alpha:=arctan(a/b);

    nxa:=xa+(cos(pi/2)*(xc-xa)-sin(pi/2)*(yc-ya));
    nya:=ya+(sin(pi/2)*(xc-xa)+cos(pi/2)*(yc-ya));

    nxb:=nxa+xc-xa;
    nyb:=nya+yc-ya;

    nxc:=nxa+(b/c)*(cos(alpha)*(xc-xa)-sin(alpha)*(yc-ya));
    nyc:=nya+(b/c)*(sin(alpha)*(xc-xa)+cos(alpha)*(yc-ya));

    if (a>=minlen) and (b>=minlen) and (c>=minlen) then begin
       if (not check_inside_screen) or
          ((nxa>0) and (nxa<getmaxx) and
          (nxb>0) and (nxb<getmaxx) and
          (nxc>0) and (nxc<getmaxx) and
          (nya>0) and (nya<getmaxy) and
          (nyb>0) and (nyb<getmaxy) and
          (nyc>0) and (nyc<getmaxy)) then begin
              if show_at_entry then begin
                  show_line(xa,ya,nxa,nya);
                  show_line(xc,yc,nxb,nyb);
              end;
              dreieck(nxa,nya,nxb,nyb,nxc,nyc);
              if not show_at_entry then begin
                  show_line(xa,ya,nxa,nya);
                  show_line(xc,yc,nxb,nyb);
              end;

        end
    end;

    (* Berechnen des rechten Teiles *)

    alpha:=-arctan(b/a);

    nxb:=xb+(cos(pi/2)*(xb-xc)-sin(pi/2)*(yb-yc));
    nyb:=yb+(sin(pi/2)*(xb-xc)+cos(pi/2)*(yb-yc));

    nxa:=nxb+xc-xb;
    nya:=nyb+yc-yb;

    nxc:=nxb+(a/c)*(cos(alpha)*(xc-xb)-sin(alpha)*(yc-yb));
    nyc:=nyb+(a/c)*(sin(alpha)*(xc-xb)+cos(alpha)*(yc-yb));

    if (a>=minlen) and (b>=minlen) and (c>=minlen) then begin
       if (not check_inside_screen) or
          ((nxa>0) and (nxa<getmaxx) and
          (nxb>0) and (nxb<getmaxx) and
          (nxc>0) and (nxc<getmaxx) and
          (nya>0) and (nya<getmaxy) and
          (nyb>0) and (nyb<getmaxy) and
          (nyc>0) and (nyc<getmaxy)) then begin
              if show_at_entry then begin
                  show_line(xc,yc,nxa,nya);
                  show_line(xb,yb,nxb,nyb);
              end;
              dreieck(nxa,nya,nxb,nyb,nxc,nyc);
              if not show_at_entry then begin
                  show_line(xc,yc,nxa,nya);
                  show_line(xb,yb,nxb,nyb);
              end;
          end
    end;

    if not show_at_entry then
        show_dreieck(xa,ya,xb,yb,xc,yc);
end;

begin
    treiber:=detect;
    initgraph(treiber,modus,treiber_pfad);

    dreieck(getmaxx/2-breite/2,getmaxy/4,
            getmaxx/2+breite/2,getmaxy/4,
            getmaxx/2-breite/2+breite*sqr(cos(winkel*pi/180)),
                 getmaxy/4+breite*sin(winkel*pi/180)*cos(winkel*pi/180));

    if wait_for_key_at_the_end then begin
        outtextxy(0,0,'Return');
        readln
    end;
    closegraph
end.
