##################################################################
# Modul für 3d-Zeichenroutinen
#
# Letzte Änderung: 06.01.2012
##################################################################
use POSIX qw /floor ceil/;
use Math::Trig;
use strict;
use warnings;
my (
	$alpha,            $beta,         $coortype,        $alphatrue,
	$betatrue,         $coortypetrue, $dreidimensional, $pstricks,
	$pstrickstrue,     $strichx,      $strichy,         $strichz,
	$markierungx,      $markierungy,  $markierungz,     $markierung,
	$markierungsdicke, $xmin,         $ymin,            $xmax,
	$ymax,             $zmin,         $zmax,            $erstex1,
	$erstex2,          $erstey1,      $erstey2,         $erstez1,
	$erstez2
);

$dreidimensional  = 0;
$alpha            = 45;
$beta             = 30;
$coortype         = 2;
$alphatrue        = $betatrue = $coortypetrue = 0;
$pstricks         = 0;
$pstrickstrue     = 0;
$strichx          = $strichy = $strichz = 0.2;
$markierungx      = -0.5;
$markierungy      = 0.5;
$markierungz      = -0.4;
$markierungsdicke = 0.6;
my $beschriftung = 0;

$markierung = 0;
#################################################################
# Wird 3d gezeichnet?
#################################################################
sub set3dzeichnen {
	my ($wert) = @_;
	$dreidimensional = $wert;
}

sub get3dzeichnen { return $dreidimensional; }
#################################################################
# Wie 3d zeichnen?
#################################################################
sub setpstricks {
	my ($wert) = @_;
	$pstrickstrue = $wert;
}

sub setbeschriftung { $beschriftung = 1; }

my $punkt = 0;
sub setpunkt { $punkt = 1; }

sub getpstricks { return $pstrickstrue; }

sub set3dpstricks {
	my ($wert) = @_;
	if ( getpstricks() == 0 ) {
		$pstricks = $wert;
		setpstricks(1);
	}
	else { $pstricks = $pstricks; }
}

sub get3dpstricks { return $pstricks; }
#################################################################
# Winkel und Koordinaten fuer 3d setzen
#################################################################
sub set3dwinkel {
	my ( $wert, $alphaoderbeta ) = @_;
	set3dzeichnen(1);
	if ( $alphaoderbeta eq "alpha" ) {
		if ( get3d("alpha") == 0 ) {
			$alpha = $wert;
			set3d( 1, "alpha" );
		}
		else { $alpha = $alpha; }
	}
	elsif ( $alphaoderbeta eq "beta" ) {
		if ( get3d("beta") == 0 ) {
			set3d( 1, "beta" );
			$beta = $wert;
		}
		else { $beta = $beta; }
	}
	else { printf("%% Kein Winkel gesetzt \n"); }
}

sub get3dwinkel {
	my ($alphaoderbeta) = @_;
	if    ( $alphaoderbeta eq "alpha" ) { return ($alpha); }
	elsif ( $alphaoderbeta eq "beta" )  { return ($beta); }
	else { return printf("%% Kein Winkel gesetzt \n"); }
}

sub set3dkoor {
	my ($wert) = @_;
	set3dzeichnen(1);
	if ( $wert > 3 ) { $wert = 2; }
	if ( get3d("coor") == 0 ) {
		$coortype = $wert;
		set3d( 1, "coor" );
	}
	else { $coortype = $coortype; }
}

sub get3dkoor { return $coortype; }

sub set3d {
	my ( $wert, $alphaoderbeta ) = @_;
	set3dzeichnen(1);
	if    ( $alphaoderbeta eq "alpha" ) { $alphatrue    = $wert; }
	elsif ( $alphaoderbeta eq "beta" )  { $betatrue     = $wert; }
	elsif ( $alphaoderbeta eq "coor" )  { $coortypetrue = $wert; }
	else                                { printf("%% Kein Winkel gesetzt \n"); }
}

sub get3d {
	my ($alphaoderbeta) = @_;
	if    ( $alphaoderbeta eq "alpha" ) { return $alphatrue; }
	elsif ( $alphaoderbeta eq "beta" )  { return $betatrue; }
	elsif ( $alphaoderbeta eq "coor" )  { return $coortypetrue; }
	else { return printf("%% Kein Winkel gesetzt \n"); }
}

sub x3d {
	my ( $x, $y, $z ) = @_;
	set3dzeichnen(1);
	if ( ( istzahl($x) == 1 ) && ( istzahl($y) == 1 ) && ( istzahl($z) == 1 ) )
	{
		if ( $coortype == 0 ) {
			return nachkommastellen(
				-(
					$x +
					  getskalierung("x") *
					  cos( degtorad( get3dwinkel("alpha") ) )
				  ) +
				  $y *
				  getskalierung("y") *
				  sin( degtorad( get3dwinkel("alpha") ) ),
				4
			);
		}
		elsif ( $coortype == 1 ) {
			return nachkommastellen(
				(
					$y *
					  getskalierung("y") -
					  $x *
					  getskalierung("x") *
					  sin( degtorad( get3dwinkel("alpha") ) - degtorad(90) )
				),
				4
			);
		}
		elsif ( $coortype == 2 ) {
			return nachkommastellen(
				( $y * getskalierung("y") - ( 0.5 * $x * getskalierung("x") ) ),
				4
			);
		}
		elsif ( $coortype == 3 ) {
			return nachkommastellen(
				$y * getskalierung("y") + ( 0.5 * $x * getskalierung("x") ),
				4 );
		}
		else { return "ERROR"; }
	}
	else { return "ERROR"; }
}

sub y3d {
	my ( $x, $y, $z ) = @_;

	set3dzeichnen(1);
	if ( ( istzahl($x) == 1 ) && ( istzahl($y) == 1 ) && ( istzahl($z) == 1 ) )
	{
		if ( $coortype == 0 ) {
			return nachkommastellen(
				-(
					$x *
					  getskalierung("x") *
					  sin( degtorad( get3dwinkel("alpha") ) ) +
					  $y *
					  getskalierung("y") *
					  cos( degtorad( get3dwinkel("alpha") ) )
				  ) *
				  sin( degtorad( get3dwinkel("beta") ) ) +
				  $z *
				  getskalierung("z") *
				  cos( degtorad( get3dwinkel("beta") ) ),
				4
			);
		}
		elsif ( $coortype == 1 ) {
			return nachkommastellen(
				$z *
				  getskalierung("z") -
				  $x *
				  getskalierung("x") *
				  cos( degtorad( get3dwinkel("alpha") ) - degtorad(90) ),
				4
			);
		}
		elsif ( $coortype == 2 ) {
			return nachkommastellen(
				( $z * getskalierung("z") - ( 0.5 * $x * getskalierung("x") ) ),
				4
			);
		}
		elsif ( $coortype == 3 ) {
			return nachkommastellen(
				$z * getskalierung("z") + ( 0.5 * $x * getskalierung("x") ),
				4 );
		}
		else { return "ERROR"; }
	}
	else { return "ERROR"; }
}

#################################################################
# Hilfsfunktionen fuer 3d
#################################################################

sub calcfunk3d {
	my $funktionsausdruck = shift;
	my $variablex         = shift;
	my $wertx             = shift;
	my $variabley         = shift;
	my $werty             = shift;
	my @ergebnis          = regelwerk( tokenizer($funktionsausdruck) );

	return rechenbaum_ausrechnen(
		$ergebnis[0]{'Baum'},
		{
			$variablex => $wertx,
			$variabley => $werty,
			'pi'       => pi(),
			'e'        => exp(1)
		}
	);

}

# Berechnet den maximalen undminimalen z-Wert
sub calczminmax {
	my ( $func, $xminwert, $yminwert, $xmaxwert, $ymaxwert, $minmax ) = @_;
	my ( $bereichmin, $bereichmax, $schrittx, $schritty, $xsuche, $ysuche,
		$zsuche, $schrittanzahl );
	$schrittanzahl = 50;

	$bereichmin = $bereichmax = 0;

	for ( $schrittx = 0 ; $schrittx < $schrittanzahl ; $schrittx++ ) {
		$xsuche = $xminwert +
		  ( $xmaxwert - $xminwert ) * ( $schrittx / ( $schrittanzahl - 1 ) );
		for ( $schritty = 0 ; $schritty < $schrittanzahl ; $schritty++ ) {
			$ysuche =
			  $yminwert +
			  ( $ymaxwert - $yminwert ) *
			  ( $schritty / ( $schrittanzahl - 1 ) );

			$zsuche = calcfunk3d( $func, "x", $xsuche, "y", $ysuche );
			if ( $zsuche < $bereichmin ) { $bereichmin = $zsuche; }
			if ( $zsuche > $bereichmax ) { $bereichmax = $zsuche; }
		}
	}

	return sprintf( "%0.4f", $bereichmin ) if ( $minmax eq "min" );
	return sprintf( "%0.4f", $bereichmax ) if ( $minmax eq "max" );
	printf( "calcxminmax: Unbekannter Parameter minmax='%s'\n", $minmax );
}

sub calczmin {
	my ( $func, $xminwert, $xmaxwert, $yminwert, $ymaxwert ) = @_;

	return sprintf( "%0.4f",
		calczminmax( $func, $xminwert, $yminwert, $xmaxwert, $ymaxwert, "min" )
	);
}

sub calczmax {
	my ( $func, $xminwert, $xmaxwert, $yminwert, $ymaxwert ) = @_;
	return sprintf( "%0.4f",
		calczminmax( $func, $xminwert, $yminwert, $xmaxwert, $ymaxwert, "max" )
	);
}

$xmin    = $ymin    = $xmax    = $ymax    = $zmin    = $zmax    = 0;
$erstex1 = $erstex2 = $erstey1 = $erstey2 = $erstez1 = $erstez2 = 0;

#package dateierzeugen;
# Minimum und Maximum setzen
sub setminmax3d {
	my ( $min, $xyz, $minmax ) = @_;
	if ( $xyz eq "x" ) {
		if   ( $minmax eq "min" ) { $xmin = $min; }
		else                      { $xmax = $min; }
	}
	if ( $xyz eq "y" ) {
		if   ( $minmax eq "min" ) { $ymin = $min; }
		else                      { $ymax = $min; }
	}
	if ( $xyz eq "z" ) {
		if   ( $minmax eq "min" ) { $zmin = $min; }
		else                      { $zmax = $min; }
	}

}

sub getminmax3d {
	my ( $xyz, $minmax ) = @_;
	if ( $xyz eq "x" ) {
		if   ( $minmax eq "min" ) { return sprintf( "%0.4f", $xmin ); }
		else                      { return sprintf( "%0.4f", $xmax ); }
	}
	if ( $xyz eq "y" ) {
		if   ( $minmax eq "min" ) { return sprintf( "%0.4f", $ymin ); }
		else                      { return sprintf( "%0.4f", $ymax ); }
	}
	if ( $xyz eq "z" ) {
		if   ( $minmax eq "min" ) { return sprintf( "%0.4f", $zmin ); }
		else                      { return sprintf( "%0.4f", $zmax ); }
	}

}

sub grenzen3d {
	my ( $x, $y, $z ) = @_;
	minmax3d( $x, $y, $z, $x, $y, $z );
}

