##################################################################
# Modul fuer allgemeine Funktionen des Plotter-Skriptes in Pstricks
#
# Letzte Aenderung: 10.01.2012
##################################################################
use POSIX qw /floor ceil/;
use Math::Trig;
use strict;
use warnings;
my ( $zahler, $extern, $dateiname );

sub setextern {
    my ($ext) = @_;
    $extern = $ext;
}

sub getextern { return $extern; }

my ($xminachse, $xmaxachse, $yminachse, $ymaxachse, $xsetzen1, $xsetzen2,
    $ysetzen1, $ysetzen2);

$xminachse = $xmaxachse = $yminachse = $ymaxachse = $xsetzen1 = $xsetzen2 =
    $ysetzen1 = $ysetzen2 = 0;

sub achsengraph {
    my ( $x1, $y1 ) = @_;
    setachsengraph( $x1, $y1, $x1, $y1 );
}

sub setachsengraphrueck {
    $xminachse=$xmaxachse=$yminachse=$ymaxachse=0;
}

sub setachsengraph {
    my ( $xmin, $ymin, $xmax, $ymax ) = @_;


    if (   ( istzahl($xmin) == 1 )
	   && ( istzahl($ymin) == 1 )
	   && ( istzahl($xmax) == 1 )
	   && ( istzahl($ymax) == 1 ) )
    {
	
	
	if ( $xsetzen1 == 0 ) {
	    $xminachse = $xmin;
	    $xsetzen1  = 1;
	}
	else {$xminachse =min($xminachse,$xmin); }
	if ( $xsetzen2 == 0 ) {
	    $xmaxachse = $xmax;
	    $xsetzen2  = 1;
	}
	else {$xmaxachse=max($xmaxachse,$xmax);}
	if ( $ysetzen1 == 0 ) {
	    $yminachse = $ymin;
	    $ysetzen1  = 1;
	}
	else {$yminachse =min($yminachse,$ymin);}
	if ( $ysetzen2 == 0 ) {
	    $ymaxachse = $ymax;
	    $ysetzen2  = 1;
	}
	else {$ymaxachse=max($ymaxachse,$ymax); }
    }
}

sub getachsengraph {
    my ($text) = @_;
    if ( $text eq "xmin" ) { return $xminachse; }
    if ( $text eq "ymin" ) { return $yminachse; }
    if ( $text eq "xmax" ) { return $xmaxachse; }
    if ( $text eq "ymax" ) { return $ymaxachse; }
}

$dateiname = 0;

## Zeichnen von Funktionen