sub minmax3d {
	my ( $x1, $y1, $z1, $x2, $y2, $z2 ) = @_;

	if ( istzahl($x1) == 1 ) {
		if ( $erstex1 == 0 ) {
			setminmax3d( $x1, "x", "min" );
			$erstex1 = 1;
		}
		else {
			if ( $x1 < getminmax3d( "x", "min" ) ) {
				setminmax3d( $x1, "x", "min" );
			}
		}
	}
	if ( istzahl($x2) == 1 ) {
		if ( $erstex2 == 0 ) {
			setminmax( $x2, "x", "max" );
			$erstex2 = 1;
		}
		else {
			if ( $x2 > getminmax3d( "x", "max" ) ) {
				setminmax3d( $x2, "x", "max" );
			}
		}
	}
	if ( istzahl($y1) == 1 ) {
		if ( $erstey1 == 0 ) {
			setminmax3d( $y1, "y", "min" );
			$erstex1 = 1;
		}
		else {
			if ( $y1 < getminmax3d( "y", "min" ) ) {
				setminmax3d( $y1, "y", "min" );
			}
		}
	}
	if ( istzahl($y2) == 1 ) {
		if ( $erstey2 == 0 ) {
			setminmax( $y2, "y", "max" );
			$erstey2 = 1;
		}
		else {
			if ( $y2 > getminmax3d( "y", "max" ) ) {
				setminmax3d( $y2, "y", "max" );
			}
		}
	}
	if ( istzahl($z1) == 1 ) {
		if ( $erstez1 == 0 ) {
			setminmax3d( $z1, "z", "min" );
			$erstez1 = 1;
		}
		else {
			if ( $z1 < getminmax3d( "z", "min" ) ) {
				setminmax3d( $z1, "z", "min" );
			}
		}
	}
	if ( istzahl($z2) == 1 ) {
		if ( $erstez2 == 0 ) {
			setminmax( $z2, "z", "max" );
			$erstez2 = 1;
		}
		else {
			if ( $z2 > getminmax3d( "z", "max" ) ) {
				setminmax3d( $z2, "z", "max" );
			}
		}
	}

	if (   ( istzahl($x1) == 0 )
		&& ( istzahl($y1) == 1 )
		&& ( istzahl($z1) == 1 ) )
	{

		minmax(
			x3d( $x1, 0, 0 ),
			y3d( $x1, 0, 0 ),
			x3d( $x1, 0, $z1 ),
			y3d( $x1, 0, 0 )
		);
		minmax(
			x3d( 0, $y1, 0 ),
			y3d( 0, $y1, 0 ),
			x3d( 0, $y1, 0 ),
			y3d( 0, $y1, 0 )
		);
		minmax(
			x3d( 0, 0, $z1 ),
			y3d( 0, 0, $z1 ),
			x3d( 0, 0, $z1 ),
			y3d( 0, 0, $z1 )
		);
		minmax(
			x3d( 0, $y1, $z1 ),
			y3d( 0, $y1, $z1 ),
			x3d( 0, $y1, $z1 ),
			y3d( 0, $y1, $z1 )
		);
		minmax(
			x3d( $x1, 0, $z1 ),
			y3d( $x1, 0, $z1 ),
			x3d( $x1, 0, $z1 ),
			y3d( $x1, 0, $z1 )
		);
		minmax(
			x3d( $x1, $y1, 0 ),
			y3d( $x1, $y1, 0 ),
			x3d( $x1, $y1, 0 ),
			y3d( $x1, $y1, 0 )
		);
		minmax(
			x3d( $x1, $y1, $z1 ),
			y3d( $x1, $y1, $z1 ),
			x3d( $x1, $y1, $z1 ),
			y3d( $x1, $y1, $z1 )
		);
	}
	if (   ( istzahl($x2) == 1 )
		&& ( istzahl($y2) == 1 )
		&& ( istzahl($z2) == 1 ) )
	{
		minmax(
			x3d( $x2, 0, 0 ),
			y3d( $x2, 0, 0 ),
			x3d( $x2, 0, $z2 ),
			y3d( $x2, 0, 0 )
		);
		minmax(
			x3d( 0, $y2, 0 ),
			y3d( 0, $y2, 0 ),
			x3d( 0, $y2, 0 ),
			y3d( 0, $y2, 0 )
		);
		minmax(
			x3d( 0, 0, $z2 ),
			y3d( 0, 0, $z2 ),
			x3d( 0, 0, $z2 ),
			y3d( 0, 0, $z2 )
		);
		minmax(
			x3d( 0, $y2, $z2 ),
			y3d( 0, $y2, $z2 ),
			x3d( 0, $y2, $z2 ),
			y3d( 0, $y2, $z2 )
		);
		minmax(
			x3d( $x2, 0, $z2 ),
			y3d( $x2, 0, $z2 ),
			x3d( $x2, 0, $z2 ),
			y3d( $x2, 0, $z2 )
		);
		minmax(
			x3d( $x2, $y2, 0 ),
			y3d( $x2, $y2, 0 ),
			x3d( $x2, $y2, 0 ),
			y3d( $x2, $y2, 0 )
		);
		minmax(
			x3d( $x2, $y2, $z2 ),
			y3d( $x2, $y2, $z2 ),
			x3d( $x2, $y2, $z2 ),
			y3d( $x2, $y2, $z2 )
		);
	}

}

my (
	$xminachse, $xmaxachse, $yminachse, $ymaxachse, $zminachse, $zmaxachse,
	$xsetzen1,  $xsetzen2,  $ysetzen1,  $ysetzen2,  $zsetzen1,  $zsetzen2
);

$xminachse = $xmaxachse = $yminachse = $ymaxachse = $zminachse = $zmaxachse =
  $xsetzen1 = $xsetzen2 = $ysetzen1 = $ysetzen2 = $zsetzen1 = $zsetzen2 = 0;

sub setachsengraph3d {
	my ( $x1, $y1, $z1, $x2, $y2, $z2 ) = @_;

	if (   ( istzahl($x1) == 1 )
		&& ( istzahl($y1) == 1 )
		&& ( istzahl($z1) == 1 )
		&& ( istzahl($x2) == 1 )
		&& ( istzahl($y2) == 1 )
		&& ( istzahl($z2) == 1 ) )
	{

		if ( $xsetzen1 == 0 ) {
			$xminachse = $x1;
			$xsetzen1  = 1;
		}
		else { $xminachse = abrunden( min( $xminachse, $x1 ), 1 ); }

		if ( $xsetzen2 == 0 ) {
			$xmaxachse = $x2;
			$xsetzen2  = 1;
		}
		else { $xmaxachse = aufrunden( max( $xmaxachse, $x2 ), 1 ); }

		if ( $ysetzen1 == 0 ) {
			$yminachse = $y1;
			$ysetzen1  = 1;
		}
		else { $yminachse = abrunden( min( $yminachse, $y1 ), 1 ); }
		if ( $ysetzen2 == 0 ) {
			$ymaxachse = $y2;
			$ysetzen2  = 1;
		}
		else { $ymaxachse = aufrunden( max( $ymaxachse, $y2 ), 1 ); }

		if ( $zsetzen1 == 0 ) {
			$zminachse = $z1;
			$zsetzen1  = 1;
		}
		else { $zminachse = abrunden( min( $zminachse, $z1 ), 1 ); }

		if ( $zsetzen2 == 0 ) {
			$zmaxachse = $z2;
			$zsetzen2  = 1;
		}
		else { $zmaxachse = aufrunden( max( $zmaxachse, $z2 ), 1 ); }
	}
}

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

##################################################################
########### Berechnungen fuer Vektoren
##################################################################
sub calcendpunktx3d {
	my ( $x, $laenge, $w1, $w2 ) = @_;
	set3dzeichnen(1);
	return $x + cos( degtorad($w2) ) * $laenge * cos( degtorad($w1) );
}

sub calcendpunkty3d {
	my ( $y, $laenge, $w1, $w2 ) = @_;
	set3dzeichnen(1);
	return $y + sin( degtorad($w2) ) * $laenge * cos( degtorad($w1) );

}

sub calcendpunktz3d {
	my ( $z, $laenge, $w1, $w2 ) = @_;
	set3dzeichnen(1);
	return $z + sin( degtorad($w1) ) * $laenge;

}