sub graph {
    my ( $layer, $func, $x1, $y1, $z1, $x2, $y2, $z2, $linienart,
	 $linienstaerke, $farbe, $parameter )
	= @_;

    my ( $xmin, $xmax, $ymin, $ymax, $parameterweiter, $x, $y, $z, $i, $j,
	 $jzahler, $abstandx, $abstandy, $dx, $dy, $n, $xzeichnen, $yzeichnen,
	 $innen, $aussen, $wechsel, $wechselhilf1, $wechselhilf2, $start );

    $parameterweiter = "";
    $xzeichnen       = 1;
    $yzeichnen       = 0;
    $innen           = $aussen = 0;
    $wechselhilf1    = $wechselhilf2 = 0;
    $wechsel         = 1;
    $start           = 0;

    settexthier("");

    if ( dreidimensional( $func, "y" ) == 0 ) {

	setachsengraph( $x1, $y1, $x2, $y2 );
	minmax( $x1, $y1, $x2, $y2 );
	if ( $y1 != $y2 ) {

	    for ( $j = $x1 ; $j <= $x2 ; $j = $j + ( $x2 - $x1 ) / 100 ) {
		if (   ( calcfunk( $func, "x", $j ) <= $y2 )
		       && ( calcfunk( $func, "x", $j ) >= $y1 ) )
		{

		    if ( $start == 0 ) {
			$wechsel      = 1;
			$wechselhilf1 = $wechsel;
			$start        = 1;
		    }

		    if ( $wechsel == $wechselhilf1 ) {$wechsel = $wechsel;}
		    else {$wechsel++;}
		    $wechselhilf1 = $wechsel;
		    $innen++;

		}
		else {

		    if ( $start == 0 ) {
			$wechsel      = 1;
			$wechselhilf2 = $wechsel;
			$start        = 1;
		    }

		    if ( $wechsel == $wechselhilf2 ) {$wechsel = $wechsel;}
		    else {$wechsel++;}
		    $wechselhilf2 = $wechsel;

		    $aussen++;

		}
	    }

	    $xmin = calcxmin( $func, $x1, $x2, $y1, $y2 );
	    $xmax = calcxmax( $func, $x1, $x2, $y1, $y2 );
	    if ( $xmin == $xmax ) {
		$xmin = $x1;
		$xmax = $x2;
	    }
	}
	else {
	    $xmin = $x1;
	    $xmax = $x2;
	}

	if ( getknoten() == 1 ) {
	    if ( get3dzeichnen() == 1 ) { }
	    else {
		knotensetzen( "\\pnode", $xmin, calcfunk( $func, "x", $xmin ),
			      "" );
		knotensetzen( "\\pnode", $xmax, calcfunk( $func, "x", $xmax ),
			      "" );
	    }
	}

	#	kommentar($layer,$wechsel);

#	kommentar($layer,aufrunden( (schoenetabelle( ($x2-$x1) * 10000 ) / 10000), 1));
#	kommentar($layer,schoenetabelle( ($x2-$x1) * 10000 ) / 10000);

	if ( $wechsel <= 3 ) {

	    if (   ( $func =~ /cos/ )
		   || ( $func =~ /sin/ )
		   || ( $func =~ /tan/ ) )
	    {
		if ( $parameter =~ /algebraic/ ) { $parameterweiter = ""; }
		else { $parameterweiter = "algebraic, "; }
	    }
	    $parameterweiter = $parameterweiter . $parameter;

	    if ( $parameterweiter =~ /algebraic/ ) {
		klammer($xmin);
		klammer($xmax);
		klammer($func);
		befehlerzeugen( $layer, "psplot", $farbe, $linienart,
				$linienstaerke, $parameterweiter, "", gettexthier() );
	    }
	    else {
		klammer($xmin);
		klammer($xmax);
		klammer( upn($func) );
		befehlerzeugen( $layer, "psplot", $farbe, $linienart,
				$linienstaerke, $parameterweiter, "", gettexthier() );
	    }
	    minmax( $xmin, $y1, $xmax, $y2 );
	}
	else {
	    settexthier("");
	    for ($j = $x1 ;$j <= $x2 ;$j =$j +aufrunden( ( schoenetabelle( ( $x2 - $x1 ) * 10000 ) / 10000 ),1 ) / 10) {
		if (   ( calcfunk( $func, "x", $j ) <= $y2 )
		       && ( calcfunk( $func, "x", $j ) >= $y1 ) )
		{

		    paarohneminmax( nachkommastellen( $j, 3 ),
				    nachkommastellen( calcfunk( $func, "x", $j ), 3 ) );
		}
		else {
		    liniekopf( $layer, $linienart, $linienstaerke, $farbe,
			       $parameterweiter, "", gettexthier() );
		    settexthier("");
		}

	    }

#	    listplot( $layer, "", $linienart, $linienstaerke, $farbe, gettexthier() );

	}
    }
    else {
	setachsengraph3d( $x1, $y1, $z1, $x2, $y2, $z2 );
	if ( $z1 == $z2 ) {
	    $ymin = $y1;
	    $ymax = $y2;
	    if ( $parameter =~ /xPlotpoints=([-0-9\.]+)/ ) {
		$n  = $1;
		$dx = ( $x2 - $x1 ) / $n;
	    }
	    else { $dx = ( $x2 - $x1 ) / 25; }
	    if ( $parameter =~ /yPlotpoints=([-0-9\.]+)/ ) {
		$n  = $1;
		$dy = ( $y2 - $y1 ) / $n;
	    }
	    else { $dy = ( $y2 - $y1 ) / 25; }

	    for ( $i = $y1 ; $i <= $y2 ; $i = $i + $dy ) {
		for ( $j = $x1 ; $j <= $x2 ; $j = $j + $dx ) {
		    $z = calcfunk3d( $func, "x", $j, "y", $i );
		    setachsengraph3d( $j, $i, $z, $j, $i, $z );
		    minmax3d( $j, $i, $z, $j, $i, $z );
		}
	    }
	}
	else {
	    $ymin = calcymin3d( $func, $x1, $x2, $y1, $y2, $z1, $z2 );
	    $ymax = calcymax3d( $func, $x1, $x2, $y1, $y2, $z1, $z2 );
	    setachsengraph3d( $x1, $y1, $z1, $x2, $y2, $z2 );
	    minmax3d( $x1, $y1, $z1, $x2, $y2, $z2 );
	}

	set3dzeichnen(1);

	if ( get3dpstricks() == 1 ) {
	    $parameterweiter =
		"plotstyle=curve, " . $parameterweiter . $parameter;

	    if ( $parameterweiter =~ /algebraic/ ) {

		paar( $x1,   $x2 );
		paar( $ymin, $ymax );
		klammer($func);
		befehlerzeugen( $layer, "psplotThreeD", $farbe, $linienart,
				$linienstaerke, $parameterweiter, "", gettexthier() );
	    }
	    else {
		paar( $x1,   $x2 );
		paar( $ymin, $ymax );
		klammer( upn($func) );
		befehlerzeugen( $layer, "psplotThreeD", $farbe, $linienart,
				$linienstaerke, $parameterweiter, "", gettexthier() );
	    }
	    minmax3d( $x1, $ymin, $z1, $x1, $ymax, $z2 );
	    settexthier("");

	}
	else {

	    if ( $parameter =~ /xPlotpoints=([-0-9\.]+)/ ) {
		$n = $1;
		$parameter =~ s/xPlotpoints=$n//g;
		$dx = ( $x2 - $x1 ) / $n;
	    }
	    else { $dx = ( $x2 - $x1 ) / 25; }
	    if ( $parameter =~ /yPlotpoints=([-0-9\.]+)/ ) {
		$n = $1;
		$parameter =~ s/yPlotpoints=$n//g;
		$dy = ( $ymax - $ymin ) / $n;
	    }
	    else { $dy = ( $ymax - $ymin ) / 25; }
	    $parameterweiter = $parameterweiter . $parameter;
	    settexthier("");

	    if ( $parameterweiter =~ /drawStyle=xLines/ ) {
		$parameterweiter =~ s/drawStyle=xLines,//g;
		$parameterweiter =~ s/drawStyle=xLines//g;
		$xzeichnen = 1;
	    }
	    if ( $parameterweiter =~ /drawStyle=yLines/ ) {
		$parameterweiter =~ s/drawStyle=yLines,//g;
		$parameterweiter =~ s/drawStyle=yLines//g;
		$yzeichnen = 1;
		$xzeichnen = 0;
	    }
	    if ( $parameterweiter =~ /drawStyle=xyLines/ ) {
		$parameterweiter =~ s/drawStyle=xyLines,//g;
		$parameterweiter =~ s/drawStyle=xyLines//g;
		$yzeichnen = $xzeichnen = 1;
	    }
	    if ( $parameterweiter =~ /drawStyle=yxLines/ ) {
		$parameterweiter =~ s/drawStyle=yxLines,//g;
		$parameterweiter =~ s/drawStyle=yxLines//g;
		$yzeichnen = $xzeichnen = 1;
	    }
	    $parameterweiter =~ s/hiddenLine=true,//g;
	    $parameterweiter =~ s/hiddenLine=false,//g;
	    $parameterweiter =~ s/hiddenLine=true//g;
	    $parameterweiter =~ s/hiddenLine=false//g;
	    $parameterweiter =~ s/hiddenLine,//g;
	    $parameterweiter =~ s/hiddenLine//g;
	    $n = 0;

	    if ( $xzeichnen == 1 ) {
		for ( $i = $ymin ; $i <= $ymax ; $i = $i + $dy ) {
		    for ( $j = $x1 ; $j <= $x2 ; $j = $j + $dx ) {
			if ( $z1 == $z2 ) {
			    $z = calcfunk3d( $func, "x", $j, "y", $i );
			    tripel(
				nachkommastellen( $j, 4 ),
				nachkommastellen( $i, 4 ),
				nachkommastellen( $z, 4 )
				);
			    $n++;
			}
			else {
			    if ( ( calcfunk3d( $func, "x", $j, "y", $i ) > $z1 )
				 && ( calcfunk3d( $func, "x", $j, "y", $i ) <
				      $z2 ) )
			    {
				$z = calcfunk3d( $func, "x", $j, "y", $i );
				tripel(
				    nachkommastellen( $j, 4 ),
				    nachkommastellen( $i, 4 ),
				    nachkommastellen( $z, 4 )
				    );
				$n++

			    }
			}

		    }
		    if ( $n > 1 ) {
			liniekopf( $layer, $linienart, $linienstaerke, $farbe,
				   $parameterweiter, "", gettexthier() );
		    }
		    settexthier("");
		    $n = 0;
		}
	    }

	    if ( $yzeichnen == 1 ) {

		for ( $j = $x1 ; $j <= $x2 ; $j = $j + $dx ) {
		    for ( $i = $ymin ; $i <= $ymax ; $i = $i + $dy ) {
			if ( $z1 == $z2 ) {
			    $z = calcfunk3d( $func, "x", $j, "y", $i );
			    tripel(
				nachkommastellen( $j, 4 ),
				nachkommastellen( $i, 4 ),
				nachkommastellen( $z, 4 )
				);
			    $n++;
			}
			else {
			    if ( ( calcfunk3d( $func, "x", $j, "y", $i ) > $z1 )
				 && ( calcfunk3d( $func, "x", $j, "y", $i ) <
				      $z2 ) )
			    {
				$z = calcfunk3d( $func, "x", $j, "y", $i );
				tripel(
				    nachkommastellen( $j, 4 ),
				    nachkommastellen( $i, 4 ),
				    nachkommastellen( $z, 4 )
				    );
				$n++

			    }
			}

		    }
		    if ( $n > 1 ) {

			liniekopf(
			    $layer,                               $linienart,
			    $linienstaerke,                       $farbe,
			    "plotstyle=curve" . $parameterweiter, "",
			    gettexthier()
			    );
		    }
		    settexthier("");
		    $n = 0;
		}
	    }

	}
    }
    settexthier("");

    $innen = $aussen = 0;
    $wechselhilf1 = 0;
    $wechselhilf2 = 0;
    $wechsel      = 1;
    $start        = 0;

}

sub graphrot {

    my ( $layer, $func, $x1, $y1, $x2, $y2, $schritte, $farbe, $fuellart,
	 $fuellfarbe, $linienart, $linienstaerke, $parameter ) = @_;

    setachsengraph( $x1, min( -$y1, -$y2 ), $x2, max( $y1, $y2 ) );
    minmax( $x1, $y1, $x2, $y2 );
    my ( $xmin, $xmax );

    if ( $y1 == $y2 ) {
	$xmin = $x1;
	$xmax = $x2;
    }
    else {
	$xmin = calcxmin( $func, $x1, $x2, $y1, $y2 );
	$xmax = calcxmax( $func, $x1, $x2, $y1, $y2 );
    }
    settexthier("");

    paar( $xmin, $xmax );
    klammer($schritte);
    klammer( upn($func) );
    befehlfuellungerzeugen(
	$layer,      "psVolume", $farbe,         $fuellart,
	$fuellfarbe, $linienart, $linienstaerke, $parameter,
	"",          gettexthier()
	);

    settexthier("");

}

### Folgen zeichnen

sub folge {
    my ( $layer, $func, $x1, $x2, $dx, $groesse, $linienart, $linienstaerke,
	 $farbe, $parameter ) = @_;

    setachsengraph( $x1, calcfunk( $func, "x", $x1 ),
		    $x2, calcfunk( $func, "x", $x2 ) );
    my $anzahlpunkte = aufrunden( abs( $x2 - $x1 ) / $dx + 1, 1 );

    my $parameterweiter =
	"showpoints=true, plotstyle=dots, dotstyle=o, plotpoints="
	. $anzahlpunkte
	. ", dotsize="
	. $groesse . "pt";

    $parameterweiter = $parameterweiter . $parameter;
    graph( $layer, $func, $x1, 0, 0, $x2, 0, 0, $linienart, $linienstaerke,
	   $farbe, $parameterweiter );

}