#################################################################
# Gitter im 3d
#################################################################
sub kariert3d {
	my (
		$layer,     $farbe,    $linienstaerke, $linienart,
		$xmin,      $ymin,     $zmin,          $xmax,
		$ymax,      $zmax,     $abstandx,      $dickx,
		$ganzdickx, $abstandy, $dicky,         $ganzdicky,
		$abstandz,  $dickz,    $ganzdickz,
	) = @_;

	my $knotenersatz = getknoten();

	setknoten(0);

	my ( $i, $j, $k );

	if ( get3dpstricks() == 1 ) {

		if ( $abstandx != 0 ) {
			for ( $i = $xmin ; $i <= $xmax ; $i = $i + $abstandx ) {
				minmax3d( $i, 0,     $zmin, $i, 0,     $zmax );
				minmax3d( $i, $ymin, 0,     $i, $ymax, 0 );
			}

			schleife( $layer, "nx", $xmin, $xmax, $abstandx );
			linie( $layer, "\\nx", 0, $zmin, "\\nx", 0, $zmax, $linienart,
				$linienstaerke, $farbe, "", "" );
			linie( $layer, "\\nx", $ymin, 0, "\\nx", $ymax, 0, $linienart,
				$linienstaerke, $farbe, "", "" );
			schleifenende($layer);
		}

		if ( $dickx != 0 ) {
			schleife( $layer, "nx", $xmin, $xmax, $dickx );
			linie( $layer, "\\nx", 0, $zmin, "\\nx", 0, $zmax, $linienart,
				$linienstaerke, $farbe, "", "" );
			linie( $layer, "\\nx", $ymin, 0, "\\nx", $ymax, 0, $linienart,
				$linienstaerke, $farbe, "", "" );
			schleifenende($layer);
		}
		if ( $ganzdickx != 0 ) {

			schleife( $layer, "nx", $xmin, $xmax, $ganzdickx );
			linie( $layer, "\\nx", 0, $zmin, "\\nx", 0, $zmax, $linienart,
				$linienstaerke, $farbe, "", "" );
			linie( $layer, "\\nx", $ymin, 0, "\\nx", $ymax, 0, $linienart,
				$linienstaerke, $farbe, "", "" );
			schleifenende($layer);
		}

		if ( $abstandy != 0 ) {
			for ( $i = $ymin ; $i <= $ymax ; $i = $i + $abstandy ) {
				minmax3d( 0,     $i, $zmin, 0,     $i, $zmax );
				minmax3d( $xmin, $i, 0,     $xmax, $i, 0 );
			}
			schleife( $layer, "ny", $ymin, $ymax, $abstandy );
			linie( $layer, 0, "\\ny", $zmin, 0, "\\ny", $zmax, $linienart,
				$linienstaerke, $farbe, "", "" );
			linie( $layer, $xmin, "\\ny", 0, $xmax, "\\ny", 0, $linienart,
				$linienstaerke, $farbe, "", "" );
			schleifenende($layer);
		}

		if ( $dicky != 0 ) {
			schleife( $layer, "ny", $ymin, $ymax, $dicky );
			linie( $layer, 0, "\\ny", $zmin, 0, "\\ny", $zmax, $linienart,
				$linienstaerke, $farbe, "", "" );
			linie( $layer, $xmin, "\\ny", 0, $xmax, "\\ny", 0, $linienart,
				$linienstaerke, $farbe, "", "" );
			schleifenende($layer);

		}
		if ( $ganzdicky != 0 ) {
			schleife( $layer, "ny", $ymin, $ymax, $ganzdicky );
			linie( $layer, 0, "\\ny", $zmin, 0, "\\ny", $zmax, $linienart,
				$linienstaerke, $farbe, "", "" );
			linie( $layer, $xmin, "\\ny", 0, $xmax, "\\ny", 0, $linienart,
				$linienstaerke, $farbe, "", "" );
			schleifenende($layer);
		}

		if ( $abstandz != 0 ) {
			for ( $i = $zmin ; $i <= $zmax ; $i = $i + $abstandz ) {
				minmax3d( 0,     $ymin, $i, 0,     $ymax, $i );
				minmax3d( $xmin, 0,     $i, $xmax, 0,     $i );
			}
			schleife( $layer, "nz", $zmin, $zmax, $abstandz );
			linie( $layer, 0, $ymin, "\\nz", 0, $ymax, "\\nz", $linienart,
				$linienstaerke, $farbe, "", "" );
			linie( $layer, $xmin, 0, "\\nz", $xmax, 0, "\\nz", $linienart,
				$linienstaerke, $farbe, "", "" );
			schleifenende($layer);
		}
		if ( $dickz != 0 ) {
			schleife( $layer, "nz", $zmin, $zmax, $dickz );
			linie( $layer, 0, $ymin, "\\nz", 0, $ymax, "\\nz", $linienart,
				$linienstaerke, $farbe, "", "" );
			linie( $layer, $xmin, 0, "\\nz", $xmax, 0, "\\nz", $linienart,
				$linienstaerke, $farbe, "", "" );
			schleifenende($layer);

		}
		if ( $ganzdickz != 0 ) {
			schleife( $layer, "nz", $zmin, $zmax, $ganzdickz );
			linie( $layer, 0, $ymin, "\\nz", 0, $ymax, "\\nz", $linienart,
				$linienstaerke, $farbe, "", "" );
			linie( $layer, $xmin, 0, "\\nz", $xmax, 0, "\\nz", $linienart,
				$linienstaerke, $farbe, "", "" );
			schleifenende($layer);

		}

	}
	else {
		if ( $abstandx != 0 ) {
			for ( $i = $xmin ; $i <= $xmax ; $i = $i + $abstandx ) {
				linie( $layer, $i, 0, $zmin, $i, 0, $zmax, $linienart,
					$linienstaerke, $farbe, "", "" );
				linie( $layer, $i, $ymin, 0, $i, $ymax, 0, $linienart,
					$linienstaerke, $farbe, "", "" );
			}
		}
		if ( $dickx != 0 ) {
			for ( $i = $xmin ; $i <= $xmax ; $i = $i + $dickx ) {
				linie( $layer, $i, 0, $zmin, $i, 0, $zmax, $linienart,
					$linienstaerke, $farbe, "", "" );
				linie( $layer, $i, $ymin, 0, $i, $ymax, 0, $linienart,
					$linienstaerke, $farbe, "", "" );
			}
		}
		if ( $ganzdickx != 0 ) {
			for ( $i = $xmin ; $i <= $xmax ; $i = $i + $ganzdickx ) {
				linie( $layer, $i, 0, $zmin, $i, 0, $zmax, $linienart,
					$linienstaerke, $farbe, "", "" );
				linie( $layer, $i, $ymin, 0, $i, $ymax, 0, $linienart,
					$linienstaerke, $farbe, "", "" );
			}
		}

		if ( $abstandy != 0 ) {
			for ( $i = $ymin ; $i <= $ymax ; $i = $i + $abstandy ) {
				linie( $layer, 0, $i, $zmin, 0, $i, $zmax, $linienart,
					$linienstaerke, $farbe, "", "" );
				linie( $layer, $xmin, $i, 0, $xmax, $i, 0, $linienart,
					$linienstaerke, $farbe, "", "" );
			}
		}
		if ( $dicky != 0 ) {
			for ( $i = $ymin ; $i <= $ymax ; $i = $i + $dicky ) {
				linie( $layer, 0, $i, $zmin, 0, $i, $zmax, $linienart,
					$linienstaerke, $farbe, "", "" );
				linie( $layer, $xmin, $i, 0, $xmax, $i, 0, $linienart,
					$linienstaerke, $farbe, "", "" );
			}
		}
		if ( $ganzdicky != 0 ) {
			for ( $i = $ymin ; $i <= $ymax ; $i = $i + $ganzdicky ) {
				linie( $layer, 0, $i, $zmin, 0, $i, $zmax, $linienart,
					$linienstaerke, $farbe, "", "" );
				linie( $layer, $xmin, $i, 0, $xmax, $i, 0, $linienart,
					$linienstaerke, $farbe, "", "" );
			}
		}

		if ( $abstandz != 0 ) {
			for ( $i = $zmin ; $i <= $zmax ; $i = $i + $abstandz ) {
				linie( $layer, 0, $ymin, $i, 0, $ymax, $i, $linienart,
					$linienstaerke, $farbe, "", "" );
				linie( $layer, $xmin, 0, $i, $xmax, 0, $i, $linienart,
					$linienstaerke, $farbe, "", "" );
			}
		}
		if ( $dickz != 0 ) {
			for ( $i = $zmin ; $i <= $zmax ; $i = $i + $dickz ) {
				linie( $layer, 0, $ymin, $i, 0, $ymax, $i, $linienart,
					$linienstaerke, $farbe, "", "" );
				linie( $layer, $xmin, 0, $i, $xmax, 0, $i, $linienart,
					$linienstaerke, $farbe, "", "" );
			}
		}
		if ( $ganzdickz != 0 ) {
			for ( $i = $zmin ; $i <= $zmax ; $i = $i + $ganzdickz ) {
				linie( $layer, 0, $ymin, $i, 0, $ymax, $i, $linienart,
					$linienstaerke, $farbe, "", "" );
				linie( $layer, $xmin, 0, $i, $xmax, 0, $i, $linienart,
					$linienstaerke, $farbe, "", "" );
			}
		}
	}
	setknoten($knotenersatz);

}

#################################################################
# Achsen im 3d
#################################################################