###Parametrisierte Funktionen

sub parametricplot {
    my ( $layer, $func1, $func2, $func3, $t1, $u1, $t2, $u2, $linienart,
	$linienstaerke, $farbe, $parameter ) = @_;

    my $parameterweiter = "plotpoints=200, ";
    $parameterweiter = $parameterweiter . "" . "" . $parameter;

    my ( $i, $j, $n );
    calcparaminmax( $func1, $func2, $func3, $t1, $t2, $u1, $u2 );
    

    settexthier("");

    if ( $func3 eq "" ) {
	klammer($t1);
	klammer($t2);
	if ( $parameterweiter =~ /algebraic/ ) {
	    klammer( $func1 . "|" . $func2 );
	}
	else {
	    klammer( upn($func1) . upn($func2) );
	}

	befehlerzeugen( $layer, "parametricplot", $farbe, $linienart,
			$linienstaerke, $parameterweiter, "", gettexthier() );
    }
    else {

	if ( $u1 == $u2 ) {
	    paarohneminmax( $t1, $t2 );
	    if ( $parameterweiter =~ /algebraic/ ) {
		klammer( $func1 . "|" . $func2 . "|" . $func3 );
	    }
	    else {
		klammer( upn($func1) . upn($func2) . upn($func3) );
	    }
	}
	else {
	    paarohneminmax( $t1, $t2 );
	    paarohneminmax( $u1, $u2 );
	    if ( $parameterweiter =~ /algebraic/ ) {
		klammer( $func1 . "|" . $func2 . "|" . $func3 );
	    }
	    else {
		klammer( upn($func1) . upn($func2) . upn($func3) );
	    }
	}

	set3dzeichnen(1);
	set3dpstricks(1);
	befehlerzeugen( $layer, "parametricplotThreeD", $farbe, $linienart,
			$linienstaerke, $parameterweiter, "", gettexthier() );

    }

    settexthier("");

}

### Zeichnen von allgemeinen Daten
sub fileplot {
    my ( $layer, $datei, $linienart, $linienstaerke, $farbe, $parameter ) = @_;

    settexthier("");
    setachsengraph( 0, 0, 0, 0 );
    setachsengraph3d( 0, 0, 0, 0, 0, 0 );
    klammer($datei);
    my $parameterweiter = "";

    $parameterweiter = $parameterweiter . " " . " " . $parameter;

    if ( get3dpstricks() == 1 ) {
	befehlerzeugen( $layer, "fileplotThreeD", $farbe, $linienart,
			$linienstaerke, $parameterweiter, "", gettexthier() );
    }
    else {
	befehlerzeugen( $layer, "fileplot", $farbe, $linienart, $linienstaerke,
			$parameterweiter, "", gettexthier() );
    }
    settexthier("");

}

sub listplot {
    my ( $layer, $datei, $linienart, $linienstaerke, $farbe, $parameter ) = @_;
    setachsengraph( 0, 0, 0, 0 );
    setachsengraph3d( 0, 0, 0, 0, 0, 0 );
    my $parameterweiter = "";

    $parameterweiter = $parameterweiter . " " . " " . $parameter;

    if ( get3dpstricks() == 1 ) {
	befehlerzeugen( $layer, "listplotThreeD", $farbe, $linienart,
			$linienstaerke, $parameterweiter, "", "{\\datenlesen}" );
    }
    else {
	befehlerzeugen( $layer, "listplot", $farbe, $linienart, $linienstaerke,
			$parameterweiter, "", "{\\datenlesen}" );
    }

}

sub daten {
    my ( $layer, $datei, $linienart, $linienstaerke, $farbe, $parameter ) = @_;
    setachsengraph( 0, 0, 0, 0 );
    setachsengraph3d( 0, 0, 0, 0, 0, 0 );
    my $parameterweiter = "";

    $parameterweiter = $parameterweiter . "" . "" . $parameter;

    if ( get3dpstricks() == 1 ) {
	befehlerzeugen( $layer, "dataplotThreeD", $farbe, $linienart,
			$linienstaerke, $parameterweiter, "", "{\\datenlesen}" );
    }
    else {
	befehlerzeugen( $layer, "dataplot", $farbe, $linienart, $linienstaerke,
			$parameterweiter, "", "{\\datenlesen}" );
    }

}

# Ableitungsfunktion zeichnen
sub ableitung {
    my ( $layer, $func, $grad, $x1, $y1, $x2, $y2, $linienart, $linienstaerke,
	 $farbe, $parameter )
	= @_;

    setachsengraph( $x1, $y1, $x2, $y2 );
    my ( $xmin, $xmax, $parameterweiter, $text );
    settexthier("");
    $parameterweiter = " algebraic,";
    $parameterweiter = $parameterweiter . " " . " " . $parameter;
    $xmin = sprintf( "%0.4f", calcablxmin( $func, $x1, $x2, $y1, $y2 ) );
    $xmax = sprintf( "%0.4f", calcablxmax( $func, $x1, $x2, $y1, $y2 ) );
    klammer($xmin);
    klammer($xmax);
    $text = "Derive(" . $grad . "," . $func . ")";
    klammer($text);
    befehlerzeugen( $layer, "psplot", $farbe, $linienart, $linienstaerke,
		    $parameterweiter, "", gettexthier() );

    minmax( $x1, $y1, $x2, $y2 );
    settexthier("");
}

# Stammfunktion zeichnen
sub stammfunktion {
    my ( $layer, $func, $x1, $y1, $x2, $y2, $linienart, $linienstaerke, $farbe,
	 $verschiebungswert, $parameter )
	= @_;
    setachsengraph( $x1, $y1, $x2, $y2 );
    settexthier("");
    my (
	@xpunkte,   @ypunkte, $schritt,       $i,
	@yintegral, $x,       $y,             $integral,
	$breite,    $element, $datei,         $merkex,
	$merkey,    $weite,   $schrittanzahl, $schrittweite,
	$punkte,    $nullwert
	);
    $dateiname++;
    $weite         = 3000;
    $schrittanzahl = ceil( $x2 - $x1 ) * $weite;
    $schrittweite  = ceil( ceil( $x2 - $x1 ) / ( getskalierung("x") / 2 ) );
    $punkte        = 0;
    $integral      = 0;
    $nullwert      = 0;

    # Integral wird berechnet
    $breite = ( $x2 - $x1 ) / ($schrittanzahl);
    for ( $schritt = 0 ; $schritt < $schrittanzahl + 1 ; $schritt++ ) {
	$x = $x1 + ( $x2 - $x1 ) * ( $schritt / $schrittanzahl );
	$y = calcfunk( $func, "x", $x );
	$element = ( $breite * $y );
	$integral += $element;
	$nullwert = $integral if ( $x <= 0 );
	$yintegral[$schritt] = $integral;
    }
    $nullwert -= $verschiebungswert;

    #oeffnedatei($dateiname);

    # Schleife zum zeichnen der Funktion
    for (
	$schritt = 0 ;
	$schritt < $schrittanzahl ;
	$schritt = $schritt + $schrittweite
	)
    {
	$x = nachkommastellen(
	    $x1 + ( $x2 - $x1 ) * ( $schritt / ( $schrittanzahl - 1 ) ), 3 );
	$y = nachkommastellen( $yintegral[$schritt] - $nullwert, 3 );

	# liegen die Funktionswerte innerhalb von ymin und ymax?
	if ( ( $y >= $y1 ) && ( $y <= $y2 ) ) {
	    $xpunkte[$punkte] = $x;
	    $ypunkte[$punkte] = $y;
	    $punkte++;
	}
	else {

	    # wenn nicht wird das bisherige Array ausgelesen und gezeichnet
	    if ( $punkte > 1 ) {
		#schreibedaten( $dateiname, $xpunkte[0], $ypunkte[0] );
	paar($xpunkte[0], $ypunkte[0]);
		for ( $i = 0 ; $i < $punkte - 2 ; $i = $i + 2 ) {

		    if (
			calcaenderungsrate(
			    $xpunkte[$i],       $ypunkte[$i],
			    $xpunkte[ $i + 1 ], $ypunkte[ $i + 1 ]
			) != calcaenderungsrate(
			    $xpunkte[ $i + 1 ],
			    $ypunkte[ $i + 1 ],
			    $xpunkte[ $i + 2 ],
			    $ypunkte[ $i + 2 ]
			)
			)

		    {
			#schreibedaten(
			 #   $dateiname,
			    #$xpunkte[ $i + 1 ],
			    #$ypunkte[ $i + 1 ]
			    #);
			    paar($xpunkte[$i+1], $ypunkte[$i+1]);

		    }
		}
		#schreibedaten(
		    #$dateiname,
		    #$xpunkte[ $i - 1 ],
		    #$ypunkte[ $i - 1 ]
		    #);
		    
		    paar($xpunkte[$i+1], $ypunkte[$i-1]);

	    }
	    $punkte = 0;
	}

    }

    # Restarray wird ausgelesen
    if ( $punkte > 1 ) {
	for ( $i = 0 ; $i < $punkte - 2 ; $i = $i + 2 ) {
	    if (
		calcaenderungsrate(
		    $xpunkte[$i],       $ypunkte[$i],
		    $xpunkte[ $i + 1 ], $ypunkte[ $i + 1 ]
		) != calcaenderungsrate(
		    $xpunkte[ $i + 1 ],
		    $ypunkte[ $i + 1 ],
		    $xpunkte[ $i + 2 ],
		    $ypunkte[ $i + 2 ]
		)
		)
	    {
		#schreibedaten(
		    #$dateiname,
		    #$xpunkte[ $i + 1 ],
		    #$ypunkte[ $i + 1 ]
		    #);
	paar($xpunkte[$i+1], $ypunkte[$i+1]);
	    }
	}
    }
    #schliessedatei($dateiname);
    #readdata( $layer, $dateiname );
    	liniekopf( $layer, $linienart, $linienstaerke, $farbe,
					$parameter, "", gettexthier() );
    #daten( $layer, $dateiname, $linienart, $linienstaerke, $farbe, $parameter );
    $punkte = 0;
        settexthier("");

}