sub achsen3d {
	my (
		$layer,    $farbe, $linienstaerke, $linienart,
		$pfeilart, $xmin,  $xmax,          $ymin,
		$ymax,     $zmin,  $zmax,          $dx,
		$xskala,   $xtext, $dy,            $yskala,
		$ytext,    $dz,    $zskala,        $ztext
	) = @_;

	my $knotenersatz = getknoten();

	if ( getgitter() == 1 ) {
		kariert3d( 1, "lightgray", 0.25, "solid", $xmin, $ymin, $zmin, $xmax,
			$ymax, $zmax, $dx, 0, 0, $dy, 0, 0, $dz, 0, 0 );
		setgitter(2);
	}

	setknoten(0);

	setgrossskalierung3d( $xmax - $xmin, $ymax - $ymin, $zmax - $zmin );
	setachsengraph3d( $xmin, $ymin, $zmin, $xmax, $ymax, $zmax );

	if ( ( getgitter() == 1 ) || ( getgitter() == 3 ) ) {
		kariert3d( $layer, "lightgray", 0.25, "solid", $xmin, $ymin, $zmin,
			$xmax, $ymax, $zmax, $dx, 0, 0, $dy, 0, 0, $dz, 0, 0 );
		setgitter(2);
	}

	minmax3d( $xmin, 0,     0,     $xmax, 0, 0 );
	minmax3d( 0,     $ymin, 0,     $ymax, 0, 0 );
	minmax3d( 0,     0,     $zmin, 0,     0, $zmax );

	my ( $parameterweiter, $i, $j, $k );
	$parameterweiter = "";
	$i = $j = $k = 0;

	if ( $xmin != $xmax ) {
		for ( $i = $xmin ; $i <= $xmax + $dx ; $i = $i + $dx ) {
			minmax3d( $i, 0, 0, $i, 0, 0 );
		}
	}
	if ( $ymin != $ymax ) {
		for ( $i = $ymin ; $i <= $ymax + $dy ; $i = $i + $dy ) {
			minmax3d( 0, $i, 0, 0, $i, 0 );
		}
	}
	if ( $zmin != $zmax ) {
		for ( $i = $zmin ; $i <= $zmax + $dz ; $i = $i + $dz ) {
			minmax3d( 0, 0, $i, 0, 0, $i );
		}
	}

	set3dzeichnen(1);

	if ( get3dpstricks() == 1 ) {

		$parameterweiter =
		    $parameterweiter
		  . "comma, "
		  . "drawing, planecorr=normal,"
		  . "linecolor="
		  . $farbe
		  . ", xMin="
		  . nachkommastellen( $xmin, 4 )
		  . ", xMax="
		  . nachkommastellen( $xmax, 4 )
		  . ", yMin="
		  . nachkommastellen( $ymin, 4 )
		  . ", yMax="
		  . nachkommastellen( $ymax, 4 )
		  . ", zMin="
		  . nachkommastellen( $zmin, 4 )
		  . ", zMax="
		  . nachkommastellen( $zmax, 4 )
		  . ", nameX="
		  . $xtext
		  . ", nameY="
		  . $ytext
		  . ", nameZ="
		  . $ztext;

		if ( get3dpstricks() == 1 ) {

			my $hilfsdicke = $markierungsdicke;
			$markierungsdicke = 0;

			if ( $xmin != $xmax ) {
				for ( $i = ( 0 + $dx ) ; $i < $xmax ; $i = $i + $dx ) {
					xstrich3d( $layer, $i, $farbe );
				}
				for ( $i = ( 0 - $dx ) ; $i > $xmin ; $i = $i - $dx ) {
					xstrich3d( $layer, $i, $farbe );
				}
			}
			if ( $ymin != $ymax ) {
				for ( $j = ( 0 + $dy ) ; $j < $ymax ; $j = $j + $dy ) {
					ystrich3d( $layer, $j, $farbe );
				}
				for ( $j = ( 0 - $dy ) ; $j > $ymin ; $j = $j - $dy ) {
					ystrich3d( $layer, $j, $farbe );
				}
			}
			if ( $zmin != $zmax ) {
				for ( $k = ( 0 + $dz ) ; $k < $zmax ; $k = $k + $dz ) {
					zstrich3d( $layer, $k, $farbe );
				}
				for ( $k = ( 0 - $dz ) ; $k > $zmin ; $k = $k - $dz ) {
					zstrich3d( $layer, $k, $farbe );
				}
			}
			$markierungsdicke = $hilfsdicke;

			if ( $xskala eq "normal" ) {

				if ( $xmin != $xmax ) {
					if ( $xmax != 0 ) {
						schleife( $layer, "nx", 0 + $dx, $xmax - $dx, $dx );
						xmarkierung3d( $layer, "\\nx", "\\nx", $farbe );
						schleifenende($layer);

					}
					if ( $xmin != 0 ) {
						schleife( $layer, "nx", 0 - $dx, $xmin + $dx, -$dx );
						xmarkierung3d( $layer, "\\nx", "\\nx", $farbe );
						schleifenende($layer);
					}
				}

				if ( $ymin != $ymax ) {
					if ( $ymax != 0 ) {
						schleife( $layer, "ny", 0 + $dy, $ymax - $dy, $dy );
						ymarkierung3d( $layer, "\\ny", "\\ny", $farbe );
						schleifenende($layer);
					}
					if ( $ymin != 0 ) {

						schleife( $layer, "ny", 0 - $dy, $ymin + $dy, -$dy );
						ymarkierung3d( $layer, "\\ny", "\\ny", $farbe );
						schleifenende($layer);
					}
				}
				if ( $zmin != $zmax ) {
					if ( $zmax != 0 ) {
						schleife( $layer, "nz", 0 + $dz, $zmax - $dz, $dz );
						zmarkierung3d( $layer, "\\nz", "\\nz", $farbe );
						schleifenende($layer);
					}
					if ( $zmin != 0 ) {
						schleife( $layer, "nz", 0 - $dz, $zmin + $dz, -$dz );
						zmarkierung3d( $layer, "\\nz", "\\nz", $farbe );
						schleifenende($layer);
					}
				}
			}
			elsif ( $xskala eq "nurstriche" ) {

				if ( $xmin != $xmax ) {

					if ( $xmax != 0 ) {
						schleife( $layer, "nx", 0 + $dx, $xmax - $dx, $dx );
						xstrich3d( $layer, "\\nx", $farbe );
						schleifenende($layer);
					}
					if ( $xmin != 0 ) {
						schleife( $layer, "nx", 0 - $dx, $xmin + $dx, -$dx );
						xstrich3d( $layer, "\\nx", $farbe );
						schleifenende($layer);
					}
				}
				if ( $ymin != $ymax ) {
					if ( $ymax != 0 ) {
						schleife( $layer, "ny", 0 + $dy, $ymax - $dy, $dy );
						ystrich3d( $layer, "\\ny", $farbe );
						schleifenende($layer);
					}
					if ( $ymin != 0 ) {
						schleife( $layer, "ny", 0 - $dy, $ymin + $dy, -$dy );
						ystrich3d( $layer, "\\ny", $farbe );
						schleifenende($layer);
					}
				}
				if ( $zmin != $zmax ) {
					if ( $zmax != 0 ) {
						schleife( $layer, "nz", 0 + $dz, $zmax - $dz, $dz );
						zstrich3d( $layer, "\\nz", $farbe );
						schleifenende($layer);
					}
					if ( $zmin != 0 ) {
						schleife( $layer, "nz", 0 - $dz, $zmin + $dz, -$dz );
						zstrich3d( $layer, "\\nz", $farbe );
						schleifenende($layer);
					}
				}
			}
			elsif ( $xskala eq "nureins" ) {
				if ( $xmin != $xmax ) {
					xmarkierung3d( $layer, 1, 1, $farbe );
				}
				if ( $ymin != $ymax ) {
					ymarkierung3d( $layer, 1, 1, $farbe );
				}
				if ( $zmin != $zmax ) {
					zmarkierung3d( $layer, 1, 1, $farbe );
				}

			}
			elsif ( $xskala eq "nurstrichundeins" ) {

				if ( $xmin != $xmax ) {

					if ( $xmax != 0 ) {
						schleife( $layer, "nx", 0 + $dx, $xmax - $dx, $dx );
						xstrich3d( $layer, "\\nx", "\\nx", $farbe );
						schleifenende($layer);
					}
					if ( $xmin != 0 ) {
						schleife( $layer, "nx", 0 - $dx, $xmin + $dx, -$dx );
						xstrich3d( $layer, "\\nx", "\\nx", $farbe );
						schleifenende($layer);
					}
				}
				if ( $ymin != $ymax ) {
					if ( $ymax != 0 ) {
						schleife( $layer, "ny", 0 + $dy, $ymax - $dy, $dy );
						ystrich3d( $layer, "\\ny", "\\ny", $farbe );
						schleifenende($layer);
					}
					if ( $ymin != 0 ) {
						schleife( $layer, "ny", 0 - $dy, $ymin + $dy, -$dy );
						ystrich3d( $layer, "\\ny", "\\ny", $farbe );
						schleifenende($layer);
					}
				}
				if ( $zmin != $zmax ) {
					if ( $zmax != 0 ) {
						schleife( $layer, "nz", 0 + $dz, $ymax - $dz, $dz );
						zstrich3d( $layer, "\\nz", "\\nz", $farbe );
						schleifenende($layer);
					}
					if ( $zmin != 0 ) {
						schleife( $layer, "nz", 0 - $dz, $zmin + $dz, -$dz );
						zstrich3d( $layer, "\\nz", "\\nz", $farbe );
						schleifenende($layer);
					}
				}
				if ( $xmin != $xmax ) {
					xmarkierung3d( $layer, 1, 1, $farbe );
				}
				if ( $ymin != $ymax ) {
					ymarkierung3d( $layer, 1, 1, $farbe );
				}
				if ( $zmin != $zmax ) {
					zmarkierung3d( $layer, 1, 1, $farbe );
				}
			}

		}
		else {
			if ( $xskala eq "normal" ) {
				if ( $xmin != $xmax ) {
					for ( $i = ( 0 + $dx ) ; $i < $xmax ; $i = $i + $dx ) {
						xmarkierung3d( $layer, $i, $i, $farbe );
					}
					for ( $i = ( 0 - $dx ) ; $i > $xmin ; $i = $i - $dx ) {
						xmarkierung3d( $layer, $i, $i, $farbe );
					}
				}
				if ( $ymin != $ymax ) {
					for ( $j = ( 0 + $dy ) ; $j < $ymax ; $j = $j + $dy ) {
						ymarkierung3d( $layer, $j, $j, $farbe );
					}
					for ( $j = ( 0 - $dy ) ; $j > $ymin ; $j = $j - $dy ) {
						ymarkierung3d( $layer, $j, $j, $farbe );
					}
				}
				if ( $zmin != $zmax ) {
					for ( $k = ( 0 + $dz ) ; $k < $zmax ; $k = $k + $dz ) {
						zmarkierung3d( $layer, $k, $k, $farbe );
					}
					for ( $k = ( 0 - $dz ) ; $k > $zmin ; $k = $k - $dz ) {
						zmarkierung3d( $layer, $k, $k, $farbe );
					}
				}
			}
			elsif ( $xskala eq "nurstriche" ) {
				if ( $xmin != $xmax ) {
					for ( $i = ( 0 + $dx ) ; $i < $xmax ; $i = $i + $dx ) {
						xstrich3d( $layer, $i, $farbe );
					}
					for ( $i = ( 0 - $dx ) ; $i > $xmin ; $i = $i - $dx ) {
						xstrich3d( $layer, $i, $farbe );
					}
				}
				if ( $ymin != $ymax ) {
					for ( $j = ( 0 + $dy ) ; $j < $ymax ; $j = $j + $dy ) {
						ystrich3d( $layer, $j, $farbe );
					}
					for ( $j = ( 0 - $dy ) ; $j > $ymin ; $j = $j - $dy ) {
						ystrich3d( $layer, $j, $farbe );
					}
				}
				if ( $zmin != $zmax ) {
					for ( $k = ( 0 + $dz ) ; $k < $zmax ; $k = $k + $dz ) {
						zstrich3d( $layer, $k, $farbe );
					}
					for ( $k = ( 0 - $dz ) ; $k > $zmin ; $k = $k - $dz ) {
						zstrich3d( $layer, $k, $farbe );
					}
				}
			}
			elsif ( $xskala eq "nureins" ) {
				if ( $xmin != $xmax ) {
					xmarkierung3d( $layer, 1, 1, $farbe );
				}
				if ( $ymin != $ymax ) {
					ymarkierung3d( $layer, 1, 1, $farbe );
				}
				if ( $zmin != $zmax ) {
					zmarkierung3d( $layer, 1, 1, $farbe );
				}

			}
			elsif ( $xskala eq "strichundeins" ) {
				for ( $i = ( 0 + $dx ) ; $i < $xmax ; $i = $i + $dx ) {
					if ( $i == 1 ) { xmarkierung3d( $layer, 1, 1, $farbe ); }
					else           { xstrich3d( $layer, $i, $farbe ); }
				}
				for ( $i = ( 0 - $dx ) ; $i > $xmin ; $i = $i - $dx ) {
					xstrich3d( $layer, $i, $farbe );
				}
				for ( $j = ( 0 + $dy ) ; $j < $ymax ; $j = $j + $dy ) {
					if ( $j == 1 ) { ymarkierung3d( $layer, 1, 1, $farbe ); }
					else           { ystrich3d( $layer, $j, $farbe ); }
				}
				for ( $j = ( 0 - $dy ) ; $j > $ymin ; $j = $j - $dy ) {
					ystrich3d( $layer, $j, $farbe );
				}
				for ( $k = ( 0 + $dz ) ; $k < $zmax ; $k = $k + $dz ) {
					if ( $k == 1 ) { zmarkierung3d( $layer, 1, 1, $farbe ); }
					else           { zstrich3d( $layer, $k, $farbe ); }
				}
				for ( $k = ( 0 - $dz ) ; $k > $zmin ; $k = $k - $dz ) {
					zstrich3d( $layer, $k, $farbe );
				}

			}

			else { $parameterweiter = $parameterweiter; }

		}

		befehlerzeugen( $layer, "pstThreeDCoor", $farbe, $linienart,
			$linienstaerke, $parameterweiter, "", "" );
	}
	else {
		if ( $xmin != $xmax ) {
			if ( $xmax == 0 ) {
				linie( $layer, $xmin, 0, 0, $xmax, 0, 0, $linienart,
					$linienstaerke, $farbe, "", $pfeilart );
			}
			else {
				linie( $layer, $xmin, 0, 0, $xmax, 0, 0, $linienart,
					$linienstaerke, $farbe, "", $pfeilart );
			}
		}
		if ( $ymin != $ymax ) {
			if ( $ymax == 0 ) {
				linie( $layer, 0, $ymin, 0, 0, $ymax, 0, $linienart,
					$linienstaerke, $farbe, "", $pfeilart );
			}
			else {
				linie( $layer, 0, $ymin, 0, 0, $ymax, 0, $linienart,
					$linienstaerke, $farbe, "", $pfeilart );
			}
		}
		if ( $zmin != $zmax ) {
			if ( $zmax == 0 ) {
				linie( $layer, 0, 0, $zmin, 0, 0, $zmax, $linienart,
					$linienstaerke, $farbe, "", $pfeilart );
			}
			else {
				linie( $layer, 0, 0, $zmin, 0, 0, $zmax, $linienart,
					$linienstaerke, $farbe, "", $pfeilart );
			}
		}

		if ( $xskala eq "normal" ) {
			if ( $xmin != $xmax ) {
				for ( $i = ( 0 + $dx ) ; $i < $xmax ; $i = $i + $dx ) {
					xmarkierung3d( $layer, $i, $i, $farbe );
				}
				for ( $i = ( 0 - $dx ) ; $i > $xmin ; $i = $i - $dx ) {
					xmarkierung3d( $layer, $i, $i, $farbe );
				}
			}
			if ( $ymin != $ymax ) {
				for ( $j = ( 0 + $dy ) ; $j < $ymax ; $j = $j + $dy ) {
					ymarkierung3d( $layer, $j, $j, $farbe );
				}
				for ( $j = ( 0 - $dy ) ; $j > $ymin ; $j = $j - $dy ) {
					ymarkierung3d( $layer, $j, $j, $farbe );
				}
			}
			if ( $zmin != $zmax ) {
				for ( $k = ( 0 + $dz ) ; $k < $zmax ; $k = $k + $dz ) {
					zmarkierung3d( $layer, $k, $k, $farbe );
				}
				for ( $k = ( 0 - $dz ) ; $k > $zmin ; $k = $k - $dz ) {
					zmarkierung3d( $layer, $k, $k, $farbe );
				}
			}
		}
		elsif ( $xskala eq "nurstriche" ) {
			if ( $xmin != $xmax ) {
				for ( $i = ( 0 + $dx ) ; $i < $xmax ; $i = $i + $dx ) {
					xstrich3d( $layer, $i, $farbe );
				}
				for ( $i = ( 0 - $dx ) ; $i > $xmin ; $i = $i - $dx ) {
					xstrich3d( $layer, $i, $farbe );
				}
			}
			if ( $ymin != $ymax ) {
				for ( $j = ( 0 + $dy ) ; $j < $ymax ; $j = $j + $dy ) {
					ystrich3d( $layer, $j, $farbe );
				}
				for ( $j = ( 0 - $dy ) ; $j > $ymin ; $j = $j - $dy ) {
					ystrich3d( $layer, $j, $farbe );
				}
			}
			if ( $zmin != $zmax ) {
				for ( $k = ( 0 + $dz ) ; $k < $zmax ; $k = $k + $dz ) {
					zstrich3d( $layer, $k, $farbe );
				}
				for ( $k = ( 0 - $dz ) ; $k > $zmin ; $k = $k - $dz ) {
					zstrich3d( $layer, $k, $farbe );
				}
			}
		}
		elsif ( $xskala eq "nureins" ) {
			if ( $xmin != $xmax ) {
				xmarkierung3d( $layer, 1, 1, $farbe );
			}
			if ( $ymin != $ymax ) {
				ymarkierung3d( $layer, 1, 1, $farbe );
			}
			if ( $zmin != $zmax ) {
				zmarkierung3d( $layer, 1, 1, $farbe );
			}

		}
		elsif ( $xskala eq "strichundeins" ) {
			for ( $i = ( 0 + $dx ) ; $i < $xmax ; $i = $i + $dx ) {
				if ( $i == 1 ) { xmarkierung3d( $layer, 1, 1, $farbe ); }
				else           { xstrich3d( $layer, $i, $farbe ); }
			}
			for ( $i = ( 0 - $dx ) ; $i > $xmin ; $i = $i - $dx ) {
				xstrich3d( $layer, $i, $farbe );
			}
			for ( $j = ( 0 + $dy ) ; $j < $ymax ; $j = $j + $dy ) {
				if ( $j == 1 ) { ymarkierung3d( $layer, 1, 1, $farbe ); }
				else           { ystrich3d( $layer, $j, $farbe ); }
			}
			for ( $j = ( 0 - $dy ) ; $j > $ymin ; $j = $j - $dy ) {
				ystrich3d( $layer, $j, $farbe );
			}
			for ( $k = ( 0 + $dz ) ; $k < $zmax ; $k = $k + $dz ) {
				if ( $k == 1 ) { zmarkierung3d( $layer, 1, 1, $farbe ); }
				else           { zstrich3d( $layer, $k, $farbe ); }
			}
			for ( $k = ( 0 - $dz ) ; $k > $zmin ; $k = $k - $dz ) {
				zstrich3d( $layer, $k, $farbe );
			}

		}
		else { $parameterweiter = $parameterweiter; }

		if ( $xmin != $xmax ) {
			xmarkierung3dohnelinie( $layer, $xmax, $xtext, $farbe );
		}
		if ( $ymin != $ymax ) {
			ymarkierung3dohnelinie( $layer, $ymax, $ytext, $farbe );
		}
		if ( $zmin != $zmax ) {
			zmarkierung3dohnelinie( $layer, $zmax, $ztext, $farbe );
		}
	}
	abstand($layer);

	setknoten($knotenersatz);

}