# Zeichnen der Flaeche unter einer Funktion
sub integral {
    my (
	$layer,      $func,      $x1,            $y1,
	$x2,         $y2,        $farbe,         $fuellart,
	$fuellfarbe, $linienart, $linienstaerke, $parameter
	) = @_;

    setachsengraph( $x1, $y1, $x2, $y2 );
    my ( $parameterweiter, $xmin, $xmax );

    $parameterweiter = "algebraic" . $parameter;

    if ( $y1 == $y2 ) {
	$xmin = $x1;
	$xmax = $x2;

    }
    else {
	$xmin = nachkommastellen( calcxmin( $func, $x1, $x2, $y1, $y2 ), 2 );
	$xmax = nachkommastellen( calcxmax( $func, $x1, $x2, $y1, $y2 ), 2 );
    }
    schreibeinarray(
	$layer,
	sprintf(
	    "\\pscustom[fillcolor = %s]
 {\\gsave", $fuellfarbe
	)
	);
    graph( $layer, $func, $xmin, $y1, 0, $xmax, $y2, 0, $linienart,
	   $linienstaerke, $farbe, $parameter );
    linie( $layer, $xmax, 0, "", $xmin, 0, "", $linienart, $linienstaerke,
	   $farbe, $parameter, "" );
    befehlfuellungerzeugen(
	$layer,      "fill",     $farbe,         $fuellart,
	$fuellfarbe, $linienart, $linienstaerke, $parameter,
	"",          ""
	);
    schreibeinarray( $layer, sprintf("\\grestore}") );

}
### Sichern von Daten
sub datensichern {
    my ($layer) = @_;
    schreibeinarray( $layer, sprintf("\\savedata{\\mydata}[") );
}

sub readdata {
    my ( $layer, $name ) = @_;
    schreibeinarray( $layer, sprintf( "\\readdata{\\datenlesen}{%s}", $name ) );
}

sub setfilehandle { my ($file) = @_; }
my $AUSGABE;

my $filecontens = 0;

sub oeffnedatei {
    my ($name) = @_;
    if ( getextern() == 0 ) {
	if ( $filecontens == 0 ) {
	    usepackage( "", "filecontents" );
	    $filecontens = 1;
	}
	else {
	}
	schreibeinarray( 105,
			 sprintf( "\n\\begin{filecontents*}{%s}", $name ) );
	$zahler = 0;
	settexthier("");
    }
    else {
	open( $AUSGABE, '>', $name );
	$zahler = 0;
    }
}

sub schliessedatei {
    my ($name) = @_;
    if ( $extern == 0 ) {
	pstricks( 105, gettexthier() );
	pstricks( 105, "\\end{filecontents*}" );
	abstand(105);
	$zahler = 0;
    }
    else {
	close $AUSGABE;
	$zahler = 0;
    }
}

sub schreibedaten {
    my ( $name, $x, $y ) = @_;
    setachsengraph( $x, $y, $x, $y );
    $zahler++;
    if ( getextern() == 0 ) { paar( $x, $y ); }
    else                    { printf( $AUSGABE "(%g,%g)", $x, $y ); }
    minmax( $x, $y, $x, $y );
}

sub schreibedaten3d {
    my ( $name, $x, $y, $z ) = @_;
    $zahler++;
    setachsengraph3d( $x, $y, $z, $x, $y, $z );
    my ( $xersatz, $yersatz );
    $xersatz = x3d( $x, $y, $z );
    $yersatz = y3d( $x, $y, $z );
    if ( getextern() == 0 ) { tripel( $x, $y, $z ); }
    else {

	if ( get3dpstricks() == 1 ) {
	    printf( $AUSGABE "(%g,%g,%g) ", $x, $y, $z );
	}
	else { printf( $AUSGABE "(%g,%g) ", $xersatz, $yersatz ); }
    }

}

sub lesedaten {
    my ( $layer, $name ) = @_;
    my $zeile;
    open( $AUSGABE, $name ) || die $name . ": $!";
    while ( $zeile = <$AUSGABE> ) {
	schreibeinarray( $layer, sprintf( "%s", $zeile ) );
    }
}

sub oberuntersumme {
    my ( $layer, $func, $x1, $y1, $x2, $y2, $farbe, $fuellart, $fuellfarbe,
	 $linienart, $linienstaerke, $n, $summen )
	= @_;
    setachsengraph( $x1, $y1, $x2, $y2 );
    my $farbeersatz         = getfarbe();
    my $fuellartersatz      = getfuellart();
    my $fuellfarbeersatz    = getfuellfarbe();
    my $linienstaerkeersatz = getlinienstaerke();
    my $linienartersatz     = getlinienart();
    my (
	$yober,   $yunter,          $schritt,      $xlinks,
	$xrechts, $flaecheober,     $flaecheunter, $xmin,
	$xmax,    $parameterweiter, $breite
	);

    $parameterweiter = "";

    if ( $y1 != $y2 ) {
	$xmin = calcxmin( $func, $x1, $x2, $y1, $y2 );
	$xmax = calcxmax( $func, $x1, $x2, $y1, $y2 );
    }
    else {
	$xmin = $x1;
	$xmax = $x2;
    }

    $breite = nachkommastellen( ( $xmax - $xmin ) / $n, 4 );

    if ( $n > 2 ) {
	pstricks( $layer, "{" );

	einstellungen( $layer, $farbe, $fuellart, $fuellfarbe, $linienart,
		       $linienstaerke, $parameterweiter );

	for ( $schritt = 0 ; $schritt < $n ; $schritt++ ) {
	    $xlinks =
		nachkommastellen( $xmin + ( $xmax - $xmin ) * ( $schritt / ($n) ),
				  4 );
	    $xrechts = nachkommastellen(
		$xmin + ( $xmax - $xmin ) * ( ( $schritt + 1 ) / ($n) ), 4 );
	    $yober = calcymax( $func, $xlinks, $xrechts );
	    $yunter = calcymin( $func, $xlinks, $xrechts );
	    if ( abs($yober) > abs($yunter) ) {
		rechteck( $layer, $xlinks, 0, $breite, $yober, 0, "", "", "",
			  "", $linienstaerke, $parameterweiter )
		    if ( ( $summen eq "ober" ) || ( $summen eq "beide" ) );
		rechteck( $layer, $xlinks, 0, $breite, $yunter, 0, "", "", "",
			  "", $linienstaerke, $parameterweiter )
		    if ( ( $summen eq "unter" ) || ( $summen eq "beide" ) );
	    }
	    else {
		rechteck( $layer, $xlinks, 0, $breite, $yober, 0, "", "", "",
			  "", $linienstaerke, $parameterweiter )
		    if ( ( $summen eq "ober" ) || ( $summen eq "beide" ) );
		rechteck( $layer, $xlinks, 0, $breite, $yunter, 0, "", "", "",
			  "", $linienstaerke, $parameterweiter )
		    if ( ( $summen eq "unter" ) || ( $summen eq "beide" ) );
	    }
	}
	pstricks( $layer, "}" );
    }
    else {
	for ( $schritt = 0 ; $schritt < $n ; $schritt++ ) {
	    $xlinks = $xmin + ( $xmax - $xmin ) * ( $schritt / ($n) );
	    $xrechts = $xmin + ( $xmax - $xmin ) * ( ( $schritt + 1 ) / ($n) );
	    $yober = calcymax( $func, $xlinks, $xrechts );
	    $yunter = calcymin( $func, $xlinks, $xrechts );
	    if ( abs($yober) > abs($yunter) ) {
		rechteck(
		    $layer,         $xlinks,
		    0,              $breite,
		    $yober,         0,
		    $farbe,         $fuellart,
		    $fuellfarbe,    $linienart,
		    $linienstaerke, $parameterweiter
		    ) if ( ( $summen eq "ober" ) || ( $summen eq "beide" ) );
		rechteck(
		    $layer,         $xlinks,
		    0,              $breite,
		    $yunter,        0,
		    $farbe,         $fuellart,
		    $fuellfarbe,    $linienart,
		    $linienstaerke, $parameterweiter
		    ) if ( ( $summen eq "unter" ) || ( $summen eq "beide" ) );
	    }
	    else {
		rechteck(
		    $layer,         $xlinks,
		    0,              $breite,
		    $yober,         0,
		    $farbe,         $fuellart,
		    $fuellfarbe,    $linienart,
		    $linienstaerke, $parameterweiter
		    ) if ( ( $summen eq "ober" ) || ( $summen eq "beide" ) );
		rechteck(
		    $layer,         $xlinks,
		    0,              $breite,
		    $yunter,        0,
		    $farbe,         $fuellart,
		    $fuellfarbe,    $linienart,
		    $linienstaerke, $parameterweiter
		    ) if ( ( $summen eq "unter" ) || ( $summen eq "beide" ) );
	    }
	}
    }
    setfarbe($farbeersatz);
    setfuellart($fuellartersatz);
    setfuellfarbe($fuellfarbeersatz);
    setlinienstaerke($linienstaerkeersatz);
    setlinienart($linienartersatz);

}

# der Flaecheninhalt zwischen zwei Funktionen kann gezeichnet werden
sub einschluss {
    my ( $layer, $func1, $func2, $x1, $y1, $x2, $y2, $schnittpunkte, $farbe,
	 $fuellart, $fuellfarbe, $linienart, $linienstaerke, $parameter )
	= @_;
    my ( $bereichxmin, $bereichxmax, $parameterweiter );

    setachsengraph( $x1, $y1, $x2, $y2 );
    kommentar( $layer,
	       "Einschluss zwischen den Funktionen " . $func1 . " und " . $func2 );

    $parameterweiter = $parameter;
    if ( $schnittpunkte eq "links" ) {
	$bereichxmin =
	    nachkommastellen( calcschnittlinks( $func1, $func2, $x1, $x2 ), 6 );
	$bereichxmax = nachkommastellen( $x2, 2 );
    }
    elsif ( $schnittpunkte eq "rechts" ) {
	$bereichxmax =
	    nachkommastellen( calcschnittrechts( $func1, $func2, $x1, $x2 ), 6 );
	$bereichxmin = nachkommastellen( $x1, 2 );
    }
    elsif ( $schnittpunkte eq "beide" ) {
	$bereichxmin =
	    nachkommastellen( calcschnittlinks( $func1, $func2, $x1, $x2 ), 6 );
	$bereichxmax =
	    nachkommastellen( calcschnittrechts( $func1, $func2, $x1, $x2 ), 6 );
    }
    else {
	$bereichxmin = nachkommastellen( $x1, 2 );
	$bereichxmax = nachkommastellen( $x2, 2 );
    }

    einschlussanfang( $layer, $farbe, $fuellart, $fuellfarbe, $linienart,
		      $linienstaerke, $parameter );
    graph( $layer, $func1, $bereichxmin, 0, 0, $bereichxmax, 0, 0, $linienart,
	   $linienstaerke, $farbe, $parameterweiter );

    graph( $layer, $func2, $bereichxmax, 0, 0, $bereichxmin, 0, 0, $linienart,
	   $linienstaerke, $farbe, $parameterweiter );
    einschlussende( $layer, $farbe, $fuellart, $fuellfarbe, $linienart,
		    $linienstaerke, $parameter );

#	if ( calcfunk( $func1, "x", $bereichxmax ) != calcfunk( $func2, "x", $bereichxmax ) ) {
#
#		linie(
#			$layer, $bereichxmax, nachkommastellen( calcfunk( $func1, "x", $bereichxmax ), 6 ),
#			"", $bereichxmax, nachkommastellen( calcfunk( $func2,     "x", $bereichxmax ), 6 ),
#			"", $linienart, $linienstaerke, $farbe, $parameter, ""
#		);
#
#	}
#
#	if ( calcfunk( $func1, "x", $bereichxmin ) != calcfunk( $func2, "x", $bereichxmin ) ) {
#		linie(
#			$layer, $bereichxmin, nachkommastellen( calcfunk( $func1, "x", $bereichxmin ), 6 ),
#			"", $bereichxmin, nachkommastellen( calcfunk( $func2,     "x", $bereichxmin ), 6 ),
#			"", $linienart, $linienstaerke, $farbe, $parameter, ""
#		);
#
#	}

}

sub punkteende {
    my ( $layer, $farbe, $linienart, $linienstaerke ) = @_;
    schreibeinarray( $layer, sprintf("]") );
    schreibeinarray( $layer,
		     sprintf("\\dataplot[plotstyle=curve,showpoints=false,") );
    erzeugen( $layer, $linienart, $linienstaerke, $farbe, "" );
    schreibeinarray( $layer,
		     sprintf( "{\\mydata}", $farbe, $linienstaerke, $linienart ) );
}

1;