#################################################################
# Markierungen an der Achse
#################################################################

sub xmarkierung3d {
	my ( $layer, $x, $text, $farbe ) = @_;

	if ( istzahl($x) == 0 ) { set3dpstricks(1); }
	set3dzeichnen(1);

	xmarkierung3dohnelinie( $layer, $x, $text, $farbe );
	xstrich3d( $layer, $x, $farbe );
}

sub xmarkierung3dohnelinie {
	my ( $layer, $x, $text, $farbe ) = @_;
	my ( $y, $z, $ausrichtung );

	$y = $markierungx;
	$z = 0;
	set3dzeichnen(1);
	beschriftung3d( $layer, $farbe, $x, $y, $z, 0, 180, $text );

}

sub ymarkierung3d {
	my ( $layer, $y, $text, $farbe ) = @_;
	my ( $x, $z );

	if ( istzahl($y) == 0 ) { set3dpstricks(1); }
	set3dzeichnen(1);
	ymarkierung3dohnelinie( $layer, $y, $text, $farbe );
	ystrich3d( $layer, $y, $farbe );
}

sub ymarkierung3dohnelinie {
	my ( $layer, $y, $text, $farbe ) = @_;
	my ( $x, $z );
	$x = $markierungy;
	$z = 0;
	set3dzeichnen(1);
	beschriftung3d( $layer, $farbe, $x, $y, $z, 0, 270, $text );
}

sub zmarkierung3d {
	my ( $layer, $z, $text, $farbe ) = @_;

	if ( istzahl($z) == 0 ) { set3dpstricks(1); }
	set3dzeichnen(1);
	zmarkierung3dohnelinie( $layer, $z, $text, $farbe );
	zstrich3d( $layer, $z, $farbe );
}

sub zmarkierung3dohnelinie {
	my ( $layer, $z, $text, $farbe ) = @_;
	my ( $x, $y );

	$x = 0;
	$y = $markierungz;

	set3dzeichnen(1);
	beschriftung3d( $layer, $farbe, $x, $y, $z, 0, 180, $text );
}

sub xstrich3d {
	my ( $layer, $x, $farbe ) = @_;
	my ( $y, $z );
	$y = $strichx;
	$z = 0;
	set3dzeichnen(1);
	linie( $layer, $x, $y, $z, $x, -$y, $z, "solid", $markierungsdicke, $farbe,
		"", "" );
}

sub ystrich3d {
	my ( $layer, $y, $farbe ) = @_;
	my ( $x, $z );
	$x = $strichy;
	$z = 0;
	set3dzeichnen(1);

	linie( $layer, $x, $y, $z, -$x, $y, $z, "solid", $markierungsdicke, $farbe,
		"", "" );
}

sub zstrich3d {
	my ( $layer, $z, $farbe ) = @_;
	my ( $x, $y );
	$x = 0;
	$y = $strichz;
	set3dzeichnen(1);
	linie( $layer, $x, $y, $z, $x, -$y, $z, "solid", $markierungsdicke, $farbe,
		"", "" );
}

sub beschriftung3d {
	my ( $layer, $farbe, $x, $y, $z, $winkel, $ausrichtung, $text ) = @_;

	if ( istzahl($x) == 1 ) { $x = nachkommastellen( $x, 4 ); }
	else                    { set3dpstricks(1); }
	if ( istzahl($y) == 1 ) { $y = nachkommastellen( $y, 4 ); }
	else                    { set3dpstricks(1); }
	if ( istzahl($z) == 1 ) { $z = nachkommastellen( $z, 4 ); }
	else                    { set3dpstricks(1); }
	$text =~ tr/./,/s;

	if ( get3dpstricks() == 1 ) {

		if ( $winkel == 0 ) {

			settexthier("");
			if (   ( istzahl($x) == 1 )
				&& ( istzahl($y) == 1 )
				&& ( istzahl($z) == 1 ) )
			{
				tripel( $x, $y, $z );
			}
			else { tripelohneminmax( $x, $y, $z ); }
			klammer( textfarbe( $text, $farbe ) );
			befehlerzeugen( $layer, "pstThreeDPut", "", "", "", "", "",
				gettexthier() );
			settexthier("");
		}
		else {
			settexthier("");
			if (   ( istzahl($x) == 1 )
				&& ( istzahl($y) == 1 )
				&& ( istzahl($z) == 1 ) )
			{
				tripel( $x, $y, $z );
			}
			else { tripelohneminmax( $x, $y, $z ); }

			klammer("\\uput{0}["
				  . $ausrichtung . "]{"
				  . $winkel
				  . "}(0,0){"
				  . textfarbe( $text, $farbe )
				  . "}" );
			befehlerzeugen( $layer, "pstThreeDPut", "", "", "", "", "",
				gettexthier() );
			settexthier("");
		}

	}
	else {
		beschriftung(
			$layer, $farbe,
			x3d( $x, $y, $z ),
			y3d( $x, $y, $z ),
			$winkel, $ausrichtung, $text
		);
	}

	if ( ( istzahl($x) == 1 ) && ( istzahl($y) == 1 ) && ( istzahl($z) == 1 ) )
	{
		my $laenge = length($text);
		minmax3d(
			$x - ($laenge),
			$y - ($laenge),
			$z - ($laenge),
			$x + ($laenge),
			$y + ($laenge),
			$z + ($laenge)
		);
	}

}
#################################################################
# Geradenfunktion
#################################################################

sub gerade {
	my ( $layer, $x1, $y1, $z1, $x2, $y2, $z2, $r1, $r2, $farbe, $linienart,
		$linienstaerke, $parameter, $pfeilart )
	  = @_;

	if ( ( $z1 ne "" ) && ( $z2 ne "" ) ) {
		kommentar( $layer,
			    "Die Gerade g: (" 
			  . $x1 . "|" 
			  . $y1 . "|" 
			  . $z1 
			  . ") + r(" 
			  . $x2 . "|"
			  . $y2 . "|"
			  . $z2
			  . ")" );
		linie(
			$layer,          $x1 + $r1 * $x2, $y1 + $r1 * $y2,
			$z1 + $r1 * $z2, $x1 + $r2 * $x2, $y1 + $r2 * $y2,
			$z1 + $r2 * $z2, $linienart,      $linienstaerke,
			$farbe,          $parameter,      $pfeilart
		);

	}
	else {
		kommentar( $layer,
			    "Die Gerade g: (" 
			  . $x1 . "|" 
			  . $y1 
			  . ") + r(" 
			  . $x2 . "|" 
			  . $y2
			  . ")" );

		linie(
			$layer,          $x1 + $r1 * $x2,
			$y1 + $r1 * $y2, "",
			$x1 + $r2 * $x2, $y1 + $r2 * $y2,
			"",              $linienart,
			$linienstaerke,  $farbe,
			$parameter,      $pfeilart
		);

	}

}

sub ebene {
	my (
		$layer,      $xauf,       $yauf,          $zauf,
		$xrichtung1, $yrichtung1, $zrichtung1,    $xrichtung2,
		$yrichtung2, $zrichtung2, $r1,            $r2,
		$r3,         $r4,         $farbe,         $fuellart,
		$fuellfarbe, $linienart,  $linienstaerke, $parameter
	) = @_;

	my ( $x1, $y1, $z1, $x2, $y2, $z2, $x3, $y3, $z3, $x4, $y4, $z4 );

	$x1 = $xauf + $r3 * $xrichtung2 + $r1 * $xrichtung1;
	$y1 = $yauf + $r3 * $yrichtung2 + $r1 * $yrichtung1;
	$z1 = $zauf + $r3 * $zrichtung2 + $r1 * $zrichtung1;

	$x2 = $xauf + $r3 * $xrichtung2 + $r2 * $xrichtung1;
	$y2 = $yauf + $r3 * $yrichtung2 + $r2 * $yrichtung1;
	$z2 = $zauf + $r3 * $zrichtung2 + $r2 * $zrichtung1;

	$x3 = $x1 + ( $r4 - $r3 ) * $xrichtung2;
	$y3 = $y1 + ( $r4 - $r3 ) * $yrichtung2;
	$z3 = $z1 + ( $r4 - $r3 ) * $zrichtung2;

	$x4 = $x2 + ( $r4 - $r3 ) * $xrichtung2;
	$y4 = $y2 + ( $r4 - $r3 ) * $yrichtung2;
	$z4 = $z2 + ( $r4 - $r3 ) * $zrichtung2;

	kommentar( $layer,
		    "Die Ebene E: (" 
		  . $xauf . "|" 
		  . $yauf . "|" 
		  . $zauf 
		  . ") + r("
		  . $xrichtung1 . "|"
		  . $yrichtung1 . "|"
		  . $zrichtung1
		  . ") + s("
		  . $xrichtung2 . "|"
		  . $yrichtung2 . "|"
		  . $zrichtung2
		  . ")" );

	viereck( $layer, $x1, $y1, $z1, $x2, $y2, $z2, $x4, $y4, $z4, $x3, $y3, $z3,
		$farbe, $fuellart, $fuellfarbe, $linienart, $linienstaerke,
		$parameter );

	setachsengraph3d( $x1, $y1, $z1, $x1, $y1, $z1 );
	setachsengraph3d( $x2, $y2, $z2, $x2, $y2, $z2 );
	setachsengraph3d( $x3, $y3, $z3, $x3, $y3, $z3 );
	setachsengraph3d( $x4, $y4, $z4, $x4, $y4, $z4 );

}

sub ebenenormal {
	my ( $layer, $x1, $y1, $z1, $xn, $yn, $zn, $r1, $r2, $r3, $r4, $farbe,
		$fuellart, $fuellfarbe, $linienart, $linienstaerke, $parameter )
	  = @_;

	kommentar( $layer, "hier" );

	my ( $x2, $y2, $z2, $x3, $y3, $z3 );

	if ( $zn == 0 ) {
		$z2 = 1;
		$x2 = 0;
		$y2 = 0;
		$z3 = 0;
		$x3 = -$y2;
		$y3 = $x3;
	}
	if ( $zn == 0 ) {
		$z2 = 1;
		$x2 = 0;
		$y2 = 0;
		$z3 = 0;
		$x3 = -$y2;
		$y3 = $x3;
	}
	elsif ( ( $zn == 0 ) && ( $yn == 0 ) ) {
		$x2 = $y2 = $z3 = 0;
		$z2 = 1;
		$x3 = -1;
		$y3 = 2;
	}
	else {
		$x2 = $yn;
		$y2 = -$xn;
		$z2 = 0;
		$x3 = 0;
		$y3 = $zn;
		$z3 = -$yn;
	}

	ebene(
		$layer,      $x1,        $y1,            $z1,
		$x2,         $y2,        $z2,            $x3,
		$y3,         $z3,        $r1,            $r2,
		$r3,         $r4,        $farbe,         $fuellart,
		$fuellfarbe, $linienart, $linienstaerke, $parameter
	);

}

sub ebenekform {
	my ( $layer, $a, $b, $c, $d, $n1, $n2, $farbe, $fuellart, $fuellfarbe,
		$linienart, $linienstaerke, $parameter )
	  = @_;

	my ( $x1, $x2, $x3, $x4, $y1, $y2, $y3, $y4, $z1, $z2, $z3, $z4 );

	if ( ( $a == 0 ) && ( $b != 0 ) && ( $c != 0 ) ) {
		$x1 = 0;
		$y1 = $d / $b;
		$z1 = 0;

		$x2 = 0;
		$y2 = 0;
		$z2 = $d / $c;

		$x3 = $n1;
		$y3 = 0;
		$z3 = $d / $c;

		$x4 = $n1;
		$y4 = $d / $b;
		$z4 = 0;
		viereck(
			$layer,     $x1,            $y1,       $z1,
			$x2,        $y2,            $z2,       $x3,
			$y3,        $z3,            $x4,       $y4,
			$z4,        $farbe,         $fuellart, $fuellfarbe,
			$linienart, $linienstaerke, $parameter
		);

	}
	elsif ( ( $a != 0 ) && ( $b == 0 ) && ( $c != 0 ) ) {
		$x1 = $d / $a;
		$y1 = 0;
		$z1 = 0;
		$x2 = $d / $a;
		$y2 = $n1;
		$z2 = 0;
		$x3 = 0;
		$y3 = $n1;
		$z3 = $d / $c;
		$x4 = 0;
		$y4 = 0;
		$z4 = $d / $c;
		viereck(
			$layer,     $x1,            $y1,       $z1,
			$x2,        $y2,            $z2,       $x3,
			$y3,        $z3,            $x4,       $y4,
			$z4,        $farbe,         $fuellart, $fuellfarbe,
			$linienart, $linienstaerke, $parameter
		);
	}
	elsif ( ( $a != 0 ) && ( $b != 0 ) && ( $c == 0 ) ) {
		$x1 = $d / $a;
		$y1 = 0;
		$z1 = 0;
		$x2 = 0;
		$y2 = $d / $b;
		$z2 = 0;
		$x3 = 0;
		$y3 = $d / $b;
		$z3 = $n1;
		$x4 = $d / $a;
		$y4 = 0;
		$z4 = $n1;
		viereck(
			$layer,     $x1,            $y1,       $z1,
			$x2,        $y2,            $z2,       $x3,
			$y3,        $z3,            $x4,       $y4,
			$z4,        $farbe,         $fuellart, $fuellfarbe,
			$linienart, $linienstaerke, $parameter
		);
	}
	elsif ( ( $a != 0 ) && ( $b == 0 ) && ( $c == 0 ) ) {
		$x1 = $d / $a;
		$y1 = $n1;
		$z1 = 0;

		$x2 = $d / $a;
		$y2 = 0;
		$z2 = 0;

		$x3 = $d / $a;
		$y3 = 0;
		$z3 = $n2;
		$x4 = $d / $a;
		$y4 = $n1;
		$z4 = $n2;
		viereck(
			$layer,     $x1,            $y1,       $z1,
			$x2,        $y2,            $z2,       $x3,
			$y3,        $z3,            $x4,       $y4,
			$z4,        $farbe,         $fuellart, $fuellfarbe,
			$linienart, $linienstaerke, $parameter
		);
	}
	elsif ( ( $a == 0 ) && ( $b != 0 ) && ( $c == 0 ) ) {
		$x1 = $n1;
		$y1 = ( $d / $b );
		$z1 = 0;

		$x2 = 0;
		$y2 = ( $d / $b );
		$z2 = 0;

		$x3 = 0;
		$y3 = ( $d / $b );
		$z3 = $n2;

		$x4 = $n1;
		$y4 = ( $d / $b );
		$z4 = $n2;
		viereck(
			$layer,     $x1,            $y1,       $z1,
			$x2,        $y2,            $z2,       $x3,
			$y3,        $z3,            $x4,       $y4,
			$z4,        $farbe,         $fuellart, $fuellfarbe,
			$linienart, $linienstaerke, $parameter
		);
	}

	elsif ( ( $a == 0 ) && ( $b == 0 ) && ( $c != 0 ) ) {

		$x1 = $n1;
		$y1 = 0;
		$z1 = $d / $c;
		$x2 = 0;
		$y2 = 0;
		$z2 = $d / $c;
		$x3 = 0;
		$y3 = $n2;
		$z3 = $d / $c;
		$x4 = $n1;
		$y4 = $n2;
		$z4 = $d / $c;
		viereck(
			$layer,     $x1,            $y1,       $z1,
			$x2,        $y2,            $z2,       $x3,
			$y3,        $z3,            $x4,       $y4,
			$z4,        $farbe,         $fuellart, $fuellfarbe,
			$linienart, $linienstaerke, $parameter
		);
	}
	else {
		$x1 = $d / $a;
		$y1 = 0;
		$z1 = 0;
		$x2 = 0;
		$y2 = $d / $b;
		$z2 = 0;
		$x3 = 0;
		$y3 = 0;
		$z3 = $d / $c;
		dreieck( $layer, $x1, $y1, $z1, $x2, $y2, $z2, $x3, $y3, $z3, $farbe,
			$fuellart, $fuellfarbe, $linienart, $linienstaerke, $parameter );

	}

}

sub quader {
	my ( $layer, $x, $y, $z, $a, $b, $c, $w1, $w2, $farbe, $fuellart,
		$fuellfarbe, $linienart, $linienstaerke, $parameter )
	  = @_;

	my $liniehinten;

	if   ( $fuellart ne "" ) { $liniehinten = "solid"; }
	else                     { $liniehinten = "dashed"; }

	settexthier("");

	minmax3d( $x,      $y,      $z,      $x,      $y,      $z );
	minmax3d( $x + $a, $y,      $z,      $x + $a, $y,      $z );
	minmax3d( $x + $a, $y + $b, $z,      $x + $a, $y + $b, $z );
	minmax3d( $x + $a, $y + $b, $z + $c, $x + $a, $y + $b, $z + $c );

	if ( ( get3dpstricks() == 1 ) && ( $fuellart ne "" ) ) {
		tripel( $x, $y, $z );
		tripel( 0,  $b, 0 );
		tripel( $a, 0,  0 );
		tripel( 0,  0,  $c );

		befehlfuellungerzeugen(
			$layer,      "pstThreeDBox", $farbe,         $fuellart,
			$fuellfarbe, $linienart,     $linienstaerke, $parameter,
			"",          gettexthier()
		);
	}
	else {

		if ( $fuellart ne "" ) {
			viereck(
				$layer,       $x + $a,        $y,        $z,
				$x + $a,      $y,             $z + $c,   $x,
				$y,           $z + $c,        $x,        $y,
				$z,           $fuellfarbe,    $fuellart, $fuellfarbe,
				$liniehinten, $linienstaerke, $parameter
			);

			viereck(
				$layer,     $x,             $y,        $z,
				$x,         $y + $b,        $z,        $x,
				$y + $b,    $z + $c,        $x,        $y,
				$z + $c,    $fuellfarbe,    $fuellart, $fuellfarbe,
				$linienart, $linienstaerke, $parameter
			);

			viereck(
				$layer,     $x + $a,        $y + $b,   $z,
				$x + $a,    $y,             $z,        $x,
				$y,         $z,             $x,        $y + $b,
				$z,         $fuellfarbe,    $fuellart, $fuellfarbe,
				$linienart, $linienstaerke, $parameter
			);
		}

		settexthier("");
		tripel( $x,      $y + $b, $z );
		tripel( $x,      $y,      $z );
		tripel( $x + $a, $y,      $z );
		liniekopf( $layer, "dashed", $linienstaerke, $farbe, $parameter, "",
			gettexthier() );
		settexthier("");
		tripel( $x, $y, $z );
		tripel( $x, $y, $z + $c );
		liniekopf( $layer, "dashed", $linienstaerke, $farbe, $parameter, "",
			gettexthier() );
		settexthier("");

		viereck(
			$layer,     $x + $a,        $y + $b,   $z,
			$x + $a,    $y + $b,        $z + $c,   $x,
			$y + $b,    $z + $c,        $x,        $y + $b,
			$z,         $farbe,         $fuellart, $fuellfarbe,
			$linienart, $linienstaerke, $parameter
		);

		viereck(
			$layer,     $x + $a,        $y,        $z,
			$x + $a,    $y + $b,        $z,        $x + $a,
			$y + $b,    $z + $c,        $x + $a,   $y,
			$z + $c,    $farbe,         $fuellart, $fuellfarbe,
			$linienart, $linienstaerke, $parameter
		);

		viereck(
			$layer,     $x + $a,        $y + $b,   $z + $c,
			$x + $a,    $y,             $z + $c,   $x,
			$y,         $z + $c,        $x,        $y + $b,
			$z + $c,    $farbe,         $fuellart, $fuellfarbe,
			$linienart, $linienstaerke, $parameter
		);

	}
	settexthier("");

	if ( $punkt == 1 ) {
		if ( $beschriftung == 0 ) {
			punktzeichnen( $layer - 1, $x + $a, $y, $z, 0.05, 225, $farbe,
				"solid", $farbe, $linienart, $linienstaerke, "", "" );
			punktzeichnen( $layer - 1, $x + $a, $y + $b, $z, 0.05, 315, $farbe,
				"solid", $farbe, $linienart, $linienstaerke, "", "" );
			punktzeichnen( $layer - 1, $x, $y + $b, $z, 0.05, 45, $farbe,
				"solid", $farbe, $linienart, $linienstaerke, "", "" );
			punktzeichnen( $layer - 1, $x, $y, $z, 0.05, 135, $farbe, "solid",
				$farbe, $linienart, $linienstaerke, "", "" );
			punktzeichnen( $layer - 1, $x + $a, $y, $z + $c, 0.05, 225, $farbe,
				"solid", $farbe, $linienart, $linienstaerke, "", "" );
			punktzeichnen(
				$layer - 1, $x + $a,    $y + $b,        $z + $c,
				0.05,       315,        $farbe,         "solid",
				$farbe,     $linienart, $linienstaerke, "",
				""
			);
			punktzeichnen( $layer - 1, $x, $y + $b, $z + $c, 0.05, 45, $farbe,
				"solid", $farbe, $linienart, $linienstaerke, "", "" );
			punktzeichnen( $layer - 1, $x, $y, $z + $c, 0.05, 135, $farbe,
				"solid", $farbe, $linienart, $linienstaerke, "", "" );
		}

	}

	if ( $beschriftung == 1 ) {

		punktzeichnen( $layer - 1, $x + $a, $y, $z, 0.05, 225, $farbe, "solid",
			$farbe, $linienart, $linienstaerke, "\$A\$", "" );
		punktzeichnen(
			$layer - 1, $x + $a,    $y + $b,        $z,
			0.05,       315,        $farbe,         "solid",
			$farbe,     $linienart, $linienstaerke, "\$B\$",
			""
		);
		punktzeichnen( $layer - 1, $x, $y + $b, $z, 0.05, 45, $farbe, "solid",
			$farbe, $linienart, $linienstaerke, "\$C\$", "" );
		punktzeichnen( $layer - 1, $x, $y, $z, 0.05, 135, $farbe, "solid",
			$farbe, $linienart, $linienstaerke, "\$D\$", "" );
		punktzeichnen(
			$layer - 1, $x + $a,    $y,             $z + $c,
			0.05,       225,        $farbe,         "solid",
			$farbe,     $linienart, $linienstaerke, "\$E\$",
			""
		);
		punktzeichnen(
			$layer - 1, $x + $a,    $y + $b,        $z + $c,
			0.05,       315,        $farbe,         "solid",
			$farbe,     $linienart, $linienstaerke, "\$F\$",
			""
		);
		punktzeichnen(
			$layer - 1, $x,         $y + $b,        $z + $c,
			0.05,       45,         $farbe,         "solid",
			$farbe,     $linienart, $linienstaerke, "\$G\$",
			""
		);
		punktzeichnen( $layer - 1, $x, $y, $z + $c, 0.05, 135, $farbe, "solid",
			$farbe, $linienart, $linienstaerke, "\$H\$", "" );

	}

}

sub kugel {
	my (
		$layer,     $x,             $y,        $z,
		$r,         $farbe,         $fuellart, $fuellfarbe,
		$linienart, $linienstaerke, $parameter
	) = @_;
	my $i;

	settexthier("");
	set3dpstricks(1);
	tripel( $x, $y, $z );
	klammer($r);
	befehlfuellungerzeugen(
		$layer,      "pstThreeDSphere", $farbe,         $fuellart,
		$fuellfarbe, $linienart,        $linienstaerke, $parameter,
		"",          gettexthier()
	);
	minmax3d( $x - $r, $y,      $z,      $x - $r, $y,      $z );
	minmax3d( $x,      $y - $r, $z,      $x,      $y - $r, $z );
	minmax3d( $x,      $y,      $z - $r, $x,      $y,      $z - $r );
	minmax3d( $x + $r, $y,      $z,      $x + $r, $y,      $z );
	minmax3d( $x,      $y + $r, $z,      $x,      $y + $r, $z );
	minmax3d( $x,      $y,      $z + $r, $x,      $y,      $z + $r );

	settexthier("");

}

sub kreis3d {
	my (
		$layer,     $x,             $y,        $z,
		$u1,        $u2,            $u3,       $startwinkel,
		$endwinkel, $farbe,         $fuellart, $fuellfarbe,
		$linienart, $linienstaerke, $parameter
	) = @_;

	ellipse3d(
		$layer,         $x,        $y,           $z,
		$u1,            $u2,       $u3,          $u1,
		-$u2,           -$u3,      $startwinkel, $endwinkel,
		$farbe,         $fuellart, $fuellfarbe,  $linienart,
		$linienstaerke, $parameter
	);

}

sub ellipse3d {
	my (
		$layer, $x, $y, $z, $u1, $u2, $u3, $v1, $v2, $v3, $startwinkel,
		$endwinkel,
		$farbe,
		$fuellart,
		$fuellfarbe, $linienart, $linienstaerke, $parameter

	) = @_;
	settexthier("");

	my $i = 0;
	for ( $i = $startwinkel ; $i <= $endwinkel ; $i++ ) {
		setachsengraph3d(
			$x + cos( degtorad($i) ) * $u1 + sin( degtorad($i) ) * $v1,
			$y + cos( degtorad($i) ) * $u2 + sin( degtorad($i) ) * $v2,
			$z + cos( degtorad($i) ) * $u3 + sin( degtorad($i) ) * $v3,
			$x + cos( degtorad($i) ) * $u1 + sin( degtorad($i) ) * $v1,
			$y + cos( degtorad($i) ) * $u2 + sin( degtorad($i) ) * $v2,
			$z + cos( degtorad($i) ) * $u3 + sin( degtorad($i) ) * $v3
		);
		grenzen3d(
			$x + cos( degtorad($i) ) * $u1 + sin( degtorad($i) ) * $v1,
			$y + cos( degtorad($i) ) * $u2 + sin( degtorad($i) ) * $v2,
			$z + cos( degtorad($i) ) * $u3 + sin( degtorad($i) ) * $v3
		);
	}

	if ( get3dpstricks() == 1 ) {
		tripel( $x,  $y,  $z );
		tripel( $u1, $u2, $u3 );
		tripel( $v1, $v2, $v3 );

		pstricks( $layer,
			    "\\psset{beginAngle= "
			  . $startwinkel
			  . ",endAngle="
			  . $endwinkel
			  . "}" );
		befehlfuellungerzeugen(
			$layer,         "pstThreeDEllipse",
			$farbe,         $fuellart,
			$fuellfarbe,    $linienart,
			$linienstaerke, $parameter,
			"",             gettexthier()
		);
	}
	else {

		for ( $i = $startwinkel ; $i <= $endwinkel ; $i = $i + 1 ) {
			tripel(
				$x + cos( degtorad($i) ) * $u1 + sin( degtorad($i) ) * $v1,
				$y + cos( degtorad($i) ) * $u2 + sin( degtorad($i) ) * $v2,
				$z + cos( degtorad($i) ) * $u3 + sin( degtorad($i) ) * $v3
			);
		}
		polygon( $layer, $linienart, $linienstaerke, $farbe, $fuellart,
			$fuellfarbe, $parameter . ", plotstyle=curve",
			gettexthier() );

	}
	settexthier("");
}

sub rechteck3d {
	my ( $layer, $x, $y, $z, $r1, $r2, $r3, $r4, $r5, $r6, $farbe, $fuellart,
		$fuellfarbe, $linienart, $linienstaerke, $parameter )
	  = @_;

	settexthier("");

	if ( get3dpstricks() == 1 ) {
		tripel( $x,  $y,  $z );
		tripel( $r1, $r2, $r3 );
		tripel( $r4, $r5, $r6 );
		befehlfuellungerzeugen(
			$layer,         "pstThreeDSquare",
			$farbe,         $fuellart,
			$fuellfarbe,    $linienart,
			$linienstaerke, $parameter,
			"",             gettexthier()
		);
	}
	else {
		tripel( $x,             $y,             $z );
		tripel( $x + $r1,       $y + $r2,       $z + $r3 );
		tripel( $x + $r1 + $r4, $y + $r2 + $r5, $z + $r3 + $r6 );
		tripel( $x + $r4,       $y + $r5,       $z + $r6 );
		tripel( $x,             $y,             $z );
		befehlfuellungerzeugen(
			$layer,      "pspolygon", $farbe,         $fuellart,
			$fuellfarbe, $linienart,  $linienstaerke, $parameter,
			"",          gettexthier()
		);
	}
	settexthier("");

}

sub pyramide {
	my ( $layer, $x, $y, $z, $a, $b, $c, $w1, $w2, $farbe, $fuellart,
		$fuellfarbe, $linienart, $linienstaerke, $parameter )
	  = @_;

	my $n = 0;

	if ( $fuellart eq "" ) {

		linie(
			$layer,         $x - $a, $y + $b,    $z,
			$x - $a,        $y,      $z,         "dashed",
			$linienstaerke, $farbe,  $parameter, ""
		);
		linie(
			$layer, $x - $a, $y, $z,
			$x - ( 0.5 * $a + $w1 ),
			$y + 0.5 * $b + $w2,
			$z + $c, "dashed", $linienstaerke, $farbe, $parameter, ""
		);

		linie( $layer, $x - $a, $y, $z, $x, $y, $z, "dashed", $linienstaerke,
			$farbe, $parameter, "" );

		dreieck(
			$layer,              $x - $a,
			$y + $b,             $z,
			$x,                  $y + $b,
			$z,                  $x - ( 0.5 * $a + $w1 ),
			$y + 0.5 * $b + $w2, $z + $c,
			$farbe,              $fuellart,
			$fuellfarbe,         $linienart,
			$linienstaerke,      $parameter
		);

		dreieck(
			$layer,              $x,
			$y,                  $z,
			$x,                  $y + $b,
			$z,                  $x - ( 0.5 * $a + $w1 ),
			$y + 0.5 * $b + $w2, $z + $c,
			$farbe,              $fuellart,
			$fuellfarbe,         $linienart,
			$linienstaerke,      $parameter
		);
	}
	else {

		rechteck3d( $layer, $x, $y, $z, -$a, 0, 0, 0, $b, 0, $farbe, $fuellart,
			$fuellfarbe, $linienart, $linienstaerke, $parameter );

		dreieck(
			$layer,              $x - $a,
			$y + $b,             $z,
			$x - $a,             $y,
			$z,                  $x - ( 0.5 * $a + $w1 ),
			$y + 0.5 * $b + $w2, $z + $c,
			$farbe,              $fuellart,
			$fuellfarbe,         $linienart,
			$linienstaerke,      $parameter
		);
		dreieck(
			$layer,              $x,
			$y,                  $z,
			$x - $a,             $y,
			$z,                  $x - ( 0.5 * $a + $w1 ),
			$y + 0.5 * $b + $w2, $z + $c,
			$farbe,              $fuellart,
			$fuellfarbe,         $linienart,
			$linienstaerke,      $parameter
		);

		dreieck(
			$layer,              $x - $a,
			$y + $b,             $z,
			$x,                  $y + $b,
			$z,                  $x - ( 0.5 * $a + $w1 ),
			$y + 0.5 * $b + $w2, $z + $c,
			$farbe,              $fuellart,
			$fuellfarbe,         $linienart,
			$linienstaerke,      $parameter
		);

		dreieck(
			$layer,              $x,
			$y,                  $z,
			$x,                  $y + $b,
			$z,                  $x - ( 0.5 * $a + $w1 ),
			$y + 0.5 * $b + $w2, $z + $c,
			$farbe,              $fuellart,
			$fuellfarbe,         $linienart,
			$linienstaerke,      $parameter
		);

	}

}

sub pyramidestumpf {
	my (
		$layer, $x, $y, $z, $a, $b, $c, $hoehe, $w1, $w2, $farbe,
		$fuellart,
		$fuellfarbe, $linienart, $linienstaerke, $parameter

	) = @_;

	my ( $aneu, $bneu, $cneu );

	$cneu = $hoehe;

	$aneu = nachkommastellen( ( $c - $cneu ) / $c * $a, 3 );
	$bneu = nachkommastellen( ( $c - $cneu ) / $c * $b, 3 );

	if ( $cneu == $c ) {
		pyramide(
			$layer, $x, $y, $z, $a, $b, $c, $w1, $w2, $farbe,
			$fuellart,
			$fuellfarbe, $linienart, $linienstaerke, $parameter

		);
	}
	else {

		if ( $fuellart eq "" ) {

			linie( $layer, $x, $y, $z, $x - $a, $y, $z,, "dashed",
				$linienstaerke, $farbe, $parameter, "" );

			linie( $layer, $x - $a, $y + $b, $z, $x - $a, $y, $z,, "dashed",
				$linienstaerke, $farbe, $parameter, "" );

			rechteck3d(
				$layer,                      $x - 0.5 * $a + 0.5 * $aneu,
				$y + 0.5 * $b - 0.5 * $bneu, $z + $cneu,
				-$aneu,                      0,
				0,                           0,
				$bneu,                       0,
				$farbe,                      $fuellart,
				$fuellfarbe,                 $linienart,
				$linienstaerke,              $parameter
			);

			linie(
				$layer,                      $x - $a,
				$y,                          $z,
				$x - 0.5 * $a - 0.5 * $aneu, $y + 0.5 * $b - 0.5 * $bneu,
				$z + $cneu,                  "dashed",
				$linienstaerke,              $farbe,
				$parameter,                  ""
			);

			viereck(
				$layer,                      $x - 0.5 * $a - 0.5 * $aneu,
				$y + 0.5 * $b + 0.5 * $bneu, $z + $cneu,
				$x - 0.5 * $a + 0.5 * $aneu, $y + 0.5 * $b + 0.5 * $bneu,
				$z + $cneu,                  $x,
				$y + $b,                     $z,
				$x - $a,                     $y + $b,
				$z,                          $farbe,
				$fuellart,                   $fuellfarbe,
				$linienart,                  $linienstaerke,
				$parameter
			);

			viereck(
				$layer,                      $x - 0.5 * $a + 0.5 * $aneu,
				$y + 0.5 * $b - 0.5 * $bneu, $z + $cneu,
				$x,                          $y,
				$z,                          $x,
				$y + $b,                     $z,
				$x - 0.5 * $a + 0.5 * $aneu, $y + 0.5 * $b + 0.5 * $bneu,
				$z + $cneu,                  $farbe,
				$fuellart,                   $fuellfarbe,
				$linienart,                  $linienstaerke,
				$parameter
			);

		}
		else {

			rechteck3d( $layer, $x, $y, $z, -$a, 0, 0, 0, $b, 0, $farbe,
				$fuellart, $fuellfarbe, "dashed", $linienstaerke, $parameter );

			rechteck3d(
				$layer,                      $x - 0.5 * $a + 0.5 * $aneu,
				$y + 0.5 * $b - 0.5 * $bneu, $z + $cneu,
				-$aneu,                      0,
				0,                           0,
				$bneu,                       0,
				$farbe,                      $fuellart,
				$fuellfarbe,                 "dashed",
				$linienstaerke,              $parameter
			);

			viereck(
				$layer,                      $x - 0.5 * $a - 0.5 * $aneu,
				$y + 0.5 * $b - 0.5 * $bneu, $z + $cneu,
				$x - 0.5 * $a + 0.5 * $aneu, $y + 0.5 * $b - 0.5 * $bneu,
				$z + $cneu,                  $x,
				$y,                          $z,
				$x - $a,                     $y,
				$z,                          $farbe,
				$fuellart,                   $fuellfarbe,
				$linienart,                  $linienstaerke,
				$parameter
			);

			viereck(
				$layer,                      $x - 0.5 * $a - 0.5 * $aneu,
				$y + 0.5 * $b - 0.5 * $bneu, $z + $cneu,
				$x - 0.5 * $a - 0.5 * $aneu, $y + 0.5 * $b + 0.5 * $bneu,
				$z + $cneu,                  $x - $a,
				$y + $b,                     $z,
				$x - $a,                     $y,
				$z,                          $farbe,
				$fuellart,                   $fuellfarbe,
				$linienart,                  $linienstaerke,
				$parameter
			);

			viereck(
				$layer,                      $x - 0.5 * $a - 0.5 * $aneu,
				$y + 0.5 * $b + 0.5 * $bneu, $z + $cneu,
				$x - 0.5 * $a + 0.5 * $aneu, $y + 0.5 * $b + 0.5 * $bneu,
				$z + $cneu,                  $x,
				$y + $b,                     $z,
				$x - $a,                     $y + $b,
				$z,                          $farbe,
				$fuellart,                   $fuellfarbe,
				$linienart,                  $linienstaerke,
				$parameter
			);

			viereck(
				$layer,                      $x - 0.5 * $a + 0.5 * $aneu,
				$y + 0.5 * $b - 0.5 * $bneu, $z + $cneu,
				$x,                          $y,
				$z,                          $x,
				$y + $b,                     $z,
				$x - 0.5 * $a + 0.5 * $aneu, $y + 0.5 * $b + 0.5 * $bneu,
				$z + $cneu,                  $farbe,
				$fuellart,                   $fuellfarbe,
				$linienart,                  $linienstaerke,
				$parameter
			);

			viereck(
				$layer,
				$x - 0.5 * $a + 0.5 * $aneu, $y + 0.5 * $b - 0.5 * $bneu,
				$z + $cneu,
				$x - 0.5 * $a + 0.5 * $aneu, $y + 0.5 * $b + 0.5 * $bneu,
				$z + $cneu,
				$x - 0.5 * $a - 0.5 * $aneu, $y + 0.5 * $b + 0.5 * $bneu,
				$z + $cneu,
				$x - 0.5 * $a - 0.5 * $aneu,
				$y + 0.5 * $b - 0.5 * $bneu,
				$z + $cneu,

				$farbe, $fuellart, $fuellfarbe, $linienart, $linienstaerke,
				$parameter
			);
		}
	}
}

sub kegel {
	my ( $layer, $x, $y, $z, $r, $h, $weiter, $farbe, $fuellart, $fuellfarbe,
		$linienart, $linienstaerke, $parameter )
	  = @_;

	my ( $xmitte, $ymitte, $zmitte );

	my ( $i, $w1, $w2 );

	$xmitte = $x;
	$ymitte = $y;
	$zmitte = $z + $h;

#ellipse3d( $layer, $x, $y, $z, $r, 0, 0, 0, $r, 0, 0, 360, $farbe, $fuellart, $fuellfarbe, $linienart, $linienstaerke,		$parameter );

	for ( $i = 0 ; $i <= 360 ; $i = $i + $weiter ) {

		$w2 = 90 + $i;
		$w1 = 90 + $i + $weiter;
		if ( $fuellart ne "" ) {

			befehlfuellungerzeugen(
				$layer,      "pscustom", $farbe,         $fuellart,
				$fuellfarbe, $linienart, $linienstaerke, $parameter,
				"",          ""
			);

			pstricks( $layer, "{\\gsave" );

			ellipse3d( $layer, $x, $y, $z, $r, 0, 0, 0, $r, 0, $w2, $w1, $farbe,
				$fuellart, $fuellfarbe, $linienart, $linienstaerke,
				$parameter );

			linie(
				$layer, $xmitte, $ymitte, $zmitte,
				nachkommastellen( $x + cos( degtorad($w2) ) * $r, 4 ),
				nachkommastellen( $y + sin( degtorad($w2) ) * $r, 4 ),
				$z, "", "", "", "", ""
			);

			linie(
				$layer,
				nachkommastellen( $x + cos( degtorad($w1) ) * $r, 4 ),
				nachkommastellen( $y + sin( degtorad($w1) ) * $r, 4 ),
				$z, $xmitte, $ymitte, $zmitte, "", "", "", "", ""
			);

			befehlfuellungerzeugen( $layer, "fill", "", $fuellart, $fuellfarbe,
				"", "", $parameter, "", "" );
			pstricks( $layer, "\\grestore}" );
		}

	}

	ellipse3d( $layer, $x, $y, $z, $r, 0, 0, 0, $r, 0, 0, 360, $farbe,
		$fuellart, $fuellfarbe, $linienart, $linienstaerke, $parameter );

	for ( $i = 0 ; $i <= 360 ; $i = $i + $weiter ) {

		$w2 = 90 + $i;
		linie(
			$layer,
			$xmitte,
			$ymitte,
			$zmitte,
			nachkommastellen( $x + cos( degtorad($w2) ) * $r, 4 ),
			nachkommastellen( $y + sin( degtorad($w2) ) * $r, 4 ),
			$z,
			$linienart,
			$linienstaerke,
			$farbe,
			$parameter,
			""
		);
	}

}

sub kegelstumpf {
	my (
		$layer,         $x,        $y,          $z,
		$r,             $h,        $hoehe,      $weiter,
		$farbe,         $fuellart, $fuellfarbe, $linienart,
		$linienstaerke, $parameter
	) = @_;
	kreiskegelstumpf(
		$layer, $x, $y,
		$z, $r, ( $h - $hoehe ) / $h * $r,
		( $h - $hoehe ), $weiter,     $farbe,
		$fuellart,       $fuellfarbe, $linienart,
		$linienstaerke,  $parameter
	);
}

sub kreiskegelstumpf {
	my ( $layer, $x, $y, $z, $r1, $r2, $h, $weiter, $farbe, $fuellart,
		$fuellfarbe, $linienart, $linienstaerke, $parameter )
	  = @_;

	set3dpstricks(1);
	my ( $xmitte, $ymitte, $zmitte, $i, $w1, $w2 );

	$xmitte = $x;
	$ymitte = $y;
	$zmitte = $z + $h;

	for ( $i = 0 ; $i <= 360 ; $i = $i + $weiter ) {
		$w2 = 0 + $i;
		$w1 = 0 + $i + $weiter;

		if ( $fuellart ne "" ) {
			befehlfuellungerzeugen(
				$layer,      "pscustom", $farbe,         $fuellart,
				$fuellfarbe, $linienart, $linienstaerke, $parameter,
				"",          ""
			);
			pstricks( $layer, "{\\gsave" );
			ellipse3d( $layer, $x, $y, $z, $r1, 0, 0, 0, $r1, 0, $w2, $w1,
				$farbe, $fuellart, $fuellfarbe, $linienart, $linienstaerke,
				$parameter );
			linie(
				$layer,
				nachkommastellen( $x + cos( degtorad($w2) ) * $r1, 4 ),
				nachkommastellen( $y + sin( degtorad($w2) ) * $r1, 4 ),
				$z,
				nachkommastellen( $xmitte + cos( degtorad($w2) ) * $r2, 4 ),
				nachkommastellen( $ymitte + sin( degtorad($w2) ) * $r2, 4 ),
				$zmitte,
				"",
				"",
				"",
				"",
				""
			);
			ellipse3d(
				$layer,         $xmitte,   $ymitte,     $zmitte,
				$r2,            0,         0,           0,
				$r2,            0,         $w2,         $w1,
				$farbe,         $fuellart, $fuellfarbe, $linienart,
				$linienstaerke, $parameter
			);
			linie(
				$layer,
				nachkommastellen( $xmitte + cos( degtorad($w1) ) * $r2, 4 ),
				nachkommastellen( $ymitte + sin( degtorad($w1) ) * $r2, 4 ),
				$zmitte,
				nachkommastellen( $x + cos( degtorad($w1) ) * $r1, 4 ),
				nachkommastellen( $y + sin( degtorad($w1) ) * $r1, 4 ),
				$z,
				"",
				"",
				"",
				"",
				""
			);

			befehlfuellungerzeugen(
				$layer,      "fill", "blue", $fuellart,
				$fuellfarbe, "",     "",     $parameter,
				"",          ""
			);
			pstricks( $layer, "\\grestore}" );
		}

	}
	ellipse3d( $layer, $x, $y, $z, $r1, 0, 0, 0, $r1, 0, 0, 360, $farbe,
		$fuellart, $fuellfarbe, $linienart, $linienstaerke, $parameter );

	for ( $i = 0 ; $i <= 360 ; $i = $i + $weiter ) {
		$w2 = $i;
		linie(
			$layer,
			nachkommastellen( $xmitte + cos( degtorad($w2) ) * $r2, 4 ),
			nachkommastellen( $ymitte + sin( degtorad($w2) ) * $r2, 4 ),
			$zmitte,
			nachkommastellen( $x + cos( degtorad($w2) ) * $r1, 4 ),
			nachkommastellen( $y + sin( degtorad($w2) ) * $r1, 4 ),
			$z,
			$linienart,
			$linienstaerke,
			$farbe,
			$parameter,
			""
		);
	}
	ellipse3d( $layer, $xmitte, $ymitte, $zmitte, $r2, 0, 0, 0, $r2, 0, 0, 360,
		$farbe, $fuellart, $fuellfarbe, $linienart, $linienstaerke,
		$parameter );

}

# Ein Zylinder wird gezeichnet
sub zylinder {

	my ( $layer, $x, $y, $z, $r, $h, $weiter, $farbe, $fuellart, $fuellfarbe,
		$linienart, $linienstaerke, $parameter )
	  = @_;

	kreiskegelstumpf( $layer, $x, $y, $z, $r, $r, $h, $weiter, $farbe,
		$fuellart, $fuellfarbe, $linienart, $linienstaerke, $parameter );

}

1;

