%% $Id: pst-3dplot.tex 414 2022-01-14 20:43:27Z herbert $
%%
%% This is file `pst-3dplot.tex',
%%
%% IMPORTANT NOTICE:
%%
%% Package `pst-3dplot.tex'
%%
%% Herbert Voss <hvoss _at_ tug.org>
%% with contributions of Darrell Lamm <darrell.lamm _at_ gtri.gatech.edu<
%%
%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License Distributed from CTAN archives
%% in directory macros/latex/base/lppl.txt.
%%
%% DESCRIPTION:
%%   `pst-3dplot' is a PSTricks package to draw 3d curves,
%%       data and different graphical objects
%%
\csname PSTThreeDplotLoaded\endcsname
\let\PSTThreeDplotLoaded\endinput
% Requires PSTricks, pst-node, pst-plot, multido packages
\ifx\PSTricksLoaded\endinput\else   \input pstricks.tex\fi
\ifx\PSTnodesLoaded\endinput\else   \input pst-3d.tex\fi
\ifx\PSTplotLoaded\endinput\else    \input pst-plot.tex\fi
\ifx\PSTnodeLoaded\endinput\else    \input pst-node.tex\fi
\ifx\PSTMultidoLoaded\endinput\else \input multido.tex\fi
\ifx\PSTXKeyLoaded\endinput\else    \input pst-xkey \fi
%
\def\fileversion{2.07a}
\let\IIIDplotfileversion\fileversion
\def\filedate{2022/01/14}
\let\IIIDplotfiledate\filedate
\message{`PST-3dplot' v\fileversion, \filedate\space (HV,DL)}
%
\edef\PstAtCode{\the\catcode`\@} \catcode`\@=11\relax

\pst@addfams{pst-3dplot}
\SpecialCoor

\newdimen\pst@dimf
%
\define@boolkey[psset]{pst-3dplot}[Pst@]{Debug}[true]{}% 
\define@boolkey[psset]{pst-3dplot}[Pst@]{alternative}[true]{}% for switches 
\define@boolkey[psset]{pst-3dplot}[Pst@]{drawing}[true]{}% draw the coordinates?
\define@boolkey[psset]{pst-3dplot}[Pst@]{drawCoor}[true]{}% draw the coordinates of a dot?
\define@boolkey[psset]{pst-3dplot}[Pst@]{hiddenLine}[true]{}% emulate hidden line surface?
\define@boolkey[psset]{pst-3dplot}[Pst@]{SphericalCoor}[true]{}% (r,phi,theta)
\define@boolkey[psset]{pst-3dplot}[Pst@]{IIIDshowgrid}[true]{}% draw the coordinates of a dot?
\define@boolkey[psset]{pst-3dplot}[Pst@]{CoorCheck}[true]{}% check the coordinates
\define@boolkey[psset]{pst-3dplot}[Pst@]{CylindricalCoor}[true]{}% (r,phi,z)
\define@boolkey[psset]{pst-3dplot}[Pst@]{leftHanded}[true]{}% left-Handed coor
\define@boolkey[psset]{pst-3dplot}[Pst@]{eulerRotation}[true]{}% Use Euler rotation definition
\define@key[psset]{pst-3dplot}{coorType}[0]{%
    \pst@getint{#1}\psk@ThreeDplot@coorType
    \ifcase\psk@ThreeDplot@coorType
        % 0 is the default
      \or
%        \def\psk@ThreeDplot@Beta{0}
      \or  %2 
        \def\psk@ThreeDplot@Alpha{135}
%        \def\psk@ThreeDplot@Beta{0}
      \or %3
        \def\psk@ThreeDplot@Alpha{45}
      \or %4
%        \def\psk@ThreeDplot@Alpha{135}
      \or %5
      \or %6
        \def\psk@ThreeDplot@Alpha{26.565}
      \or %7
        \def\psk@ThreeDplot@Alpha{26.565}
      \else
    \fi}
% 0 default
% 1 z y are orthogonal and angle x|y is Alpha, Beta has no meaning 
% 1 z y are orthogonal and angle Alpha is always 135, x-axis shortened by 1/sqrt(2), Beta has no meaning 
\define@key[psset]{pst-3dplot}{SphericalCoorType}[0]{\pst@getint{#1}{\psk@ThreeDplot@SphericalCoorType}} 
\psset[pst-3dplot]{drawing,drawCoor,hiddenLine=false,SphericalCoor=false,SphericalCoorType=0,
    leftHanded=false,eulerRotation=false,coorType=0}
%
% ------- the global definitions for the pspicture frame ------
%
\define@key[psset]{pst-3dplot}{xMin}[-1]{\def\psk@ThreeDplot@xMin{#1}}
\define@key[psset]{pst-3dplot}{xMax}[4]{\def\psk@ThreeDplot@xMax{#1}}
\define@key[psset]{pst-3dplot}{yMin}[-1]{\def\psk@ThreeDplot@yMin{#1}}
\define@key[psset]{pst-3dplot}{yMax}[4]{\def\psk@ThreeDplot@yMax{#1}}
\define@key[psset]{pst-3dplot}{zMin}[-1]{\def\psk@ThreeDplot@zMin{#1}}
\define@key[psset]{pst-3dplot}{zMax}[4]{\def\psk@ThreeDplot@zMax{#1}}
\define@key[psset]{pst-3dplot}{xThreeDunit}[1.0]{\def\psk@ThreeDplot@xThreeDunit{#1}}
%\define@key[psset]{pst-3dplot}{xThreeDunit}{\pst@checknum{#1}\psk@ThreeDplot@xThreeDunit }
\define@key[psset]{pst-3dplot}{yThreeDunit}[1.0]{\def\psk@ThreeDplot@yThreeDunit{#1}}
\define@key[psset]{pst-3dplot}{zThreeDunit}[1.0]{\def\psk@ThreeDplot@zThreeDunit{#1}}
\define@key[psset]{pst-3dplot}{xRotVec}[0]{\pst@checknum{#1}\psk@ThreeDplot@xRotVec } % Rotation vector x
\define@key[psset]{pst-3dplot}{yRotVec}[0]{\pst@checknum{#1}\psk@ThreeDplot@yRotVec } % Rotation vector y
\define@key[psset]{pst-3dplot}{zRotVec}[0]{\pst@checknum{#1}\psk@ThreeDplot@zRotVec } % Rotation vector z
\define@key[psset]{pst-3dplot}{deltax}[1.0]{\def\psk@ThreeDplot@deltax{#1}}
%\define@key[psset]{pst-3dplot}{deltax}{\pst@checknum{#1}\psk@ThreeDplot@deltax}
\define@key[psset]{pst-3dplot}{deltay}[1.0]{\def\psk@ThreeDplot@deltay{#1}}
\define@key[psset]{pst-3dplot}{deltaz}[1.0]{\def\psk@ThreeDplot@deltaz{#1}}
\define@key[psset]{pst-3dplot}{Deltax}[1.0]{\def\psk@ThreeDplot@Deltax{#1}}
\define@key[psset]{pst-3dplot}{Deltay}[1.0]{\def\psk@ThreeDplot@Deltay{#1}}
\define@key[psset]{pst-3dplot}{Deltaz}[1.0]{\def\psk@ThreeDplot@Deltaz{#1}}
%
% -------------- the angles and the plotpoints -------------
%
\define@key[psset]{pst-3dplot}{Alpha}[45]{\pst@getangle{#1}\psk@ThreeDplot@Alpha } %	Horizontal turn
\define@key[psset]{pst-3dplot}{Beta}[30]{\pst@getangle{#1}\psk@ThreeDplot@Beta }%	Vertical turn
\define@key[psset]{pst-3dplot}{RotX}[0]{\pst@getangle{#1}\psk@ThreeD@RotX }% x rotation 
\define@key[psset]{pst-3dplot}{RotY}[0]{\pst@getangle{#1}\psk@ThreeD@RotY }% y rotation
\define@key[psset]{pst-3dplot}{RotZ}[0]{\pst@getangle{#1}\psk@ThreeD@RotZ }% z rotation
\define@key[psset]{pst-3dplot}{RotAngle}[0]{\pst@getangle{#1}\psk@ThreeD@RotAngle }% General rotation angle
\define@key[psset]{pst-3dplot}{RotSequence}[xyz]{\def\psk@ThreeD@RotS{#1 }}%
% Set or Concat
\define@key[psset]{pst-3dplot}{RotSet}[set]{\def\psk@ThreeD@RotSet{#1 }}%
\define@key[psset]{pst-3dplot}{PlaneSequence}[{}]{\def\psk@ThreeD@PlaneSequence{#1 }}%
\define@key[psset]{pst-3dplot}{zCoor}[0]{\pst@checknum{#1}\psk@ThreeDplot@zCoor } 
\psset[pst-3dplot]{zCoor=0}
%
\def\drawStyle@xLines{xLines}% 0
\def\drawStyle@yLines{yLines}% 1
\def\drawStyle@xyLines{xyLines}% 2
\def\drawStyle@yxLines{yxLines}% 3
\define@key[psset]{pst-3dplot}{drawStyle}[xLines]{%			how to draw 3D functions
  \def\pst@tempA{#1}%
  \ifx\pst@tempA\drawStyle@xLines\let\psk@ThreeDplot@drawStyle\z@\else%
    \ifx\pst@tempA\drawStyle@yLines\let\psk@ThreeDplot@drawStyle\@ne\else%
      \ifx\pst@tempA\drawStyle@xyLines\let\psk@ThreeDplot@drawStyle\tw@\else%
         \ifx\pst@tempA\drawStyle@yxLines\let\psk@ThreeDplot@drawStyle\thr@@\else%
            \@pstrickserr{Bad draw style: `\pst@tempa'}\@ehpa%
  \fi\fi\fi\fi%
%  \typeout{drawStyle: \the\psk@ThreeDplot@drawStyle}
  }
\psset[pst-3dplot]{drawStyle=xLines}
%
\define@key[psset]{pst-3dplot}{xPlotpoints}[25]{\def\psk@ThreeDplot@xPlotpoints{#1}}
\define@key[psset]{pst-3dplot}{yPlotpoints}[25]{\def\psk@ThreeDplot@yPlotpoints{#1}}
\define@key[psset]{pst-3dplot}{beginAngle}[0]{\def\psk@ThreeDplot@beginAngle{#1}}% for ellipse/circle arc
\define@key[psset]{pst-3dplot}{endAngle}[360]{\def\psk@ThreeDplot@endAngle{#1}}%	for ellipse/circle arc
%\define@key[psset]{pst-3dplot}{linejoin}{\def\psk@ThreeDplot@linejoin{#1 }}%	how lines come together 0,1,2
\define@key[psset]{pst-3dplot}{plane}[xy]{\def\psk@ThreeDplot@plane{#1}}%		xy,xz,yz
%		must be expanded 
\define@key[psset]{pst-3dplot}{pOrigin}[c]{\def\psk@ThreeDplot@pOrigin{#1}}%	combination of (lr)(tBb)
\define@key[psset]{pst-3dplot}{IIIDdAlpha}[0]{\def\psk@IIIDdAlpha{#1 }}
\def\ThreeDplot@planeXY{xy}
\def\ThreeDplot@planeXZ{xz}
\def\ThreeDplot@planeYZ{yz}
%
% -------------- the length and node definitions -------------
%
\iffalse
\define@key[psset]{pst-3dplot}{XO}[0]{\def\psk@ThreeDplot@XO{#1}}%	the X-offset
\define@key[psset]{pst-3dplot}{YO}[0]{\def\psk@ThreeDplot@YO{#1}}%	the y-offset
\define@key[psset]{pst-3dplot}{posStart}[0]{\def\psk@ThreeDplot@posStart{#1}}% where the arrows start
\define@key[psset]{pst-3dplot}{length}[2]{\def\psk@ThreeDplot@length{#1}}% the length of the before|outlines
\define@key[psset]{pst-3dplot}{arrowOffset}[0]{\def\psk@ThreeDplot@arrowOffset{#1}}%offset for \arrowLine
\fi

\define@key[psset]{pst-3dplot}{visibleLineStyle}[solid]{\def\psk@ThreeDplot@visibleLineStyle{#1}}% 
\define@key[psset]{pst-3dplot}{invisibleLineStyle}[dashed]{\def\psk@ThreeDplot@invisibleLineStyle{#1}}
%
\define@boolkey[psset]{pst-3dplot}[Pst@]{IIIDticks}[true]{}
\define@boolkey[psset]{pst-3dplot}[Pst@]{IIIDlabels}[true]{}
\define@key[psset]{pst-3dplot}{Dz}[1]{\def\psk@Dz{#1}}
\define@key[psset]{pst-3dplot}{IIIDxTicksPlane}[xy]{\def\psk@IIIDxTicksPlane{#1}}
\define@key[psset]{pst-3dplot}{IIIDyTicksPlane}[yz]{\def\psk@IIIDyTicksPlane{#1}}
\define@key[psset]{pst-3dplot}{IIIDzTicksPlane}[yz]{\def\psk@IIIDzTicksPlane{#1}}
\define@key[psset]{pst-3dplot}{IIIDticksize}[0.1]{\def\psk@IIIDticksize{#1}}
\define@key[psset]{pst-3dplot}{IIIDxticksep}[-0.2]{\def\psk@IIIDxticksep{#1}}
\define@key[psset]{pst-3dplot}{IIIDyticksep}[-0.2]{\def\psk@IIIDyticksep{#1}}
\define@key[psset]{pst-3dplot}{IIIDzticksep}[0.2]{\def\psk@IIIDzticksep{#1}}
\define@key[psset]{pst-3dplot}{nameX}[$x$]{\def\psk@ThreeDplot@nameX{#1}}%	start of the object arrow
\define@key[psset]{pst-3dplot}{spotX}[180]{\def\psk@ThreeDplot@spotX{#1}}%	where to draw the label
\define@key[psset]{pst-3dplot}{nameY}[$y$]{\def\psk@ThreeDplot@nameY{#1}}
\define@key[psset]{pst-3dplot}{spotY}[0]{\def\psk@ThreeDplot@spotY{#1}}
\define@key[psset]{pst-3dplot}{nameZ}[$z$]{\def\psk@ThreeDplot@nameZ{#1}}
\define@key[psset]{pst-3dplot}{spotZ}[90]{\def\psk@ThreeDplot@spotZ{#1}}
%
% ###   begin Torsten Suhling
\define@key[psset]{pst-3dplot}{planecorr}[none]{\def\psk@ThreeDplot@planecorr{#1}}%	make plane tags readable 
\def\ThreeDplot@planecorrNone{none}	% default
\def\ThreeDplot@planecorrNormal{normal}	% make planes readable 
\def\ThreeDplot@planecorrXYrot{xyrot}	% and put tag for xy-plane 
% 					% parallel to the y-axis 
% ###   end Torsten Suhling
%
\def\psds@none{\pst@gdot{}}% define none for the dotstyle
%
\newpsstyle{showCoorStyle}{linestyle=dashed,linecolor=black,linewidth=0.5pt}
\newpsstyle{hiddenStyle}{fillstyle=solid,fillcolor=white}
\newcount\pst@cntx \newcount\pst@cnty \newcount\pst@cntz
\newdimen\pst@dimx \newdimen\pst@dimy \newdimen\pst@dimz
%
\define@key[psset]{pst-3dplot}{planeGrid}[xy]{\def\psk@planeGrid{#1}}
\define@key[psset]{pst-3dplot}{planeGridOffset}[0]{\def\psk@planeGridOffset{#1}}
%
\define@boolkey[psset]{pst-3dplot}[PstThreeDplot@]{showInside}[true]{}
\define@key[psset]{pst-3dplot}{SegmentColor}{\pst@getcolor{#1}\psk@ThreeDplot@SegmentColor} 
\define@key[psset]{pst-3dplot}{increment}[10]{\pst@checknum{#1}\psk@ThreeDplot@increment}
\define@key[psset]{pst-3dplot}{Hincrement}[0.5]{\pst@checknum{#1}\psk@ThreeDplot@Hincrement}
\define@key[psset]{pst-3dplot}{xyzLight}[1 1 2]{\def\psk@ThreeDplot@xyzLight{#1 }} 
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                              %
%                        B A S I C S	                       %
%                                                              %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
\pstheader{pst-3dplot.pro}
% ---- only shortcuts -------
\def\pst@3ddict{tx@3DPlotDict begin }
\def\tx@3DPlotDict{tx@3DPlotDict begin }
\def\tx@saveCoor{\pst@3ddict saveCoor end }
\def\tx@X{\pst@3ddict x end }
\def\tx@Y{\pst@3ddict y end }
\def\tx@Z{\pst@3ddict z end }
\def\tx@xIID{\pst@3ddict x2D end }
\def\tx@yIID{\pst@3ddict y2D end }
\def\tx@ConvertToIID{\pst@3ddict ConvertTo2D end }
\def\tx@SphericalCoor{\pst@3ddict SphericalCoor end }
\def\tx@ConvertToCartesian{\pst@3ddict ConvertToCartesian end }
\def\tx@ConvCylToCartesian{\pst@3ddict ConvCylToCartesian end }
%
%
\def\setIIIDplotDefaults{%
  \psset[pstricks]{linejoin=1}%
  \psset[pst-3dplot]{
  Debug=false,CoorCheck=true,alternative=false,
  drawing=true,hiddenLine=false,eulerRotation=false,
  xMin=-1,xMax=4,yMin=-1,yMax=4,zMin=-1,zMax=4,
  xThreeDunit=1,yThreeDunit=1.0,zThreeDunit=1.0,Alpha=45,Beta=30,
  deltax=1,deltay=1.0,deltaz=1.0,Deltax=1.0,Deltay=1.0,Deltaz=1.0,
  RotX=0,RotY=0,RotZ=0,RotSequence=xyz,RotSet=set,
  xRotVec=1,yRotVec=0,zRotVec=0,RotAngle=0,
  PlaneSequence={},
  drawStyle=xLines,xPlotpoints=25,yPlotpoints=25,beginAngle=0,endAngle=360,
%  XO=0,YO=0,posStart=0,length=2,arrowOffset=0,
  visibleLineStyle=solid,invisibleLineStyle=dashed,nameX=$x$,spotX=180,
  nameY=$y$,spotY=0,nameZ=$z$,spotZ=90,plane=xy,pOrigin=c,
  drawCoor=false,SphericalCoor=false, CylindricalCoor=false,
  Dz=1,IIIDticks=false,IIIDlabels=false,IIIDxTicksPlane=xy,IIIDyTicksPlane=yz,IIIDzTicksPlane=yz,
  IIIDticksize=0.1,IIIDxticksep=-0.4,IIIDyticksep=-0.2,IIIDzticksep=0.2,
  planecorr=none,
  planeGrid=xy,planeGridOffset=0,%subticks=10,
  leftHanded=false,coorType=0,IIIDdAlpha=0,
  xyzLight=1 1 2,showInside=true,SegmentColor={[cmyk]{0.2,0.6,1,0}},
  increment=10,Hincrement=0.5,
  IIIDshowgrid,
  }%
  \def\pst@linetype{2}%  to prevent an unknown linetyp with dash
}
\setIIIDplotDefaults
%
\def\IIIDplot@variables{
  /RotX \psk@ThreeD@RotX\space def
  /RotY \psk@ThreeD@RotY\space def
  /RotZ \psk@ThreeD@RotZ\space def
  /RotAngle \psk@ThreeD@RotAngle\space def
  /xRotVec \psk@ThreeDplot@xRotVec\space def
  /yRotVec \psk@ThreeDplot@yRotVec\space def
  /zRotVec \psk@ThreeDplot@zRotVec\space def
  /dxUnit \psk@ThreeDplot@xThreeDunit\space def
  /dyUnit \psk@ThreeDplot@yThreeDunit\space def
  /dzUnit \psk@ThreeDplot@zThreeDunit\space def
  /RotSequence (\psk@ThreeD@RotS) def
  /RotSet (\psk@ThreeD@RotSet) def
  /Alpha \psk@ThreeDplot@Alpha\space def
  /Beta \psk@ThreeDplot@Beta\space def
  /Sin1 Beta sin def
  /Sin2 Alpha sin def
  /Cos1 Beta cos def
  /Cos2 Alpha cos def
  /Cos1Sin2 Cos1 Sin2 mul def
  /Sin1Sin2 Sin1 Sin2 mul def
  /Cos1Cos2 Cos1 Cos2 mul def
  /Sin1Cos2 Sin1 Cos2 mul def
  /showgrid \ifPst@IIIDshowgrid true \else false \fi def
  currentdict tx@3DPlotDict ne dup 
  {tx@3DPlotDict begin} if % Begin the correct dict if necessary
   /eulerRotation \ifPst@eulerRotation true \else false \fi def
   RotSet (set ) eq currentdict /MnewTOold known not or
   {/PROCMXYZ /SetMxyz def /PROCMQUATERNION /SetMQuaternion def}
   {RotSet (concat ) eq 
    {/PROCMXYZ /ConcatMxyz def /PROCMQUATERNION /ConcatMQuaternion def}
    {/PROCMXYZ ()          def /PROCMQUATERNION ()                 def} ifelse 
   } ifelse
    RotSequence (quaternion ) ne {PROCMXYZ} {PROCMQUATERNION} ifelse cvx exec
   /RotSet (keep ) def
 {end} if % End the correct dict if necessary
  /leftHanded \ifPst@leftHanded true \else false \fi def
  /coorType \psk@ThreeDplot@coorType\space def
  /SphericalCoorType \psk@ThreeDplot@SphericalCoorType\space def
  \psk@ThreeDplot@xyzLight\space 
  /zLight ED /yLight ED /xLight ED 
}%
%
% (#1) -> #1 #2 #3
\def\getThreeDCoor#1#2{\pst@getThreeDcoor(#1)\let#2\pst@coorIIID}
\def\pst@getThreeDcoor(#1,#2,#3){%
  \edef\pst@coorIIID{#1\space #2\space #3\space}%
}
\def\pst@addThreeDVec(#1)(#2)#3#4#5{% (#1)+(#2)=(#3,#4,#5)
  \pst@calcThreeDVec(#1)(#2)%
  \let#3\pst@getValueX%
  \let#4\pst@getValueY%
  \let#5\pst@getValueZ%
}
\def\pst@addThreeDVecPS(#1,#2,#3)(#4,#5,#6)#7#8#9{% (#1)+(#2)=(#7,#8,#9)
  \def#7{ #1 #4 add }%
  \def#8{ #2 #5 add }%
  \def#9{ #3 #6 add }%
}
\def\pst@subThreeDVec(#1)(#2,#3,#4)#5#6#7{% (#1)-(#2,#3,#4)=(#5,#6,#7)
  \pst@calcThreeDVec(#1)(-#2,-#3,-#4)%
  \let#5\pst@getValueX%
  \let#6\pst@getValueY%
  \let#7\pst@getValueZ%
}
\def\pst@subThreeDVecPS(#1,#2,#3)(#4,#5,#6)#7#8#9{% (#1)-(#2)=(#7,#8,#9)
  \def#7{ #1 #4 sub }%
  \def#8{ #2 #5 sub }%
  \def#9{ #3 #6 sub }%
}
%
\def\pst@calcThreeDVec(#1,#2,#3)(#4,#5,#6){{% #1+#4; #2+#5; #3+#6
  \pst@dima=#1 pt%
  \pst@dimb=#2 pt%
  \pst@dimc=#3 pt%
  \pst@dimf=#4 pt%
  \pst@dimg=#5 pt%
  \pst@dimh=#6 pt%
  \advance\pst@dima by \pst@dimf%
  \advance\pst@dimb by \pst@dimg%
  \advance\pst@dimc by \pst@dimh%
  \xdef\pst@getValueX{\pst@number\pst@dima}%
  \xdef\pst@getValueY{\pst@number\pst@dimb}%
  \xdef\pst@getValueZ{\pst@number\pst@dimc}%
}}%
%
% the ThreeD coordinate system
%
\def\psxyzlabel#1{\bgroup\footnotesize\textsf{#1}\egroup}
%
\define@key[psset]{pst-3dplot}{IIIDOffset}%[{(0,0,0)}]
					{\def\psk@ThreeDplot@Offset{#1}} 
\define@key[psset]{pst-3dplot}{zlabelFactor}[\relax]{\def\psk@zlabelFactor{#1}}
\psset[pst-3dplot]{IIIDOffset={(0,0,0)},zlabelFactor={}}% for coor axes
%
\def\pst@getIIIDValues(#1,#2,#3)#4#5#6\@nil{\def#4{#1}\def#5{#2}\def#6{#3}}
%
\def\pstThreeDCoor{\def\pst@par{}\pst@object{pstThreeDCoor}}
\def\pstThreeDCoor@i{%
  \pst@killglue
  \begingroup
  \addbefore@par{linewidth=0.5pt,linecolor=red,arrows=->,dotstyle=|}%
  \use@par
  \expandafter\pst@getIIIDValues\psk@ThreeDplot@Offset{\pst@OffsetX}{\pst@OffsetY}{\pst@OffsetZ}\@nil
  \pstThreeDNode(\psk@ThreeDplot@xMin,\pst@OffsetY,\pst@OffsetZ){xMin}%
  \psset[pst-3dplot]{RotSet=keep}% Keep the current rotation matrix
  \pstThreeDNode(\psk@ThreeDplot@xMax,\pst@OffsetY,\pst@OffsetZ){xMax}%
  \pstThreeDNode(\pst@OffsetX,\psk@ThreeDplot@yMin,\pst@OffsetZ){yMin}%
  \pstThreeDNode(\pst@OffsetX,\psk@ThreeDplot@yMax,\pst@OffsetZ){yMax}%
  \pstThreeDNode(\pst@OffsetX,\pst@OffsetY,\psk@ThreeDplot@zMin){zMin}%
  \pstThreeDNode(\pst@OffsetX,\pst@OffsetY,\psk@ThreeDplot@zMax){zMax}%
  \ifPst@drawing% ThreeDplot axes
    \psline(xMin)(xMax)%
    \psline(yMin)(yMax)%
    \psline(zMin)(zMax)%
    \uput[\psk@ThreeDplot@spotX](xMax){\psk@ThreeDplot@nameX}%
    \uput[\psk@ThreeDplot@spotY](yMax){\psk@ThreeDplot@nameY}%
    \uput[\psk@ThreeDplot@spotZ](zMax){\psk@ThreeDplot@nameZ}%
    \ifPst@IIIDticks
%------------ x ticks and labels --------------------------
      \ifdim\psk@ThreeDplot@xMax pt>0pt % only for positive parts of the axes
        \ifdim\psk@ThreeDplot@xMin pt>\z@
          \pstFPadd\pst@tempC\psk@ThreeDplot@xMax{-\psk@ThreeDplot@xMin}
        \else
          \let\pst@tempC\psk@ThreeDplot@xMax
        \fi
        \pstFPadd\pst@tempC\pst@tempC{-\pst@OffsetX}
        \pstFPDiv\pst@tempB\pst@tempC{\psk@ThreeDplot@deltax}
        \pst@cntx=\pst@tempB \advance\pst@cntx by -1
        \pstFPdiv\pst@tempB\psk@IIIDticksize{\psk@ThreeDplot@yThreeDunit}
        \pstFPadd\pst@tempA{-\pst@tempB}{\pst@OffsetY}
        \pstFPadd\pst@tempB{\pst@tempB}{\pst@OffsetY}
        \pstFPadd\pst@tempC\pst@OffsetX{\psk@ThreeDplot@deltax}
        \pstFPadd\pst@tempD\pst@OffsetX{\psk@Dx}
        \pst@dimm=\pst@tempD pt\edef\pst@tempD{\strip@pt\pst@dimm}% strip the 00... from fp
        \pstFPadd\pst@tempE{\psk@IIIDxticksep}{\pst@OffsetY}
        \pstFPdiv\pst@tempE\pst@tempE\psk@ThreeDplot@yThreeDunit
        \edef\@xyDecimals{\psk@xDecimals}%
        \multido{\nA=\pst@tempD+\psk@Dx,
                 \rB=\pst@tempC+\psk@ThreeDplot@deltax}
                {\the\pst@cntx}{%
          \ifx\psk@IIIDxTicksPlane\ThreeDplot@planeXY
            \pstThreeDLine[arrows=-](\rB,\pst@tempA,\pst@OffsetZ)(\rB,\pst@tempB,\pst@OffsetZ)%
          \else
            \ifx\psk@IIIDxTicksPlane\ThreeDplot@planeXZ
              \pstThreeDLine[arrows=-](\rB,\pst@OffsetZ,\pst@tempA)(\rB,\pst@OffsetZ,\pst@tempB)%
          \fi\fi
          \ifPst@IIIDlabels%
            \pstPlanePut[plane=\psk@IIIDxTicksPlane](\rB,\pst@tempE,\pst@OffsetZ){%
              \psxyzlabel{\expandafter\@LabelComma\nA..\@nil\psk@xlabelFactor}}%
%%              \psxyzlabel{\nA\psk@xlabelFactor}}%
          \fi%
        }% end of multido
      \fi% 
      \ifdim\psk@ThreeDplot@xMin pt<\z@\relax % only for negative parts of the axes
        \pstFPadd\pst@tempB\psk@ThreeDplot@xMin{-\pst@OffsetX}
        \pstFPDiv\pst@tempB\pst@tempB{\psk@ThreeDplot@deltax}%
        \pst@cntx=-\pst@int{\pst@tempB}%
        \pstFPdiv{\pst@tempB}{\psk@IIIDticksize}{\psk@ThreeDplot@yThreeDunit}
        \pstFPadd{\pst@tempA}{-\pst@tempB}{\pst@OffsetY}
        \pstFPadd{\pst@tempB}{\pst@tempB}{\pst@OffsetY}
        \pstFPadd{\pst@tempC}{\pst@OffsetX}{-\psk@ThreeDplot@deltax}
        \pstFPadd{\pst@tempD}{\pst@OffsetX}{-\psk@Dx}
        \pst@dimm=\pst@tempD pt\edef\pst@tempD{\strip@pt\pst@dimm}% strip the 00... from fp
        \pstFPadd\pst@tempE{\psk@IIIDxticksep}{\pst@OffsetY}
        \pstFPdiv\pst@tempE\pst@tempE\psk@ThreeDplot@yThreeDunit
        \edef\@xyDecimals{\psk@xDecimals}%
        \multido{\nA=\pst@tempD+-\psk@Dx,
                 \rB=\pst@tempC+-\psk@ThreeDplot@deltax}
                {\the\pst@cntx}{%
          \ifx\psk@IIIDxTicksPlane\ThreeDplot@planeXY
            \pstThreeDLine[arrows=-](\rB,\pst@tempA,\pst@OffsetZ)(\rB,\pst@tempB,\pst@OffsetZ)%
          \else
            \ifx\psk@IIIDxTicksPlane\ThreeDplot@planeXZ
              \pstThreeDLine[arrows=-](\rB,\pst@OffsetY,\pst@tempA)(\rB,\pst@OffsetZ,\pst@tempB)%
          \fi\fi
          \ifPst@IIIDlabels%
            \pstPlanePut[plane=\psk@IIIDxTicksPlane](\rB,\pst@tempE,\pst@OffsetZ){%
              \psxyzlabel{\expandafter\@LabelComma\nA..\@nil\psk@xlabelFactor}}%
%%              \psxyzlabel{\nA\psk@xlabelFactor}}%
          \fi%
        }% end of multido and the x ticks and labels
      \fi
%------------ y ticks and labels --------------------------
      \ifdim\psk@ThreeDplot@yMax pt>0pt % only for positive parts of the axes
        \ifdim\psk@ThreeDplot@yMin pt>\z@
          \pstFPadd\pst@tempC\psk@ThreeDplot@yMax{-\psk@ThreeDplot@yMin}
        \else\let\pst@tempC\psk@ThreeDplot@yMax\fi
        \pstFPadd\pst@tempC\pst@tempC{-\pst@OffsetY}
        \pstFPDiv\pst@tempB\pst@tempC{\psk@ThreeDplot@deltay}
        \pst@cnty=\pst@tempB \advance\pst@cnty by -1%
        \pstFPdiv\pst@tempB\psk@IIIDticksize{\psk@ThreeDplot@xThreeDunit}
        \pstFPadd\pst@tempA{-\pst@tempB}{\pst@OffsetX}
        \pstFPadd\pst@tempB{\pst@tempB}{\pst@OffsetX}
        \pstFPadd\pst@tempC{\pst@OffsetY}{\psk@ThreeDplot@deltay}
        \pstFPadd\pst@tempD{\pst@OffsetY}{\psk@Dy}
        \pst@dimm=\pst@tempD pt\edef\pst@tempD{\strip@pt\pst@dimm}% strip the 00... from fp
        \pstFPadd\pst@tempE{\psk@IIIDyticksep}{\pst@OffsetX}
        \pstFPdiv\pst@tempE\pst@tempE\psk@ThreeDplot@xThreeDunit
        \edef\@xyDecimals{\psk@xDecimals}%
        \multido{\nA=\pst@tempD+\psk@Dy,
                 \rB=\pst@tempC+\psk@ThreeDplot@deltay}
                {\the\pst@cnty}{%
          \ifx\psk@IIIDyTicksPlane\ThreeDplot@planeXY
            \pstThreeDLine[arrows=-](\pst@tempA,\rB,\pst@OffsetZ)(\pst@tempB,\rB,\pst@OffsetZ)%
          \else
            \ifx\psk@IIIDyTicksPlane\ThreeDplot@planeYZ
              \pstThreeDLine[arrows=-](\pst@OffsetX,\rB,\pst@tempA)(\pst@OffsetX,\rB,\pst@tempB)%
          \fi\fi
          \ifPst@IIIDlabels%
            \pstPlanePut[plane=\psk@IIIDyTicksPlane](\pst@tempE,\rB,\pst@OffsetZ){%
              \psxyzlabel{\expandafter\@LabelComma\nA..\@nil\psk@ylabelFactor}}%
%%            \psxyzlabel{\nA\psk@ylabelFactor}}%
          \fi%
        }% end of multido
      \fi% 
      \ifdim\psk@ThreeDplot@yMin pt<\z@ % only for negative parts of the axes
        \pstFPadd\pst@tempB\psk@ThreeDplot@yMin{-\pst@OffsetY}
        \pstFPDiv\pst@tempB{\pst@tempB}{\psk@ThreeDplot@deltay}
        \pst@cnty=-\pst@tempB
        \pstFPdiv\pst@tempB{\psk@IIIDticksize}{\psk@ThreeDplot@yThreeDunit}
        \pstFPadd\pst@tempA{-\pst@tempB}{\pst@OffsetX}
        \pstFPadd\pst@tempB{\pst@tempB}{\pst@OffsetX}
        \pstFPadd\pst@tempC{\pst@OffsetY}{-\psk@ThreeDplot@deltay}
        \pstFPadd\pst@tempD{\pst@OffsetY}{-\psk@Dy}
        \pst@dimm=\pst@tempD pt\edef\pst@tempD{\strip@pt\pst@dimm}% strip the 00... from fp
        \pstFPadd\pst@tempE{\psk@IIIDyticksep}{\pst@OffsetX}
        \pstFPdiv\pst@tempE\pst@tempE\psk@ThreeDplot@xThreeDunit
        \edef\@xyDecimals{\psk@xDecimals}%
        \multido{\nA=\pst@tempD+-\psk@Dy,%
                 \rB=\pst@tempC+-\psk@ThreeDplot@deltay}
                {\the\pst@cnty}{%
          \ifx\psk@IIIDyTicksPlane\ThreeDplot@planeXY
            \pstThreeDLine[arrows=-](\pst@tempA,\rB,\pst@OffsetZ)(\pst@tempB,\rB,\pst@OffsetZ)%
          \else
            \ifx\psk@IIIDyTicksPlane\ThreeDplot@planeYZ
              \pstThreeDLine[arrows=-](\pst@OffsetX,\rB,\pst@tempA)(\pst@OffsetX,\rB,\pst@tempB)%
          \fi\fi
          \ifPst@IIIDlabels%
            \pstPlanePut[plane=\psk@IIIDyTicksPlane](\pst@tempE,\rB,\pst@OffsetZ){%
              \psxyzlabel{\expandafter\@LabelComma\nA..\@nil\psk@ylabelFactor}}%
%%              \psxyzlabel{\nA\psk@ylabelFactor}}%
          \fi
        }% end of multido and y ticks and labels
      \fi
%------------ z ticks and labels --------------------------
      \ifdim\psk@ThreeDplot@zMax pt>\z@ % only for positive parts of the axes
        \ifdim\psk@ThreeDplot@zMin pt>\z@
          \pstFPadd\pst@tempC\psk@ThreeDplot@zMax{-\psk@ThreeDplot@zMin}
        \else\let\pst@tempC\psk@ThreeDplot@zMax
        \fi%
        \pstFPadd\pst@tempC\pst@tempC{-\pst@OffsetZ}
        \pstFPDiv\pst@tempB\pst@tempC{\psk@ThreeDplot@deltaz}
        \pst@cntz=\pst@int{\pst@tempB} \advance\pst@cntz by -1%
        \pstFPdiv\pst@tempB\psk@IIIDticksize{\psk@ThreeDplot@yThreeDunit}
        \pstFPadd\pst@tempA{-\pst@tempB}{\pst@OffsetY}
        \pstFPadd\pst@tempB{\pst@tempB}{\pst@OffsetY}
        \pstFPadd\pst@tempC\pst@OffsetZ{\psk@ThreeDplot@deltaz}
        \pstFPadd\pst@tempD\pst@OffsetZ{\psk@Dz}
        \pst@dimm=\pst@tempD pt\edef\pst@tempD{\strip@pt\pst@dimm}% strip the 00... from fp
        \pstFPadd\pst@tempE{\psk@IIIDzticksep}{\pst@OffsetY}
        \pstFPdiv\pst@tempE\pst@tempE\psk@ThreeDplot@yThreeDunit
        \edef\@xyDecimals{\psk@xDecimals}%
        \multido{\nA=\pst@tempD+\psk@Dz,
                 \rB=\pst@tempC+\psk@ThreeDplot@deltaz}%
                {\the\pst@cntz}{%
          \ifx\psk@IIIDzTicksPlane\ThreeDplot@planeYZ
            \pstThreeDLine[arrows=-](\pst@OffsetX,\pst@tempA,\rB)(\pst@OffsetX,\pst@tempB,\rB)%
          \else
          \ifx\psk@IIIDzTicksPlane\ThreeDplot@planeXZ
            \pstThreeDLine[arrows=-](\pst@tempA,\pst@OffsetY,\rB)(\pst@tempB,\pst@OffsetY,\rB)%
          \fi\fi
          \ifPst@IIIDlabels%
%%          \pshlabel{\psk@labelFontSize\expandafter\@LabelComma##1..\@nil\psk@xlabelFactor}%
            \pstPlanePut[plane=\psk@IIIDzTicksPlane](\pst@OffsetX,\pst@tempE,\rB){%
              \psxyzlabel{\expandafter\@LabelComma\nA..\@nil\psk@zlabelFactor}}%
          \fi%
        }%
      \fi
      \ifdim\psk@ThreeDplot@zMin pt<\z@ % only for negative parts of the axes
        \pstFPadd\pst@tempB\psk@ThreeDplot@zMin{-\pst@OffsetZ}
        \pstFPDiv\pst@tempB\pst@tempB{\psk@ThreeDplot@deltaz}
        \pst@cntz=-\pst@tempB% 
        \pstFPdiv\pst@tempB\psk@IIIDticksize{\psk@ThreeDplot@yThreeDunit}
        \pstFPadd\pst@tempA{-\pst@tempB}{\pst@OffsetY}
        \pstFPadd\pst@tempB{\pst@tempB}{\pst@OffsetY}
        \pstFPadd\pst@tempC\pst@OffsetZ{-\psk@ThreeDplot@deltaz}
        \pstFPadd\pst@tempD\pst@OffsetZ{-\psk@Dz}
        \pst@dimm=\pst@tempD pt\edef\pst@tempD{\strip@pt\pst@dimm}% strip the 00... from fp
        \pstFPadd\pst@tempE{\psk@IIIDzticksep}{\pst@OffsetY}
        \pstFPdiv\pst@tempE\pst@tempE\psk@ThreeDplot@yThreeDunit
        \edef\@xyDecimals{\psk@xDecimals}%
        \multido{\nA=\pst@tempD+-\psk@Dz,%
                 \rB=\pst@tempC+-\psk@ThreeDplot@deltaz}{\the\pst@cntz}{%
          \ifx\psk@IIIDzTicksPlane\ThreeDplot@planeYZ
            \pstThreeDLine[arrows=-](\pst@OffsetX,\pst@tempA,\rB)(\pst@OffsetX,\pst@tempB,\rB)%
          \else
          \ifx\psk@IIIDzTicksPlane\ThreeDplot@planeXZ
            \pstThreeDLine[arrows=-](\pst@tempA,\pst@OffsetY,\rB)(\pst@tempB,\pst@OffsetY,\rB)%
          \fi\fi
          \ifPst@IIIDlabels%
            \pstPlanePut[plane=\psk@IIIDzTicksPlane](\pst@OffsetX,\pst@tempE,\rB){%
              \psxyzlabel{\expandafter\@LabelComma\nA..\@nil\psk@zlabelFactor}}%
%%              \psxyzlabel{\nA\psk@zlabelFactor}}%
          \fi%
        }% end \multido
      \fi% end \ifdim\psk@ThreeDplot@zMin
    \fi% end \ifPst@IIIDticks%
  \fi% end \ifPst@drawing
  \endgroup
  \ignorespaces
}
%
% planeGrids
%
\newdimen\pst@dx\newdimen\pst@dy
\def\pstThreeDPlaneGrid{\def\pst@par{}\pst@object{pstThreeDPlaneGrid}}
\def\pstThreeDPlaneGrid@i(#1,#2)(#3,#4){{%
  \pst@killglue
  \use@par
  \pssetxlength\pst@dima{#1}
  \pssetxlength\pst@dimb{#3}
  \advance\pst@dimb by -\pst@dima
  \divide\pst@dimb by \psk@xsubticks
  \pst@dx=\pst@dimb
%  
  \pssetylength\pst@dima{#2}
  \pssetylength\pst@dimb{#4}
  \advance\pst@dimb by -\pst@dima
  \divide\pst@dimb by \psk@ysubticks
  \pst@dy=\pst@dimb
%  
  \pssetylength\pst@dimx{#2}
  \pssetylength\pst@dimy{#4}
  \pssetylength\pst@dimz{#1}
  \pssetylength\pst@dimf{#3}
  \pst@getlength\psk@planeGridOffset\pst@dima
  \pst@cntx=\psk@xsubticks \advance\pst@cntx by \@ne
  \pst@cnty=\psk@ysubticks \advance\pst@cnty by \@ne
  \psset{unit=1pt}
  \psset[pst-3dplot]{planeGridOffset=\pst@dima}% we need everything in pt
  \ifx\psk@planeGrid\ThreeDplot@planeXY
    \multido{\rA=\strip@pt\pst@dimz+\strip@pt\pst@dx}{\pst@cntx}{%
      \pstThreeDLine(\rA,\strip@pt\pst@dimx,\psk@planeGridOffset)%
                    (\rA,\strip@pt\pst@dimy,\psk@planeGridOffset)}
    \multido{\rA=\strip@pt\pst@dimx+\strip@pt\pst@dy}{\pst@cnty}{%
      \pstThreeDLine(\strip@pt\pst@dimz,\rA,\psk@planeGridOffset)%
                    (\strip@pt\pst@dimf,\rA,\psk@planeGridOffset)}
  \else
    \ifx\psk@planeGrid\ThreeDplot@planeXZ
      \multido{\rA=\strip@pt\pst@dimz+\strip@pt\pst@dx}{\pst@cntx}{%
        \pstThreeDLine(\rA,\psk@planeGridOffset,\strip@pt\pst@dimx)%
	              (\rA,\psk@planeGridOffset,\strip@pt\pst@dimy)}
      \multido{\rA=\strip@pt\pst@dimx+\strip@pt\pst@dy}{\pst@cnty}{%
        \pstThreeDLine(\strip@pt\pst@dimz,\psk@planeGridOffset,\rA)%
	              (\strip@pt\pst@dimf,\psk@planeGridOffset,\rA)}
    \else
      \multido{\rA=\strip@pt\pst@dimz+\strip@pt\pst@dx}{\pst@cntx}{%
        \pstThreeDLine(\psk@planeGridOffset,\rA,\strip@pt\pst@dimx)%
	              (\psk@planeGridOffset,\rA,\strip@pt\pst@dimy)}
      \multido{\rA=\strip@pt\pst@dimx+\strip@pt\pst@dy}{\pst@cnty}{%
        \pstThreeDLine(\psk@planeGridOffset,\strip@pt\pst@dimz,\rA)%
	              (\psk@planeGridOffset,\strip@pt\pst@dimf,\rA)}
    \fi 
  \fi%
}\ignorespaces}
%
% transform the 3d coordinates of the point (#1,#2,#3)
% into a 2d and moveto
%
\def\pstThreeDmoveto{\def\pst@par{}\pst@object{pstThreeDmoveto}}
\def\pstThreeDmoveto@i(#1,#2,#3){%
  \pst@killglue
  \begingroup
  \addto@pscode{
    \pst@3ddict
    \IIIDplot@variables
    #1 #2 #3 
    \ifPst@SphericalCoor  
      ConvertToCartesian  
    \else
      \psk@ThreeDplot@zThreeDunit\space mul /z ED
      \psk@ThreeDplot@yThreeDunit\space mul /y ED
      \psk@ThreeDplot@xThreeDunit\space mul /x ED
   \fi
    ConvertTo2D x2D y2D end moveto }%
  \use@pscode
  \def\pst@par{}%
  \endgroup
\ignorespaces}
%
%
% put anything at (#2,#3,#4)
%
\def\pstThreeDPut{\def\pst@par{}\@ifnextchar[{\pst@ThreeDPut}{\pst@ThreeDPut[]}}
\def\pst@ThreeDPut[#1](#2,#3,#4)#5{{%
  \pst@killglue%
  \psset{#1}%
  \pstThreeDNode(#2,#3,#4){temp@pstNode}%
%	\def\@tempa{c}
%	\ifx\pst@ThreeDplot@pOrigin\@tempa%
%	    \rput(temp@pstNode){#5}%
%	\else%
  \rput[\psk@ThreeDplot@pOrigin](temp@pstNode){#5}%
%	\fi%
}\ignorespaces}
%
% draws a 3d line
%
\def\cartesianIIID@coor#1,#2,#3,#4\@nil{\edef\pst@coor{#1 #2 #3 }}
\def\NormalIIIDCoor{%
  \def\pst@@getcoor##1{\pst@expandafter\cartesianIIID@coor{##1}, ,\@nil}%
  \def\pst@@getangle##1{%
    \pst@checknum{##1}\pst@angle%
    \edef\pst@angle{\pst@angle \pst@angleunit}%
  }%
  \def\psput@##1{\pst@@getcoor{##1}\leavevmode\psput@cartesian}%
}%

\def\pstThreeDLine{\NormalIIIDCoor\def\pst@par{}\pst@object{pst@lineIIID}}
\def\pst@lineIIID@i{%
  \pst@killglue
  \pst@getarrows{%
    \begin@OpenObj
      \pst@getcoors[\pst@lineIIID@ii
  }%
}
\def\pst@lineIIID@ii{%
  \addto@pscode{
     \pst@3ddict
      \IIIDplot@variables
%      \psk@ThreeDplot@linejoin setlinejoin
      /dxUnit \psk@ThreeDplot@xThreeDunit\space def
      /dyUnit \psk@ThreeDplot@yThreeDunit\space def
      /dzUnit \psk@ThreeDplot@zThreeDunit\space def 
      \ifPst@SphericalCoor /SphericalCoor true def 
      \else /SphericalCoor false def
      \fi 
      /xUnit { \pst@number\psxunit\space mul } def
      /yUnit { \pst@number\psyunit\space mul } def
      convertStackTo2D 
     end
    \pst@cp\space \psline@iii\space \tx@Line
  }%
  \end@OpenObj
  \ignorespaces
  \SpecialCoor
}
%
% set a 3d dot
%
\def\pstThreeDDot{\def\pst@par{}\pst@object{pstThreeDDot}}
\def\pstThreeDDot@i(#1,#2,#3){%
  \begingroup
  \use@keep@par
  \pstThreeDNode(#1,#2,#3){pst@A} % we need the parameters
  \ifx\psk@dotstyle\@none\else\psdots(pst@A)\fi
  \endgroup
  \ifPst@drawCoor  
    \addbefore@par{style=showCoorStyle}
    \begin@SpecialObj
    \addto@pscode{
       \pst@3ddict
       \IIIDplot@variables
%       \psk@ThreeDplot@linejoin setlinejoin
       #1 #2 #3
       \ifPst@SphericalCoor  
         ConvertToCartesian  
       \else
         \psk@ThreeDplot@zThreeDunit\space mul /z ED
         \psk@ThreeDplot@yThreeDunit\space mul /y ED
         \psk@ThreeDplot@xThreeDunit\space mul /x ED
       \fi
       ConvertTo2D 
       x2D \pst@number\psxunit\space mul 
       y2D \pst@number\psyunit\space mul 
       moveto /RotX 0 def /RotY 0 def /RotZ 0 def
       /z 0 def 
       ConvertTo2D /x2DOld x2D def /y2DOld y2D def 
       x2D \pst@number\psxunit\space mul 
       y2D \pst@number\psyunit\space mul 
       lineto
       /y@i y def /y 0 def
       ConvertTo2D 
       x2D \pst@number\psxunit\space mul 
       y2D \pst@number\psyunit\space mul 
       lineto 
       x2DOld \pst@number\psxunit\space mul 
       y2DOld \pst@number\psyunit\space mul 
       moveto 
       /y y@i def /x 0 def
       ConvertTo2D 
       x2D \pst@number\psxunit\space mul 
       y2D \pst@number\psyunit\space mul 
       lineto 
       \ifx\pslinestyle\@none\else
         gsave
         \pst@number\pslinewidth SLW
         \pst@usecolor\pslinecolor
         \@nameuse{psls@\pslinestyle}
         grestore
       \fi
     end
   }%
   \end@SpecialObj
  \fi
  \ignorespaces}
%
% transform the 3d coordinates of the node (#1,#2,#3)
% into a 2d node with the name #4
%
\def\pstThreeDNode{\def\pst@par{}\pst@object{pstThreeDNode}}
\def\pstThreeDNode@i(#1,#2,#3)#4{%
  \begingroup
  \use@par
%  \begin@SpecialObj%
  \pnode(!
    \pst@3ddict
    \IIIDplot@variables
    #1 #2 #3
    \ifPst@SphericalCoor  
      ConvertToCartesian  
    \else
      \psk@ThreeDplot@zThreeDunit\space mul /z ED
      \psk@ThreeDplot@yThreeDunit\space mul /y ED
      \psk@ThreeDplot@xThreeDunit\space mul /x ED
   \fi
    ConvertTo2D x2D y2D end ){#4}%
%  \end@SpecialObj
  \endgroup
\ignorespaces}
%
%\define@key[psset]{pst-3dplot}{nodeType}{\pst@getint{#1}\pst@IIIDNodeType}
%\psset{nodeType=0}
\def\pstIIIDNode{\def\pst@par{}\pst@object{pstIIIDNode}}
\def\pstIIIDNode@i(#1)(#2)(#3)(#4)(#5){%
  \@ifnextchar({\pstIIIDNode@iii(#1)(#2)(#3)(#4)(#5)}{\pstIIIDNode@ii(#1)(#2)(#3)(#4)(#5)}}

\def\pstIIIDNode@ii(#1)(#2)(#3)(#4)(#5)#6{%     line and plain. #6 node name
  \begin@SpecialObj
  \getThreeDCoor{#1}\pst@tempA
  \getThreeDCoor{#2}\pst@tempB
  \getThreeDCoor{#3}\pst@tempC
  \getThreeDCoor{#4}\pst@tempD
  \getThreeDCoor{#5}\pst@tempE
  \pnode(!%
    \pst@3ddict
    \IIIDplot@variables
%    #1 #2 	% a + r vec(m)            
%    #3 #4 #5    % b + s vec(u) + s vec(v) 
    [\pst@tempA] [\pst@tempC]              % x11 x21 x31 x12 x22 x32
    vector-sub /b ED
    /r [\pst@tempB] -1 vector-scale def
    /s [\pst@tempD] def
    /t [\pst@tempE] def    
    [ 
      [ r 0 get s 0 get t 0 get b 0 get ]
      [ r 1 get s 1 get t 1 get b 1 get ]
      [ r 2 get s 2 get t 2 get b 2 get ]
    ] 
    SolveLinEqSystem aload pop % r s t
    pop pop [\pst@tempB] exch vector-scale % r*vec(#2)
    [\pst@tempA] vector-add aload pop 
    /z ED /y ED /x ED
    ConvertTo2D x2D y2D end ){#6}%
  \end@SpecialObj%
}
\def\pstIIIDNode@iii(#1)(#2)(#3)(#4)(#5)(#6)#7{%     plain and plain
}
%
% a 3d uput[](){}
%
\def\pstUThreeDPut{\@ifnextchar[{\pst@UThreeDPut}{\pst@UThreeDPut[]}}
\def\pst@UThreeDPut[#1](#2,#3,#4)#5{{%
  \uput[#1](!%
    \pst@3ddict
      \IIIDplot@variables
      \ifPst@SphericalCoor
        #2\space #3\space #4\space
        ConvertToCartesian
      \else
        /x #2\space\psk@ThreeDplot@xThreeDunit\space mul def 
        /y #3\space\psk@ThreeDplot@yThreeDunit\space mul def 
        /z #4\space\psk@ThreeDplot@zThreeDunit\space mul def
      \fi
      ConvertTo2D x2D y2D 
    end ){#5}%
}\ignorespaces}
%
% Trangle [options](Point1)(Point2)(Point3)
\def\pstThreeDTriangle{\def\pst@par{}\pst@object{pst@ThreeDTriangle}}
\def\pst@ThreeDTriangle@i(#1,#2,#3)(#4,#5,#6)(#7,#8,#9){%
  \begingroup
  \use@par
  \ifPst@drawCoor%
    \bgroup
    \pstThreeDDot[style=showCoorStyle](#1,#2,#3)
    \pstThreeDDot[style=showCoorStyle](#4,#5,#6)
    \pstThreeDDot[style=showCoorStyle](#7,#8,#9)
    \egroup
  \fi%
  \begin@ClosedObj
    \addto@pscode{%
      \pst@3ddict
        \IIIDplot@variables
%        \psk@ThreeDplot@linejoin setlinejoin
        /P1 { #1 #2 #3 } def % x y z or Radius longitude lattitude
        /P2 { #4 #5 #6 } def %
        /P3 { #7 #8 #9 } def %
        /SphericalCoor \ifPst@SphericalCoor true \else false \fi def %
        /xUnit { \pst@number\psxunit\space mul } def
        /yUnit { \pst@number\psyunit\space mul } def
        P1 saveCoor
	SphericalCoor { ConvertToCartesian } if
        ConvertTo2D
        /x0 x2D xUnit def /y0 y2D yUnit def
        P2 saveCoor
        SphericalCoor { ConvertToCartesian } if
        ConvertTo2D
        /x1 x2D xUnit def /y1 y2D yUnit def
        P3 saveCoor
        SphericalCoor { ConvertToCartesian } if
        ConvertTo2D
        /x2 x2D xUnit def /y2 y2D yUnit def
        [ x0 y0 x1 y1 x2 y2 x0 y0
        \pst@cp\space \psline@iii\space \tx@Line\space closepath
      end
    }%
  \end@ClosedObj%
  \endgroup
  \ignorespaces}
%
% draws a threeD square as a polygon
%
% [#1] options
% (#2) starting vector ax,ay,az
% (#3) first direction vector ux,uy,uz
% (#4) second direction vector wx,wy,wz
%
\def\pstThreeDSquare{\def\pst@par{}\pst@object{pstThreeDSquare}}
\def\pstThreeDSquare@i(#1,#2,#3)(#4,#5,#6)(#7,#8,#9){%
  \begingroup
  \use@keep@par
  \ifPst@drawCoor
    \pstThreeDDot[style=showCoorStyle](#1,#2,#3)%
%    \pst@addThreeDVecPS(#1,#2,#3)(#4,#5,#6)\pst@tempAA\pst@tempBB\pst@tempCC
    \pstThreeDDot[style=showCoorStyle](#1 #4 add, #2 #5 add, #3 #6 add)%
%    \pst@addThreeDVecPS(#1,#2,#3)(#7,#8,#9)\pst@tempAA\pst@tempBB\pst@tempCC
    \pstThreeDDot[style=showCoorStyle](#1 #7 add, #2 #8 add, #3 #9 add)%
%    \pst@addThreeDVecPS(\pst@tempAA,\pst@tempBB,\pst@tempCC)(#4,#5,#6)\pst@tempA\pst@tempB\pst@tempC
    \pstThreeDDot[style=showCoorStyle](#1 #4 add #7 add, #2 #5 add #8 add, #3 #6 add #9 add)%
  \fi%
  \endgroup
  \begin@ClosedObj
    \addto@pscode{
      \pst@3ddict
        \IIIDplot@variables
%        \psk@ThreeDplot@linejoin setlinejoin
        /P1 { #1 #2 #3 } def % x y z or Radius longitude lattitude
        /P2 { #4 #5 #6 } def %
        /P3 { #7 #8 #9 } def %
        \tx@setTransparency
        \tx@setStrokeTransparency
        /SphericalCoor \ifPst@SphericalCoor true \else false \fi def %
        /xUnit { \pst@number\psxunit\space mul } def
        /yUnit { \pst@number\psyunit\space mul } def
        P1 saveCoor
	SphericalCoor { ConvertToCartesian } if
        ConvertTo2D
        /x0 x2D xUnit def /y0 y2D yUnit def
        P2 saveCoor
        SphericalCoor { ConvertToCartesian } if
        ConvertTo2D
        /x1 x2D xUnit x0 add def /y1 y2D yUnit y0 add def
        P3 saveCoor
        SphericalCoor { ConvertToCartesian } if
        ConvertTo2D
        /x2 x2D xUnit x1 add def /y2 y2D yUnit y1 add def
        P2 saveCoor
        SphericalCoor { ConvertToCartesian } if
        ConvertTo2D
        /x3 x2D xUnit neg x2 add def /y3 y2D yUnit neg y2 add def
        [ x0 y0 x1 y1 x2 y2 x3 y3 x0 y0
        \pst@cp\space \psline@iii\space \tx@Line\space closepath
      end
    }%
  \end@ClosedObj%
}
%
% draws a threeD Box
% [#1] options
% (#2) first direction vector ux,uy,uz
% (#3) second direction vector vx,vy,vz
% (#4) third direction vector wx,wy,wz
%
\def\pstThreeDBox{\pst@object{pstThreeDBox}}
\def\pstThreeDBox@i(#1,#2,#3){%
  \pst@killglue
  \begingroup
  \addbefore@par{alternative=false,linestyle=\psk@ThreeDplot@visibleLineStyle}%
  \use@keep@par
  \gdef\pst@tempX{#1 }%
  \gdef\pst@tempY{#2 }%
  \gdef\pst@tempZ{#3 }%
  \pstThreeDBox@ii
}
\def\pstThreeDBox@ii(#1,#2,#3)(#4,#5,#6)(#7,#8,#9){%%\def\pstThreeDBox@i[#1](#2)(#3)(#4)(#5)
\ifPst@alternative% better support for hidden lines
  \pstThreeDSquare(\pst@tempX,\pst@tempY,\pst@tempZ)(#4,#5,#6)(#7,#8,#9) % 	lower square  
  \pst@absdim{\psk@ThreeDplot@Alpha pt}\pst@dimo
  \ifdim\pst@dimo<90pt 
    \ifdim\pst@dimo>270pt
      \pstThreeDSquare(\pst@tempX,\pst@tempY,\pst@tempZ)(#1,#2,#3)(#4,#5,#6)% 	back square
    \else
      \pstThreeDSquare(\pst@tempX #7 add,\pst@tempY #8 add,\pst@tempZ #9 add)(#1,#2,#3)(#4,#5,#6)% front square
    \fi
  \else
    \ifdim\pst@dimo>270pt
      \pstThreeDSquare(\pst@tempX #7 add,\pst@tempY #8 add,\pst@tempZ #9 add)(#1,#2,#3)(#4,#5,#6)% front square
    \else
      \pstThreeDSquare(\pst@tempX,\pst@tempY,\pst@tempZ)(#1,#2,#3)(#4,#5,#6)% 	back square
    \fi
  \fi
  \ifPst@hiddenLine\psset{linestyle=\psk@ThreeDplot@invisibleLineStyle}\fi
  \pstThreeDSquare(\pst@tempX #4 add,\pst@tempY #5 add,\pst@tempZ #6 add)(#1,#2,#3)(#7,#8,#9)% left square
  \pstThreeDSquare(\pst@tempX #1 add,\pst@tempY #2 add,\pst@tempZ #3 add)(#4,#5,#6)(#7,#8,#9)% top square
  \ifdim\pst@dimo<90pt 
    \ifdim\pst@dimo>270pt 
      \pstThreeDSquare(\pst@tempX #7 add,\pst@tempY #8 add,\pst@tempZ #9 add)(#1,#2,#3)(#4,#5,#6)% front square
    \else
      \pstThreeDSquare(\pst@tempX,\pst@tempY,\pst@tempZ)(#1,#2,#3)(#4,#5,#6)% 	back square
    \fi
  \else
    \ifdim\pst@dimo>270pt 
      \pstThreeDSquare(\pst@tempX,\pst@tempY,\pst@tempZ)(#1,#2,#3)(#4,#5,#6)% 	back square
    \else
      \pstThreeDSquare(\pst@tempX #7 add,\pst@tempY #8 add,\pst@tempZ #9 add)(#1,#2,#3)(#4,#5,#6)% front square
    \fi
  \fi%
\else
  \ifnum\psk@ThreeDplot@coorType=3
    \ifPst@hiddenLine
	\psset{linestyle=\psk@ThreeDplot@invisibleLineStyle}
	\pstThreeDLine(\pst@tempX,\pst@tempY,\pst@tempZ)(\pst@tempX #1 add,\pst@tempY,\pst@tempZ)(\pst@tempX #1 add,\pst@tempY #5 add,\pst@tempZ)
	\pstThreeDLine(\pst@tempX #1 add,\pst@tempY,\pst@tempZ)(\pst@tempX #1 add,\pst@tempY,\pst@tempZ #9 add)
	\psset{linestyle=\psk@ThreeDplot@visibleLineStyle}
    \else
      \pstThreeDSquare(\pst@tempX,\pst@tempY,\pst@tempZ)(#1,#2,#3)(#4,#5,#6)% 	bottom square
      \pstThreeDSquare(\pst@tempX #1 add,\pst@tempY #2 add,\pst@tempZ #3 add)(#4,#5,#6)(#7,#8,#9)% left square
    \fi    
    \pstThreeDSquare(\pst@tempX #4 add,\pst@tempY #5 add,\pst@tempZ #6 add)(#1,#2,#3)(#7,#8,#9)% right square
    \pstThreeDSquare(\pst@tempX #7 add,\pst@tempY #8 add,\pst@tempZ #9 add)(#1,#2,#3)(#4,#5,#6)% top square
    \pstThreeDSquare(\pst@tempX,\pst@tempY,\pst@tempZ)(#4,#5,#6)(#7,#8,#9)% 	right square
  \else
    \ifnum\psk@ThreeDplot@coorType=5
      \ifPst@hiddenLine
	\psset{linestyle=\psk@ThreeDplot@invisibleLineStyle}
	\pstThreeDLine(\pst@tempX,\pst@tempY,\pst@tempZ)(\pst@tempX,\pst@tempY,\pst@tempZ #9 add)(\pst@tempX #1 add,\pst@tempY,\pst@tempZ #9 add)
	\pstThreeDLine(\pst@tempX,\pst@tempY,\pst@tempZ #9 add)(\pst@tempX,\pst@tempY #5 add,\pst@tempZ #9 add)
	\psset{linestyle=\psk@ThreeDplot@visibleLineStyle}
     \else
       \pstThreeDSquare(\pst@tempX #7 add,\pst@tempY #8 add,\pst@tempZ #9 add)(#1,#2,#3)(#4,#5,#6)% top square
     \pstThreeDSquare(\pst@tempX,\pst@tempY,\pst@tempZ)(#4,#5,#6)(#7,#8,#9)% 	right square
     \fi    
       \pstThreeDSquare(\pst@tempX,\pst@tempY,\pst@tempZ)(#1,#2,#3)(#4,#5,#6)% 	bottom square
     \pstThreeDSquare(\pst@tempX #4 add,\pst@tempY #5 add,\pst@tempZ #6 add)(#1,#2,#3)(#7,#8,#9)% top square
       \pstThreeDSquare(\pst@tempX #1 add,\pst@tempY #2 add,\pst@tempZ #3 add)(#4,#5,#6)(#7,#8,#9)% left square
   \else
    \pstThreeDSquare(\pst@tempX #1 add,\pst@tempY #2 add,\pst@tempZ #3 add)(#4,#5,#6)(#7,#8,#9)% left square
    \pstThreeDSquare(\pst@tempX #4 add,\pst@tempY #5 add,\pst@tempZ #6 add)(#1,#2,#3)(#7,#8,#9)% front square
    \pstThreeDSquare(\pst@tempX #7 add,\pst@tempY #8 add,\pst@tempZ #9 add)(#1,#2,#3)(#4,#5,#6)% top square
      \ifPst@hiddenLine
	\pstThreeDLine[linestyle=\psk@ThreeDplot@invisibleLineStyle](\pst@tempX #1 add,\pst@tempY #2 add,\pst@tempZ #3 add)(\pst@tempX,\pst@tempY,\pst@tempZ)(\pst@tempX #4 add,\pst@tempY #5 add,\pst@tempZ #6 add)
	\pstThreeDLine[linestyle=\psk@ThreeDplot@invisibleLineStyle](\pst@tempX,\pst@tempY,\pst@tempZ)(\pst@tempX #7 add,\pst@tempY #8 add,\pst@tempZ #9 add)
%	\psset{linestyle=\psk@ThreeDplot@visibleLineStyle}
    \else
	\pstThreeDSquare(\pst@tempX,\pst@tempY,\pst@tempZ)(#1,#2,#3)(#4,#5,#6)% 	bottom square
	\pstThreeDSquare(\pst@tempX,\pst@tempY,\pst@tempZ)(#4,#5,#6)(#7,#8,#9)% 	right square
    \fi    
    \fi
  \fi
\fi
 \endgroup
 \ignorespaces
}
%



\define@key[psset]{pst-3dplot}{height}[5]{\def\psk@height{#1 }}
\define@key[psset]{pst-3dplot}{move}[0 0]{\def\psk@move{#1 }}
\psset{height=5,move=0 0}
\def\pstThreeDPrism{\NormalIIIDCoor\def\pst@par{}\pst@object{prismIIID}}
\def\prismIIID@i{%
  \pst@killglue%
  \pst@getarrows{%
    \begin@OpenObj%
      \pst@getcoors[\prismIIID@ii}}
\def\prismIIID@ii{%
  \addto@pscode{%
    \pst@3ddict
      \IIIDplot@variables
      /dxUnit \psk@ThreeDplot@xThreeDunit\space def
      /dyUnit \psk@ThreeDplot@yThreeDunit\space def
      /dzUnit \psk@ThreeDplot@zThreeDunit\space def 
      \ifPst@SphericalCoor /SphericalCoor true def 
      \else /SphericalCoor false def
      \fi %
      /xUnit { \pst@number\psxunit\space mul } def
      /yUnit { \pst@number\psyunit\space mul } def
      counttomark array astore /3dValues ED
      3dValues aload pop   
      convertStackTo2D
    end
    \pst@cp\space \psline@iii\space \tx@Line 
    \pst@3ddict
    \psk@move /y0 ED /x0 ED
    [ 3dValues aload length dup /n ED 3 div cvi 
      { \psk@height add 3 1 roll y0 add 3 1 roll x0 add 3 1 roll 
        n -3 roll } repeat
    n array astore /3dValuesMove ED
    3dValuesMove aload pop
    convertStackTo2D
    end
    \pst@cp\space \psline@iii\space \tx@Line 
    \pst@3ddict
      0 3 n { 
        /Index ED 
         3dValues Index 3 getinterval aload pop 
         SphericalCoor { ConvertToCartesian } { saveCoor } ifelse
         ConvertTo2D x2D xUnit y2D yUnit moveto    
         3dValuesMove Index 3 getinterval aload pop 
         SphericalCoor { ConvertToCartesian } { saveCoor } ifelse
         ConvertTo2D x2D xUnit y2D yUnit lineto    
      } for
    end    
  }%
  \end@OpenObj%
  \ignorespaces%
  \SpecialCoor}
%
% set a 3d ellipse/circle
%
% #1 options
% #2 center cx,cy,cz
% #3 radius ax,ay,az
% #4 radius bx,by,bz
%
\def\pstThreeDEllipse{\def\pst@par{}\pst@object{pstThreeDEllipse}}
\def\pstThreeDEllipse@i(#1)(#2)(#3){%
  \addbefore@par{plotstyle=curve}%
  \@nameuse{beginplot@\psplotstyle}%
  \getThreeDCoor{#1}\pst@tempC%  center
  \getThreeDCoor{#2}\pst@tempA%  a
  \getThreeDCoor{#3}\pst@tempB%  b
  \addto@pscode{%
    \pst@3ddict \IIIDplot@variables end
%    \psk@ThreeDplot@linejoin setlinejoin
    \ifPst@SphericalCoor 
      \pst@tempC\space \tx@ConvertToCartesian 
        /zM \tx@Z def /yM \tx@Y def /xM \tx@X def % center
      \pst@tempA\space \tx@ConvertToCartesian  
        /zA \tx@Z def /yA \tx@Y def /xA \tx@X def % a
      \pst@tempB\space \tx@ConvertToCartesian 
        /zB \tx@Z def /yB \tx@Y def /xB \tx@X def % b 
    \else
      \pst@tempC\space /zM ED /yM ED /xM ED % center
      \pst@tempA\space /zA ED /yA ED /xA ED % a
      \pst@tempB\space /zB ED /yB ED /xB ED % b
    \fi
    /aStart \psk@ThreeDplot@beginAngle\space def
%    /aEnd \psk@ThreeDplot@endAngle\space dup aStart lt { 360 add } if def
%    /da aEnd aStart sub \psk@plotpoints\space div abs def
    /aEnd \psk@ThreeDplot@endAngle\space def
    /da aEnd aStart sub \psk@plotpoints\space div def
    \pst@3ddict 
      /vecA [xA yA zA] vector-length def
      /vecB [xB yB zB] vector-length def
    end
    /xyz {
      \pst@3ddict % 
%
% the angle in the parameter equation is not proportional to the real angle!
% phi=atan(b*tan(angle)/a)+floor(angle/180+0.5)*180
%
      /phi angle cvi 90 mod 0 eq { angle } { vecA angle tan mul vecB atan 
        angle 180 div .5 add floor 180 mul add } ifelse def
      xM xA phi cos mul add xB phi sin mul add 
      yM yA phi cos mul add yB phi sin mul add 
      zM zA phi cos mul add zB phi sin mul add 
      saveCoor ConvertTo2D 
      x2D \pst@number\psxunit mul y2D \pst@number\psyunit mul end 
    } def
    /angle aStart def
  }%
  \gdef\psplot@init{}%
  \@pstfalse%
  \@nameuse{testqp@\psplotstyle}%
  \if@pst\pstThreeDEllipse@ii\else\pstThreeDEllipse@iii\fi%
  \ignorespaces}
%
\def\pstThreeDEllipse@ii{%
  \addto@pscode{%
      xyz \@nameuse{beginqp@\psplotstyle}
      \psk@plotpoints 1 sub {
        /angle angle da add def
        xyz \@nameuse{doqp@\psplotstyle}
      } repeat
      /angle aEnd def
      xyz \@nameuse{doqp@\psplotstyle}
  }%
  \@nameuse{endqp@\psplotstyle}}
    
\def\pstThreeDEllipse@iii{%
  \addto@pscode{%
      mark
      /n 2 def
      \psk@plotpoints {
        xyz
        n 2 roll
        /n n 2 add def
        /angle angle da add def
      } repeat
      /angle aEnd def
      xyz
      n 2 roll
  }%
  \@nameuse{endplot@\psplotstyle}}
%
\def\pstThreeDCircle{\def\pst@par{}\pst@object{pstThreeDCircle}}
\def\pstThreeDCircle@i(#1)(#2)(#3){% (vec O)(vec a)(vec b)
  \addbefore@par{plotstyle=curve}%
  \@nameuse{beginplot@\psplotstyle}%
  \getThreeDCoor{#1}\pst@tempC%  center
  \getThreeDCoor{#2}\pst@tempA%  a
  \getThreeDCoor{#3}\pst@tempB%  b
  \addto@pscode{%
    \pst@3ddict \IIIDplot@variables end
%    \psk@ThreeDplot@linejoin setlinejoin
    \ifPst@SphericalCoor 
      \pst@tempC\space \tx@ConvertToCartesian 
        /zM \tx@Z def /yM \tx@Y def /xM \tx@X def % center
      \pst@tempA\space \tx@ConvertToCartesian  
        /zA \tx@Z def /yA \tx@Y def /xA \tx@X def % a
      \pst@tempB\space \tx@ConvertToCartesian 
        /zB \tx@Z def /yB \tx@Y def /xB \tx@X def % b 
    \else
      \pst@tempC\space /zM ED /yM ED /xM ED % center
      \pst@tempA\space /zA ED /yA ED /xA ED % a
      \pst@tempB\space /zB ED /yB ED /xB ED % b
    \fi
%   build the orthogonal part of B to vec A
    \pst@3ddict 
    /vecA [xA yA zA] vector-length def
    /vecB [xB yB zB] vector-length def
    [xA yA zA] [xB yB zB] vector-mul vecA div vecB div % is cos(alpha)
    vecB mul 					       % is |b_parallelA|
    [xA yA zA] vector-unit exch vector-scale           % is b_parallelA 
    [xB yB zB] exch vector-sub                         % is b-bparallelA=b_orthA
    dup vector-length vecA exch div vector-scale       % is b_orthA with |a| 
    aload pop
    /zB ED /yB ED /xB ED
    /vecB [xB yB zB] vector-length def
    end
    /aStart \psk@ThreeDplot@beginAngle\space def
    /aEnd \psk@ThreeDplot@endAngle\space def
    /da aEnd aStart sub \psk@plotpoints\space div def
    /xyz {
      \pst@3ddict % 
%
% the angle in the parameter equation is not proportional to the real angle!
% phi=atan(b*tan(angle)/a)+floor(angle/180+0.5)*180
%
      /phi angle cvi 90 mod 0 eq { angle } { vecA angle tan mul vecB atan 
        angle 180 div .5 add floor 180 mul add } ifelse def
      xM xA phi cos mul add xB phi sin mul add 
      yM yA phi cos mul add yB phi sin mul add 
      zM zA phi cos mul add zB phi sin mul add 
      saveCoor ConvertTo2D 
      x2D \pst@number\psxunit mul y2D \pst@number\psyunit mul end 
    } def
    /angle aStart def
  }%
  \gdef\psplot@init{}%
  \@pstfalse%
  \@nameuse{testqp@\psplotstyle}%
  \if@pst\pstThreeDEllipse@ii\else\pstThreeDEllipse@iii\fi%
  \ignorespaces}
%
\def\pstThreeDPlotFunc{\psplotThreeD}%	only for compatibility
%
% cone[options](center)(radiusA vec)(radiusB vec){height}
%
\def\pstThreeDCone{\def\pst@par{}\pst@object{pstThreeDCone}}
\def\pstThreeDCone@i(#1)(#2)(#3)#4{{%
  \use@par
  \pstThreeDEllipse(#1)(#2)(#3)%
  \begin@OpenObj%
  \getThreeDCoor{#1}\pst@tempA%
  \getThreeDCoor{#2}\pst@tempB%
  \getThreeDCoor{#3}\pst@tempC%
  \addto@pscode{
    \pst@3ddict
    \IIIDplot@variables
%    \psk@ThreeDplot@linejoin setlinejoin
    /xUnit { \pst@number\psxunit\space mul } def
    /yUnit { \pst@number\psyunit\space mul } def
    /SphericalCoor \ifPst@SphericalCoor true \else false \fi def %
    /Center [ \pst@tempA\space SphericalCoor { ConvertToCartesian } if ] def % x y z or Radius longitude lattitude
    Center aload pop saveCoor ConvertTo2D /xC x2D def /yC y2D def
    /rA [ \pst@tempB \space SphericalCoor { ConvertToCartesian } if ] def
    /rB [ \pst@tempC \space SphericalCoor { ConvertToCartesian } if ] def
    rA rB AxB UnitVec #4 AmulC Center AaddB aload pop 
    saveCoor ConvertTo2D /x2 x2D xUnit def /y2 y2D yUnit def
    [ xC rA VecNorm add 90 Beta sub sin sub xUnit yC Beta sin add yUnit 
      x2 y2
      xC rA VecNorm sub xUnit yC yUnit
      \pst@cp\space \psline@iii\space \tx@Line\space end }%
  \end@OpenObj%
}\ignorespaces}
%
\def\pstRotNodeIIID{\def\pst@par{}\pst@object{RotNodeIIID}}
\def\RotNodeIIID@i(#1,#2,#3)(#4,#5,#6)#7{%
  \pst@killglue
  \begingroup%
  \use@par%
  \def\pst@ThreeDplot@ThetaX{#4}%    rotating angle
  \def\pst@ThreeDplot@ThetaY{#5}%    rotating angle
  \def\pst@ThreeDplot@ThetaZ{#6}%    rotating angle
  \pnode(!%
    \pst@3ddict
      \IIIDplot@variables
      \ifPst@SphericalCoor
        #1\space #2\space #3\space
        ConvertToCartesian
      \else
        /x #1\space\psk@ThreeDplot@xThreeDunit\space mul def 
        /y #2\space\psk@ThreeDplot@yThreeDunit\space mul def 
        /z #3\space\psk@ThreeDplot@zThreeDunit\space mul def
      \fi
      ConvertTo2D x2D y2D 
    end ){#7}%
  \endgroup%
  \ignorespaces}
%
% Paraboloid (Idea is from Manuel ... )
%
\def\tx@SetMatrixThreeD{tx@3Ddict begin SetMatrixThreeD end }

\def\pstParaboloid{\def\pst@par{}\pst@object{pstParaboloid}}
\def\pstParaboloid@i{\@ifnextchar(\pstParaboloid@ii{\pstParaboloid@ii(0,0,0)}}
\def\pstParaboloid@ii(#1,#2,#3)#4#5{% #1:height  #2:radius 
\addto@par{viewpoint=0 0 0}%
\begin@SpecialObj%
\addto@pscode{%
  tx@3DPlotDict begin
  \IIIDplot@variables 
  #1 #2 #3 
  saveCoor
  ConvertTo2DWithoutRotating
  x2D \pst@number\psxunit mul y2D \pst@number\psyunit mul end
  translate
  /height #4 def
  /radius #5 #4 sqrt div def
  /increment \psk@ThreeDplot@increment\space def
  /viewpoint {
    \psk@viewpoint
    \ifcase\psk@ThreeDplot@coorType
      \psk@ThreeDplot@Beta\space sin add 3 1 roll
      \psk@ThreeDplot@Alpha\space cos add \psk@ThreeDplot@Beta\space cos mul 3 1 roll
      \psk@ThreeDplot@Alpha\space sin add \psk@ThreeDplot@Beta\space cos mul 3 1 roll
    \or
      3 1 roll 
      \psk@ThreeDplot@Alpha\space cos add 3 1 roll 
      \psk@ThreeDplot@Alpha\space sin add 3 1 roll 
    \else
      3 1 roll 45 cos add 3 1 roll 45 sin add 3 1 roll 
    \fi
  } def
  0 viewpoint 0 \tx@SetMatrixThreeD
  viewpoint 
  \pst@3ddict /vZ ED /vY ED /vX ED 
  /pas 0.5 def
  /pas10 pas 10 div def
%  /cmyk {} def   % we need only the values
   \psgetCMYKColorValues{\psk@ThreeDplot@SegmentColor} 
%  \psk@ThreeDplot@xyzLight\space          % xLight yLight zLight
%
  /calculate2DPoint { % four values on stack; x2D y2D are returned
    /V0 ED /Z0 ED /U20 ED /U10 ED
    U10 cos V0 mul radius mul 
    U20 sin V0 mul radius mul  
    Z0  
    tx@3DPlotDict begin
    saveCoor
    ConvertTo2D
    x2D \pst@number\psxunit mul y2D \pst@number\psyunit mul end
  } def
  /condition { PSfacetteParaboloid 0 le } def
  true MaillageParaboloid
  /condition { PSfacetteParaboloid 0 ge } def
  false MaillageParaboloid
  \ifPstThreeDplot@showInside
    /condition { PSfacetteParaboloid 0 ge } def
    false MaillageParaboloid
    vZ 0 ge {
      PlanCoupeParaboloid 1 0.5 0.5 setrgbcolor fill
      PlanCoupeParaboloid 0 setgray stroke } if
  \fi
  end
}%
% fin du code ps
  \showpointsfalse%
  \end@SpecialObj%
\ignorespaces}
%
% Sphere, the new one
\def\pstThreeDSphere{\def\pst@par{}\pst@object{pstSphereIIID}}
\def\pstSphereIIID@i(#1,#2,#3)#4{% #1:origin (x,y,z)  #2:radius 
\addto@par{viewpoint=0 0 0}% to make it compatible with pst-3dplot
\begin@SpecialObj%
\use@par
\addto@pscode{%
%  \psk@ThreeDplot@linejoin setlinejoin
  /viewpoint {% to make it compatible with parallel projection
    \psk@viewpoint
    \ifcase\psk@ThreeDplot@coorType
      \psk@ThreeDplot@Beta\space sin add 3 1 roll
      \psk@ThreeDplot@Alpha\space cos add \psk@ThreeDplot@Beta\space cos mul 3 1 roll
      \psk@ThreeDplot@Alpha\space sin add \psk@ThreeDplot@Beta\space cos mul 3 1 roll
    \or
      \psk@ThreeDplot@Beta\space sin add 3 1 roll 
      \psk@ThreeDplot@Alpha\space cos add 3 1 roll 
      \psk@ThreeDplot@Alpha\space sin add 3 1 roll 
    \else
      \psk@ThreeDplot@Beta\space sin add 3 1 roll 
      45 cos add 3 1 roll 
      45 sin add 3 1 roll 
    \fi
  } def
  0 viewpoint 0 \tx@SetMatrixThreeD
  viewpoint /vZ ED /vY ED /vX ED
% on stack must be
% x y z Radius increment C M Y K 
  #1 \pst@number\psunit mul #2 \pst@number\psunit mul #3 \pst@number\psunit mul  
  #4 \pst@number\psunit mul
  \psk@ThreeDplot@increment\space
%  /cmyk {} def   % we need only the values
   \psgetCMYKColorValues{\psk@ThreeDplot@SegmentColor} 
  tx@3DPlotDict begin 
    \IIIDplot@variables 
    \tx@setTransparency 
    \tx@setStrokeTransparency 
    MaillageSphere 
  end
}% fin du code ps
  \showpointsfalse%
  \end@SpecialObj%
\ignorespaces}
%
\def\pstIIIDCylinder{\pst@object{pstIIIDCylinder}}
\def\pstIIIDCylinder@i{\@ifnextchar({\pstIIIDCylinder@ii}{\pstIIIDCylinder@ii(0,0,0)}}
\def\pstIIIDCylinder@ii(#1,#2,#3)#4#5{{%
  \let\pst@parOrig\pst@par%
  \begin@ClosedObj%
  \addto@pscode{%
    tx@3DPlotDict begin 
    \IIIDplot@variables 
    #1 #2 #3 \ifPst@CylindricalCoor \tx@ConvCylToCartesian \fi
    saveCoor
    ConvertTo2D
%    ConvertTo2DWithoutRotating
    x2D \pst@number\psxunit mul y2D \pst@number\psyunit mul 
    translate % the lower center
      #4 \pst@number\psunit mul dup 0 360 false
      \pst@usecolor{\pslinecolor}
      IIIDEllipse 
    end
  }% end of pscode
  \end@ClosedObj
  \let\pst@par\pst@parOrig
  \begin@SpecialObj % bottom
  \addto@pscode{%
    tx@3DPlotDict begin
    \IIIDplot@variables  
    #1 #2 #3 \ifPst@CylindricalCoor \tx@ConvCylToCartesian \fi
    saveCoor
    ConvertTo2D
%    ConvertTo2DWithoutRotating
    x2D \pst@number\psxunit mul y2D \pst@number\psyunit mul 
    translate
      #4 \pst@number\psunit mul  	% radius	
      #5 \pst@number\psunit mul		% height
      0 360 				% for the future
      \psk@ThreeDplot@increment
      false				% wedge?
    \tx@setTransparency 
    \tx@setStrokeTransparency 
      IIIDCylinder 
    end
  }% end of pscode
  \end@SpecialObj
  \let\pst@par\pst@parOrig
  \begin@ClosedObj % top
  \addto@pscode{%
    tx@3DPlotDict begin
    \IIIDplot@variables 
    #1 #2 #3 #5 add \ifPst@CylindricalCoor \tx@ConvCylToCartesian \fi
    saveCoor 
    ConvertTo2D
%    ConvertTo2DWithoutRotating
    x2D \pst@number\psxunit mul y2D \pst@number\psyunit mul 
    translate
    #4 \pst@number\psunit mul dup 0 360 false
    \pst@usecolor{\pslinecolor}
    \tx@setTransparency 
    \tx@setStrokeTransparency 
    IIIDEllipse 
    end
  }% end of pscode
  \end@ClosedObj
}\ignorespaces}
%
%-------------------------- Cylinder ----------------------------
%
\def\psCylinder{\def\pst@par{}\pst@object{psCylinder}}
\def\psCylinder@i{\@ifnextchar(\psCylinder@ii{\psCylinder@ii(0,0,0)}}
\def\psCylinder@ii(#1,#2,#3)#4#5{% #1,#2,#3: center of the bottom #4:radius #5:height 
\addto@par{viewpoint=0 0 0}%
\pssetlength\pst@dima{#4}
\pssetlength\pst@dimb{#5}
\begin@SpecialObj%
\use@par
\addto@pscode {
  /viewpoint {
    \psk@viewpoint
    \ifcase\psk@ThreeDplot@coorType
      \psk@ThreeDplot@Beta\space sin add 3 1 roll
      \psk@ThreeDplot@Alpha\space cos add \psk@ThreeDplot@Beta\space cos mul 3 1 roll
      \psk@ThreeDplot@Alpha\space sin add \psk@ThreeDplot@Beta\space cos mul 3 1 roll
    \or
      3 1 roll 
      \psk@ThreeDplot@Alpha\space cos add 3 1 roll 
      \psk@ThreeDplot@Alpha\space sin add 3 1 roll 
    \else
      3 1 roll 45 cos add 3 1 roll 45 sin add 3 1 roll 
    \fi
  } def
  0 viewpoint 0 \tx@SetMatrixThreeD
  viewpoint 
  \pst@3ddict /vZ ED /vY ED /vX ED 
  \IIIDplot@variables end
%  \psk@ThreeDplot@linejoin setlinejoin
%  
  #1 #2 #3 \ifPst@CylindricalCoor \tx@ConvCylToCartesian \fi
  \pst@number\pst@dima \pst@number\psxunit div  % Radius
  \pst@number\pst@dimb \pst@number\psyunit div  % Height
  \psk@ThreeDplot@increment			% angle increment
  \psk@ThreeDplot@Hincrement			% height increment
%  /cmyk {} def   % we need only the values
   \psgetCMYKColorValues{\psk@ThreeDplot@SegmentColor} 
%
    \tx@3DPlotDict
    \tx@setTransparency 
    \tx@setStrokeTransparency 
    /ConvCyl2d { 	% on stack r phi h
      ConvCylToCartesian 
      CZ add /z ED CY add /y ED CX add /x ED 
      RotatePoint x y z Conv3D2D 
      \pst@number\psyunit mul exch
      \pst@number\psxunit mul exch
    } def		% on stack x y
    /condition { PSfacetteCylinder 0 le } def % inside
      true MaillageCylinder % save paras 
      /condition { PSfacetteCylinder 0 ge } def % outside
      false MaillageCylinder % use old paras 
    \ifPstThreeDplot@showInside\else
      vZ 0 ge {					% viewpoint coor
        PlanCoupeCylinder 1 0.5 0.5 setrgbcolor fill
        PlanCoupeCylinder 0 setgray stroke } if
    \fi
    end
  }%
% fin du code ps
  \showpointsfalse%
  \end@SpecialObj%
\ignorespaces}
%
%-------------------------- Box ----------------------------
%
\def\psBox{\def\pst@par{}\pst@object{psBox}}
\def\psBox@i{\@ifnextchar(\psBox@ii{\psBox@ii(0,0,0)}}
\def\psBox@ii(#1,#2,#3)#4#5#6{% #1,#2,#3: center of the lower left edge 
			    % #4:width #5:height #6:depth 
  \addto@par{viewpoint=0 0 0}%
  \pssetlength\pst@dima{#4}\pssetlength\pst@dimb{#5}\pssetlength\pst@dimc{#6}
  \begin@SpecialObj%
  \addto@pscode {
  /viewpoint {
    \psk@viewpoint
    \ifcase\psk@ThreeDplot@coorType
      \psk@ThreeDplot@Beta\space sin add 3 1 roll
      \psk@ThreeDplot@Alpha\space cos add \psk@ThreeDplot@Beta\space cos mul 3 1 roll
      \psk@ThreeDplot@Alpha\space sin add \psk@ThreeDplot@Beta\space cos mul 3 1 roll
    \or
      3 1 roll 
      \psk@ThreeDplot@Alpha\space cos add 3 1 roll 
      \psk@ThreeDplot@Alpha\space sin add 3 1 roll 
    \else
      3 1 roll 45 cos add 3 1 roll 45 sin add 3 1 roll 
    \fi
  } def
  0 viewpoint 0 \tx@SetMatrixThreeD
  viewpoint 
  \tx@3DPlotDict
  /vZ ED /vY ED /vX ED 
  \IIIDplot@variables
%  \psk@ThreeDplot@linejoin setlinejoin
%
  #1 2 div  #2 2 div #3 2 div  % wieso 1/2 ????
  \pst@number\pst@dima \pst@number\psxunit div  % Width
  \pst@number\pst@dimb \pst@number\psyunit div  % Height
  \pst@number\pst@dimc \pst@number\psyunit div  % Depth
%  /cmyk {} def   % we need only the values
   \psgetCMYKColorValues{\psk@ThreeDplot@SegmentColor} 
%
  /PlaneSequence [ \psk@ThreeD@PlaneSequence ] def
  /ConvBox2d { 	% on stack x y z
    CZ add /z ED CY add /y ED CX add /x ED 
    RotatePoint x y z Conv3D2D 
    \pst@number\psyunit mul exch
    \pst@number\psxunit mul exch
  } def		% on stack x y
  /condition { PSfacetteBox 0 le } def % inside
  true MaillageBox % save paras 
  /condition { PSfacetteBox 0 ge } def % outside
  false MaillageBox % use old paras 
  \ifPstThreeDplot@showInside\else
  vZ 0 ge {					% viewpoint coor
    PlanCoupeBox 1 0.5 0.5 setrgbcolor fill
%    /Height 0 def
    PlanCoupeBox 0 setgray stroke } if
  \fi
  end
  }%
% fin du code ps
  \showpointsfalse%
  \end@SpecialObj%
\ignorespaces}
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
\def\psplotinit#1{\xdef\psplot@init{#1 }}
\def\psplot@init{}
%
%\def\psplotThreeD{\@ifnextchar[{\ps@plotThreeD}{\ps@plotThreeD[]}}
\def\psplotThreeD{\def\pst@par{}\pst@object{psplotThreeD}}
\def\psplotThreeD@i(#1,#2)(#3,#4)#5{{%
  \pst@killglue
  \use@par%
  \ifcase\psk@ThreeDplot@drawStyle%
    \psplotThreeD@xLines(#1,#2)(#3,#4){#5}\or%
    \psplotThreeD@yLines(#1,#2)(#3,#4){#5}\or    
    \psplotThreeD@xLines(#1,#2)(#3,#4){#5}%
    \psplotThreeD@yLines(#1,#2)(#3,#4){#5}\or%
    \psplotThreeD@yLines(#1,#2)(#3,#4){#5}%
    \psplotThreeD@xLines(#1,#2)(#3,#4){#5}%
  \fi%
}\ignorespaces}
%
\def\psplotThreeD@xLines(#1,#2)(#3,#4)#5{%
  \pst@killglue%
  \begingroup%
%    \use@par%
    \@pstfalse%
    \@nameuse{beginplot@\psplotstyle}%
    \gdef\psplot@init{}%
    \@nameuse{testqp@\psplotstyle}%
    \if@pst%	lines and dots
      \addto@pscode{
        \IIIDplot@variables
        /func { #5 } def
        \ifPst@algebraic /Func ( #5 ) %tx@Dict begin 
        AlgParser %end 
        cvx def \fi 
        /xMin #1 def
        /x xMin def
        /x1 #2 def
        /y #3 def
        /y1 #4 def
        /dx x1 x sub \psk@ThreeDplot@xPlotpoints\space dup 0 gt {div}{pop} ifelse def
        /dy y1 y sub \psk@ThreeDplot@yPlotpoints\space dup 0 gt {div}{pop} ifelse def
        /xyz { 
	  x \psk@ThreeDplot@zCoor\space 0 gt { \ifPst@algebraic Func \else func \fi }{ y } ifelse 
          \psk@ThreeDplot@zCoor\space 0 gt { \psk@ThreeDplot@zCoor }{ \ifPst@algebraic Func \else func \fi } ifelse 
          tx@3DPlotDict begin
  	  saveCoor
	  ConvertTo2D
	  x2D \pst@number\psxunit mul y2D \pst@number\psyunit mul end } def
        }%
        \psplotThreeD@xLines@ii
    \else%	curves
  \endgroup%
  \multido{\n@Y=0+1}{\psk@ThreeDplot@yPlotpoints}{%
    \ifPst@hiddenLine\pscustom[style=hiddenStyle]{\fi%
    \@nameuse{beginplot@\psplotstyle}%
    \addto@pscode{
      \IIIDplot@variables
      /func { #5 } def
      \ifPst@algebraic /Func ( #5 )  
      AlgParser 
      cvx def \fi 
      /xMin #1 def
      /x xMin def
      /x1 #2 def
      /dx x1 x sub \psk@ThreeDplot@xPlotpoints\space dup 0 gt {div}{pop} ifelse def
      /dy #4\space #3\space sub \psk@ThreeDplot@yPlotpoints\space dup 0 gt {div}{pop} ifelse def
      /y #3\space \n@Y\space dy mul add def
        /xyz { 
	  x \psk@ThreeDplot@zCoor\space 0 gt { \ifPst@algebraic Func \else func \fi  }{ y } ifelse 
          \psk@ThreeDplot@zCoor\space 0 gt { \psk@ThreeDplot@zCoor }{ \ifPst@algebraic Func \else func \fi  } ifelse 
          tx@3DPlotDict begin
  	  saveCoor
	  ConvertTo2D
	  x2D \pst@number\psxunit mul y2D \pst@number\psyunit mul end } def
    }%
    \psplotThreeD@xLines@iii%
    \ifPst@hiddenLine }\fi%
  }%
  \fi%
  \endgroup%
  \ignorespaces%
}
%
\def\psplotThreeD@xLines@ii{%
  \addto@pscode{%
    xyz \@nameuse{beginqp@\psplotstyle}
   \psk@ThreeDplot@yPlotpoints\space 1 add {
     /x xMin def
     xyz moveto
     \psk@ThreeDplot@xPlotpoints\space 1 add {
       xyz \@nameuse{doqp@\psplotstyle}
       /x x dx add def
     } repeat
     /y y dy add def
   } repeat
   /x x1 def
   /y y1 def
   xyz \@nameuse{doqp@\psplotstyle}
  }%
  \@nameuse{endqp@\psplotstyle}%
}
\def\psplotThreeD@xLines@iii{%    curves
  \addto@pscode{%
    /x xMin def
    mark
    /n 2 def
    \psk@ThreeDplot@xPlotpoints {
      xyz
      n 2 roll
      /n n 2 add def
      /x x dx add def
    } repeat
    /x x1 def
    xyz
    n 2 roll
  }%
  \@nameuse{endplot@\psplotstyle}%
}
%
\def\psplotThreeD@yLines(#1,#2)(#3,#4)#5{%
  \pst@killglue
  \begingroup
%  \use@par%
  \@pstfalse
  \@nameuse{beginplot@\psplotstyle}%
  \gdef\psplot@init{}%
  \@nameuse{testqp@\psplotstyle}%
  \if@pst%	lines and dots
    \addto@pscode{%
      \IIIDplot@variables
      /func { #5 } def
      \ifPst@algebraic /Func (#5)  
      AlgParser 
      cvx def \fi 
      /x #1 def
      /x1 #2 def
      /yMin #3 def
      /y yMin def
      /y1 #4 def
      /dx x1 x sub \psk@ThreeDplot@xPlotpoints\space dup 0 gt {div}{pop} ifelse def
      /dy y1 y sub \psk@ThreeDplot@yPlotpoints\space dup 0 gt {div}{pop} ifelse def
      /xyz { 
	  x \psk@ThreeDplot@zCoor\space 0 gt { \ifPst@algebraic Func \else func \fi  }{ y } ifelse 
          \psk@ThreeDplot@zCoor\space 0 gt { \psk@ThreeDplot@zCoor }{ \ifPst@algebraic Func \else func \fi  } ifelse 
          tx@3DPlotDict begin
  	  saveCoor
	  ConvertTo2D
	  x2D \pst@number\psxunit mul y2D \pst@number\psyunit mul end } def
    }%
    \psplotThreeD@yLines@ii
  \else%	curves
    \endgroup
    \multido{\n@X=0+1}{\psk@ThreeDplot@xPlotpoints}{%
      \ifPst@hiddenLine\pscustom[style=hiddenStyle]{\fi
      \@nameuse{beginplot@\psplotstyle}%
      \addto@pscode{%
        \IIIDplot@variables
        /func { #5 } def
        \ifPst@algebraic /Func (#5)  
        AlgParser 
        cvx def \fi 
        /yMin #3 def
        /y yMin def
        /y1 #4 def
        /dy y1 y sub \psk@ThreeDplot@yPlotpoints\space dup 0 gt {div}{pop} ifelse def
        /dx #2\space #1\space sub \psk@ThreeDplot@xPlotpoints\space dup 0 gt {div}{pop} ifelse def
        /x #1\space \n@X\space dx mul add def
        /xyz { 
	  x \psk@ThreeDplot@zCoor\space 0 gt { \ifPst@algebraic Func \else func \fi  }{ y } ifelse 
          \psk@ThreeDplot@zCoor\space 0 gt { \psk@ThreeDplot@zCoor }{ \ifPst@algebraic Func \else func \fi  } ifelse 
          tx@3DPlotDict begin
  	  saveCoor
	  ConvertTo2D
	  x2D \pst@number\psxunit mul y2D \pst@number\psyunit mul end } def
      }%
      \psplotThreeD@yLines@iii%
      \ifPst@hiddenLine }\fi%
    }%
  \fi
  \endgroup
  \ignorespaces%
}
\def\psplotThreeD@yLines@ii{%
  \addto@pscode{%
    xyz \@nameuse{beginqp@\psplotstyle}
    \psk@ThreeDplot@xPlotpoints\space 1 add {
      /y yMin def
      xyz moveto
      \psk@ThreeDplot@yPlotpoints\space 1 add {
        xyz \@nameuse{doqp@\psplotstyle}
        /y y dy add def
      } repeat
      /x x dx add def
    } repeat
    /x x1 def
    /y y1 def
    xyz \@nameuse{doqp@\psplotstyle}
  }%
  \@nameuse{endqp@\psplotstyle}%
}
\def\psplotThreeD@yLines@iii{%    curves
  \addto@pscode{%
    /y yMin def
    mark
    /n 2 def
    \psk@ThreeDplot@yPlotpoints {
      xyz
      n 2 roll
      /n n 2 add def
      /y y dy add def
    } repeat
    /y y1 def
    xyz
    n 2 roll
  }%
    \@nameuse{endplot@\psplotstyle}%
}
%
% parametricplot ----------------------------------------------------------------
%
\def\parametricplotThreeD{\def\pst@par{}\pst@object{parametricPlotThreeD}}
\def\parametricPlotThreeD@i(#1){%
  \@ifnextchar({\parametricPlotThreeD@ii(#1)}{\parametricPlotThreeD@ii(#1)(0,0)}%
}
\def\parametricPlotThreeD@ii(#1,#2)(#3,#4)#5{{%
  \pst@killglue%
  \use@par%
  \ifPst@CoorCheck%
    \pst@dima=#3pt\pst@dimb=#4pt          % #3=#4, then we have a 3d line
    \ifdim\pst@dima=\pst@dimb
      \def\psk@ThreeDplot@yPlotpoints{1 }\fi% and set yPlotpoints=1
  \fi%
  \@pstfalse%
  \@nameuse{beginplot@\psplotstyle}%
  \@nameuse{testqp@\psplotstyle}% quick plot or something special
  \if@pst%
    \ifPst@Debug\typeout{===>Quick plot}\fi
    \def\pslinetype{0}%
    \addto@pscode{%
      \IIIDplot@variables
      \ifPst@algebraic /Func (#5)  
      AlgParser 
      cvx def \fi 
      /tMin #1 def
      /t tMin def
      /t1 #2 def
      /u #3 def
      /u1 #4 def
      /dt t1 t sub \psk@ThreeDplot@xPlotpoints\space dup 1 gt %
        { 1 sub div }{ pop pop 0 } ifelse def % step for t
      /du u1 u sub \psk@ThreeDplot@yPlotpoints\space dup 1 gt %
        { 1 sub div }{ pop pop 0 } ifelse def % step for u
      /xyz { \ifPst@algebraic Func \else #5 \fi 
        tx@3DPlotDict begin
	saveCoor
	ConvertTo2D
	x2D \pst@number\psxunit mul y2D \pst@number\psyunit mul end } def
   }%
   \parametricPlotThreeD@iii%
  \else%
    \ifPst@Debug\typeout{===>Special plot}\fi
    \def\pslinetype{0}%
    \endgroup%
    \multido{\n@Y=0+1}{\psk@ThreeDplot@yPlotpoints}{%
      \@nameuse{beginplot@\psplotstyle}%
      \addto@pscode{%
        \IIIDplot@variables
        \ifPst@algebraic /Func (#5) 
        AlgParser 
        cvx def \fi 
        /tMin #1 def
        /t tMin def
        /t1 #2 def
	/u1 #2 def
        /dt t1 t sub \psk@ThreeDplot@xPlotpoints\space dup 1 gt %
          { 1 sub div }{ pop pop 0 } ifelse def % step for t
        /du #4\space #3\space sub \psk@ThreeDplot@yPlotpoints\space dup 1 gt %
          { 1 sub div }{ pop pop 0 } ifelse def % step for t
        /u #3\space \n@Y\space du mul add def
        /xyz { \ifPst@algebraic Func \else #5 \fi 
          tx@3DPlotDict begin
  	  saveCoor
	  ConvertTo2D
	  x2D \pst@number\psxunit mul y2D \pst@number\psyunit mul end } def
     }%
     \parametricPlotThreeD@iv%
    }%
  \fi%
}\ignorespaces}
%
\def\parametricPlotThreeD@iii{%   without arrows (quickplot)
  \addto@pscode{%
    \psk@ThreeDplot@yPlotpoints {
      /t tMin def
      xyz \@nameuse{beginqp@\psplotstyle}
      /t t dt add def
      \psk@ThreeDplot@xPlotpoints\space 1 sub {
        xyz \@nameuse{doqp@\psplotstyle}
        /t t dt add def
      } repeat
      /t t dt sub def
      /u u du add def
    } repeat
  }%
  \@nameuse{endqp@\psplotstyle}%
}
%
\def\parametricPlotThreeD@iv{%    with arrows or curve
  \addto@pscode{%
%	    /t tMin def
    mark
    /n 0 def
    \psk@ThreeDplot@xPlotpoints\space {
      xyz
      /n n 2 add def
      n 2 roll
      /t t dt add def
    } repeat
%    /t t1 def
%    /u u1 def
%    xyz
%    n 2 roll
  }%
  \@nameuse{endplot@\psplotstyle}%
}
%
%------------------------ Plot 3D data --------------------------
%
\def\fileplotThreeD{\def\pst@par{}\pst@object{fileplotThreeD}}
\def\fileplotThreeD@i#1{%
    \pst@killglue%
    \begingroup%
	\use@par%
	\@pstfalse%
	\@nameuse{testqp@\psplotstyle}%%
	\if@pst
	    \dataplotThreeD@ii{\pst@readfile{#1}}%
	\else
	    \listplotThreeD@ii{\pst@altreadfile{#1}}%
	\fi
    \endgroup%
    \ignorespaces%
}
%
% dataplot
%
\def\dataplotThreeD{\def\pst@par{}\pst@object{dataplotThreeD}}
\def\dataplotThreeD@i#1{%
  \pst@killglue
  \begingroup
    \use@par
    \@pstfalse
    \@nameuse{testqp@\psplotstyle}%
    \if@pst
      \dataplotThreeD@ii{\addto@pscode{#1}}%
    \else
      \listplot@ii{\addto@pscode{#1}}%
    \fi
  \endgroup
  \ignorespaces%
}
\def\dataplotThreeD@ii#1{%
  \@nameuse{beginplot@\psplotstyle}%
    \addto@pscode{%
      \IIIDplot@variables
      /Dx { /D { Dy } def } def
      /Dy { /D { Dz } def } def
      /Dz { 			% now we have x y z
        tx@3DPlotDict begin
	saveCoor
	ConvertTo2D
	x2D \pst@number\psxunit mul y2D \pst@number\psyunit mul 
	end
	Do /D { Dx } def } def
      /D { /D { Dx } def } def
      /Do {
        \@nameuse{beginqp@\psplotstyle}%
        /Do { \@nameuse{doqp@\psplotstyle}} def
      } def}%
    #1%
    \addto@pscode{D}%
  \@nameuse{endqp@\psplotstyle}%
}
%
%
\pst@def{ScalePointsThreeD}<%
  counttomark dup dup cvi eq not { exch pop } if
  /m exch def /n m 3 div cvi def
  n { 				% now we have x y z
    tx@3DPlotDict begin
    saveCoor
    ConvertTo2D
    x2D \pst@number\psxunit mul y2D \pst@number\psyunit mul 
    end
    m 1 sub 1 roll m 1 sub 1 roll /m m 3 sub def } repeat>
%
% listplotThreeD
%
\def\listplotThreeD{\def\pst@par{}\pst@object{listplotThreeD}}
\def\listplotThreeD@i#1{\listplotThreeD@ii{\addto@pscode{#1}}}
\def\listplotThreeD@ii#1{%
  \@nameuse{beginplot@\psplotstyle}%
  \addto@pscode{ \IIIDplot@variables  /D {} def mark }%
  #1%
  \addto@pscode{\tx@ScalePointsThreeD}%
  \@nameuse{endplot@\psplotstyle}%
}
%
% adopted from pst-3d
%
\pst@def{TMSave}<%
  tx@Dict /TMatrix known not { /TMatrix { } def /RAngle { 0 } def } if
  /TMatrix [ TMatrix CM ] cvx def>
%
\pst@def{TMRestore}<%
  CP /TMatrix [ TMatrix setmatrix ] cvx def moveto>
%
\pst@def{TMChange}<%
  \tx@TMSave
  /cp [ currentpoint ] cvx def
  CM
  CP T \tx@STV
  CM matrix invertmatrix 
  matrix concatmatrix
  exch exec
  concat cp moveto>
%
\def\pstPlanePut{\@ifnextchar[{\pst@PlanePut}{\pst@PlanePut[]}}
\def\pst@PlanePut[#1](#2)#3{{%
  \pst@killglue%
  \psset{pOrigin=lB}%
  \psset{#1}%
  \pstThreeDPut[#1](#2){\ps@Plane{#3}}%
}}
%
\def\ps@Plane{\pst@makebox{\psPlane@}}
\def\psPlane@{%
  \begingroup
  \leavevmode
  \hbox{%
%	    \kern\wd\pst@hbox%
    \pst@Verb{%
      { [ 1 0
        \IIIDplot@variables
%
% ###  begin Torsten Suhling
% ------------------------------------------------------------------------
% ===================================================================
% How should 'Alpha' be for planes, if real Alpha and Beta are:
% Alpha	Beta	xy 	    xy (par. y-axis)  yz	  xz
% -------------------------------------------------------------------
% 75	> 0[1]	180 + Alpha 	90 +  Alpha  Alpha	  Alpha + 180 		
% 165	> 0	Alpha 		90 +  Alpha  Alpha	  Alpha 
% 255	> 0	Alpha		270 + Alpha  Alpha + 180  Alpha
% 345	> 0	180 + Alpha 	270 + Alpha  Alpha + 180  Alpha + 180 
% -------------------------------------------------------------------
% 75	< 0	180 - Alpha 	270 - Alpha  Alpha  	  Alpha + 180  
% 165	< 0	-Alpha 		270 - Alpha  Alpha  	  Alpha
%
% 255	< 0	-Alpha 		90 -  Alpha  Alpha + 180  Alpha
%
% 345	< 0	180 -Alpha 	90 -  Alpha  Alpha + 180  Alpha + 180 
% ------------------------------------------------------------------
% How should 'Beta' be for planes, if real Alpha and Beta are:
% Alpha	Beta	xy 	      xy (par. y-axis)	yz		xz
% -------------------------------------------------------------------
% 75 	> 0 	Beta 		Beta 		Beta[2] 	Beta 
% 165	> 0 	Beta 		Beta 		Beta 		Beta 
% 255	> 0 	Beta 		Beta 		Beta 		Beta 
% 345	> 0 	Beta 		Beta 		Beta 		Beta 
% ...................................................................
% 75 	< 0 	-Beta 		-Beta 		Beta 		Beta 
% 165	< 0 	-Beta 		-Beta 		Beta 		Beta 
% 255	< 0 	-Beta 		-Beta 		Beta 		Beta 
% 345	< 0 	-Beta 		-Beta 		Beta 		Beta 
% ================================================================
        \ifx\psk@ThreeDplot@planecorr\ThreeDplot@planecorrNone
		/SignFlag 	1 def
		/AlphaOffset 0 \psk@IIIDdAlpha add def
	\else%
          \ifx\psk@ThreeDplot@plane\ThreeDplot@planeXY 			% XY-layer's tag
            \ifx\psk@ThreeDplot@planecorr\ThreeDplot@planecorrXYrot 	% Tag written parallel y-axis
	        Beta  sin 0 lt {/SignFlag  -1}{/SignFlag    1}ifelse def
                Alpha sin 0 gt {/AlphaOffset 180 -90 SignFlag mul add}
		               {/AlphaOffset 180  90 SignFlag mul add} ifelse def 
	    \else% 							% Normal (par. x-axis)
	        Beta  sin 0 gt {/SignFlag      1}{/SignFlag     -1}ifelse def
	        Alpha cos 0 gt {/AlphaOffset 180}{/AlphaOffset   0}ifelse def
	    \fi%
	  \else 							% Vertical layers 
            \ifx\psk@ThreeDplot@plane\ThreeDplot@planeYZ 		% YZ-layer's tag 
		/SignFlag 1 def 
	        Alpha sin 0 gt {/AlphaOffset   0}{/AlphaOffset 180}ifelse def
	    \else% 							% XZ-layer's tag 
		/SignFlag 1 def 
	        Alpha cos 0 gt {/AlphaOffset 180}{/AlphaOffset   0}ifelse def
	    \fi% which vert. layer's tag 
	  \fi% vert. or xy-layer's tag 
	\fi% planecorr or not 
% ------------------------------------------------------------------ Ende
% ------------------------------------------------------------------------
% ###   Aenderung --> es werden die Operatoren SignFlag und AlphaOffset
%	eingefuegt
% ------------------------------------------------------------------------
%       /Delta Beta sin Alpha sin mul Alpha cos atan neg 90 add def 
%       /Gamma Beta sin Alpha cos mul neg Alpha sin atan def 
% ------------------------------------------------------------------------
        /Delta Beta SignFlag mul sin Alpha SignFlag mul AlphaOffset add sin mul Alpha SignFlag mul AlphaOffset add cos atan neg 90 add def 
        /Gamma Beta SignFlag mul sin Alpha SignFlag mul AlphaOffset add cos mul neg Alpha SignFlag mul AlphaOffset add sin atan def 
% ------------------------------------------------------------------- Ende
        \ifx\psk@ThreeDplot@plane\ThreeDplot@planeXY
          270 Delta sub rotate
          /Rho 90 Gamma add Delta add def
        \else
          \ifx\psk@ThreeDplot@plane\ThreeDplot@planeXZ
            270 Delta sub rotate
            /Rho 180 Delta add def
          \else
            Gamma rotate
            /Rho 90 Gamma sub def
          \fi
        \fi
        Rho cos Rho sin 0 0 ] concat} \tx@TMChange
    }%
    \box\pst@hbox
    \pst@Verb{\tx@TMRestore}%
%	    \kern\ht\pst@hbox%
  }%
  \endgroup%
}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Utility stuff
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\iffalse
% posStart=Starting point
% length=  Arrow length.
\def\Arrows{\@ifnextchar[{\pst@Arrows}{\pst@Arrows[]}}
\def\pst@Arrows[#1](#2)(#3){{%
	\psset{#1}%
	\pst@getcoor{#2}\pst@tempa
	\pst@getcoor{#3}\pst@tempb
	\pnode(!%
		/StartArrow \psk@ThreeDplot@posStart\space def
		/LengthArrow \psk@ThreeDplot@length\space def
		\pst@tempa /YA exch \pst@number\psyunit div def
		/XA exch \pst@number\psxunit div def
		\pst@tempb /YB exch \pst@number\psyunit div def
		/XB exch \pst@number\psxunit div def
		/denominateur XB XA sub def
		/numerateur YB YA sub def
		/angleDirectionAB numerateur denominateur Atan def
		/XD StartArrow angleDirectionAB cos mul XA add def
		/YD StartArrow angleDirectionAB sin mul YA add def
		/XF XD LengthArrow angleDirectionAB cos mul add def
		/YF YD LengthArrow angleDirectionAB sin mul add def
		XD YD ){ArrowStart}
	\pnode(! XF YF){ArrowEnd}
	\psset{arrows=->}%
	\psline[#1](ArrowStart)(ArrowEnd)%
}\ignorespaces}
%
% draw a line (===) outside: #2-----#3=======#4
%
\def\psOutLine{\@ifnextchar[{\pst@ToDrawOut}{\pst@ToDrawOut[]}}
\def\pst@ToDrawOut[#1](#2)(#3)#4{{%
	\psset{#1}%
	\pst@getcoor{#2}\pst@tempa
	\pst@getcoor{#3}\pst@tempb
	\pnode(!%
		/LengthArrow \psk@ThreeDplot@length\space def
		\pst@tempa /YA exch \pst@number\psyunit div def
		/XA exch \pst@number\psxunit div def
		\pst@tempb /YB exch \pst@number\psyunit div def
		/XB exch \pst@number\psxunit div def
		/denominateur XB XA sub def
		/numerateur YB YA sub def
		/angleDirectionAB numerateur denominateur Atan def
		/Xend XB LengthArrow angleDirectionAB cos mul add def
		/Yend YB LengthArrow angleDirectionAB sin mul add def
		Xend Yend){#4}
	\psline[#1](#3)(#4)
}\ignorespaces}
%
% draw a line (===) before: #4========#2-----#3
%
\def\psBeforeLine{\@ifnextchar[{\pst@BeforeLine}{\pst@BeforeLine[]}}
\def\pst@BeforeLine[#1](#2)(#3)#4{{%
	\psset{#1}%
	\pst@getcoor{#2}\pst@tempa
	\pst@getcoor{#3}\pst@tempb
	\pnode(!%
		/LengthArrow \psk@ThreeDplot@length\space def
		\pst@tempa /YA exch \pst@number\psyunit div def
		/XA exch \pst@number\psxunit div def
		\pst@tempb /YB exch \pst@number\psyunit div def
		/XB exch \pst@number\psxunit div def
		/denominateur XB XA sub def
		/numerateur YB YA sub def
		/angleDirectionAB numerateur denominateur Atan def
		/Xstart XA LengthArrow angleDirectionAB cos mul sub def
		/Ystart YA LengthArrow angleDirectionAB sin mul sub def
		Xstart Ystart){#4}
	\psline[#1](#4)(#2)%
}\ignorespaces}
%
% intersection de deux droites
% 2 juillet 2001/ rewritten 2003-01-27 Herbert
%
\def\ABinterCD(#1)(#2)(#3)(#4)#5{%
    \pst@getcoor{#1}\pst@tempa
    \pst@getcoor{#2}\pst@tempb
    \pst@getcoor{#3}\pst@tempc
    \pst@getcoor{#4}\pst@tempd
\pnode(!%
    /YA \pst@tempa exch pop \pst@number\psyunit div def
    /XA \pst@tempa pop \pst@number\psxunit div def
    /YB \pst@tempb exch pop \pst@number\psyunit div def
    /XB \pst@tempb pop \pst@number\psxunit div def
    /YC \pst@tempc exch pop \pst@number\psyunit div def
    /XC \pst@tempc pop \pst@number\psxunit div def
    /YD \pst@tempd exch pop \pst@number\psyunit div def
    /XD \pst@tempd pop \pst@number\psxunit div def
    /dY1 YB YA sub def
    /dX1 XB XA sub def
    /dY2 YD YC sub def
    /dX2 XD XC sub def
    dX1 abs 0.01 lt {
	/m2 dY2 dX2 div def
	XA dup XC sub m2 mul YC add 
    }{
	dX2 abs 0.01 lt {
	    /m1 dY1 dX1 div def
	    XC dup XA sub m1 mul YA add 
	}{%
	    /m1 dY1 dX1 div def
	    /m2 dY2 dX2 div def
	    m1 XA mul m2 XC mul sub YA sub YC add m1 m2 sub div dup
	    XA sub m1 mul YA add 
	} ifelse
    } ifelse ){#5}
}
%
% draw a parallel line
%     #2---------#3
%         #4----------#5(new)  
\def\Parallel{\@ifnextchar[{\pst@Parallel}{\pst@Parallel[]}}
\def\pst@Parallel[#1](#2)(#3)(#4)#5{{%
	\psset{#1}%
	\pst@getcoor{#2}\pst@tempa
	\pst@getcoor{#3}\pst@tempb
	\pst@getcoor{#4}\pst@tempc
	\pnode(!%
		/LengthArrow \psk@ThreeDplot@length\space def
		\pst@tempa /YA exch \pst@number\psyunit div def
		/XA exch \pst@number\psxunit div def
		\pst@tempb /YB exch \pst@number\psyunit div def
		/XB exch \pst@number\psxunit div def
		\pst@tempc /YC exch \pst@number\psyunit div def
		/XC exch \pst@number\psxunit div def
		/denominateur XB XA sub def
		/numerateur YB YA sub def
		/angleDirectionAB numerateur denominateur Atan def
		/XstartParallel XC LengthArrow angleDirectionAB cos mul add def
		/YstartParallel YC LengthArrow angleDirectionAB sin mul add def
		XstartParallel YstartParallel){#5}
	\psline[#1](#4)(#5)
}\ignorespaces}
%
% arrowLine[options](A)(B){n}
% #2---->---->---->---->----#3  #4-arrows inside
\def\arrowLine{\@ifnextchar[{\pst@arrowLine}{\pst@arrowLine[]}}
\def\pst@arrowLine[#1](#2)(#3)#4{{%
  \psset{arrowsize=4pt,arrows=->}% the defaults
  \psset{#1}%
  \def\pst@ThreeDplot@n{#4}%
  \pst@getcoor{#2}\pst@tempa
  \pst@getcoor{#3}\pst@tempb
  \pnode(!%
    /YA \pst@tempa exch pop \pst@number\psyunit div def
    /XA \pst@tempa pop \pst@number\psxunit div def
    /YB \pst@tempb exch pop \pst@number\psyunit div def
    /XB \pst@tempb pop \pst@number\psxunit div def
    /dY YB YA sub \pst@ThreeDplot@n\space 1 add div def
    /dX XB XA sub \pst@ThreeDplot@n\space 1 add div def
    /Alpha dY dX atan def
    /dYOffset \psk@ThreeDplot@arrowOffset\space Alpha sin mul def
    /dXOffset \psk@ThreeDplot@arrowOffset\space Alpha cos mul def
    XA YA ){tempArrowC}
  \multido{\i=1+1}{#4}{%
    \pnode(!%
      XA dX \i\space mul add dXOffset add
      YA dY \i\space mul add dYOffset add ){tempArrowB}
    \psline(tempArrowC)(tempArrowB)
    \pnode(tempArrowB){tempArrowC}
  }
  \psline[arrows=-](tempArrowB)(#3)
}\ignorespaces}
%
%   #1------#3------#2
\def\nodeBetween(#1)(#2)#3{%    Herbert 2003/01/05
  \pst@getcoor{#1}\pst@tempa
  \pst@getcoor{#2}\pst@tempb
  \pnode(!%
    /XA \pst@tempa pop \pst@number\psxunit div def
    /YA \pst@tempa exch pop \pst@number\psyunit div def
    /XB \pst@tempb pop \pst@number\psxunit div def
    /YB \pst@tempb exch pop \pst@number\psyunit div def
    XB XA add 2 div YB YA add 2 div){#3}
}
\fi%--------------------------------------------------------
%
% rotateNode(A)
% (A) the node
% #2  the angle
% Herbert Voss <voss@perce.de> 2003-01-26
\def\rotateNode{\pst@rotateNode}
\def\pst@rotateNode(#1)#2{{%
    \pst@getcoor{#1}\pst@tempa%
    \def\pst@ThreeDplot@angle{#2}%        the rotating angle
    \pnode(!%
    	/YA \pst@tempa exch pop \pst@number\psyunit div def
	/XA \pst@tempa pop \pst@number\psxunit div def
	YA 0 eq XA 0 eq and {0 0}{
	    /r XA dup mul YA dup mul add sqrt def
	    /AlphaOld YA XA atan def
	    /AlphaNew AlphaOld \pst@ThreeDplot@angle\space add def
	    r AlphaNew cos mul r AlphaNew sin mul
	} ifelse ){temp}%
    \pnode(temp){#1}%
}\ignorespaces}
%
\def\rotateTriangle{\pst@rotateTriangle}
\def\pst@rotateTriangle(#1)(#2)(#3)#4{{%
    \rotateNode(#1){#4}%
    \rotateNode(#2){#4}%
    \rotateNode(#3){#4}%
}\ignorespaces}
%
\def\rotateFrame{\pst@rotateFrame}
\def\pst@rotateFrame(#1)(#2)(#3)(#4)#5{{%
    \rotateNode(#1){#5}%
    \rotateNode(#2){#5}%
    \rotateNode(#3){#5}%
    \rotateNode(#4){#5}%
}\ignorespaces}
%
% An add macro for integer values
% \pstAdd{34}{6}\value ==> \value is 30
%
\def\pstAdd#1#2#3{%
  \begingroup%
  \pst@dima=#1pt
  \advance\pst@dima by #2pt
  \edef\pst@value{\endgroup\def\noexpand#3{\pst@number\pst@dima}}\pst@value%
}
\def\pstSub#1#2#3{%
  \begingroup%
  \pst@dima=#1pt\relax
  \pst@dimb=#2pt\relax
  \advance\pst@dima by -\pst@dimb
  \edef\pst@value{\endgroup%
  \def\noexpand#3{\pst@number\pst@dima}}\pst@value%
}
% An mul macro for real values
% \pstmul{2.5}{1,5}\value ==> \value is 6.25
%
\def\pstMul#1#2#3{%
  \begingroup%
  \pst@dima=#1pt\relax
  \pst@dimb=#2\pst@dima\relax
  \edef\pst@value{\endgroup
  \def\noexpand#3{\pst@number\pst@dimb}}\pst@value%
}
%
\let\pstDiv\pst@divide
%
\chardef\nin@ty=90% stolen from the trig.sty package by David Carlisle
\chardef\@clxx=180
\chardef\@lxxi=71
\mathchardef\@mmmmlxviii=4068
\chardef\@coeffz=72
\chardef\@coefb=42
\mathchardef\@coefc=840
\mathchardef\@coefd=5040
{\catcode`t=12\catcode`p=12\gdef\noPT#1pt{#1}}
\def\TG@rem@pt#1{\expandafter\noPT\the#1\space}
\def\TG@term#1{%
 \dimen@\@tempb\dimen@
 \advance\dimen@ #1\p@}
\def\TG@series{%
  \dimen@\@lxxi\dimen@
  \divide \dimen@ \@mmmmlxviii
  \edef\@tempa{\TG@rem@pt\dimen@}%
  \dimen@\@tempa\dimen@
  \edef\@tempb{\TG@rem@pt\dimen@}%
  \divide\dimen@\@coeffz
  \advance\dimen@\m@ne\p@
  \TG@term\@coefb
  \TG@term{-\@coefc}%
  \TG@term\@coefd
  \dimen@\@tempa\dimen@
  \divide\dimen@ \@coefd}
\def\CalculateSin#1{{%
  \expandafter\ifx\csname sin(\number#1)\endcsname\relax
    \dimen@=#1\p@\TG@@sin
    \expandafter\xdef\csname sin(\number#1)\endcsname
                                    {\TG@rem@pt\dimen@}%
  \fi}}
\def\CalculateCos#1{{%
  \expandafter\ifx\csname cos(\number#1)\endcsname\relax
    \dimen@=\nin@ty\p@
    \advance\dimen@-#1\p@
    \TG@@sin
    \expandafter\xdef\csname cos(\number#1)\endcsname
                                     {\TG@rem@pt\dimen@}%
  \fi}}
\def\TG@reduce#1#2{%
\dimen@#1#2\nin@ty\p@
  \advance\dimen@#2-\@clxx\p@
  \dimen@-\dimen@
  \TG@@sin}
\def\TG@@sin{%
  \ifdim\TG@reduce>+%
  \else\ifdim\TG@reduce<-%
  \else\TG@series\fi\fi}%
\def\UseSin#1{\csname sin(\number#1)\endcsname}
\def\UseCos#1{\csname cos(\number#1)\endcsname}
\chardef\z@num\z@
\expandafter\let\csname sin(0)\endcsname\z@num
\expandafter\let\csname cos(0)\endcsname\@ne
\expandafter\let\csname sin(90)\endcsname\@ne
\expandafter\let\csname cos(90)\endcsname\z@num
\expandafter\let\csname sin(-90)\endcsname\m@ne
\expandafter\let\csname cos(-90)\endcsname\z@num
\expandafter\let\csname sin(180)\endcsname\z@num
\expandafter\let\csname cos(180)\endcsname\m@ne

% A macro for sin cos values
% \pstSinCos{30}\SinVal\CosVal ==> \SinVal 0.5 \CosVal 0.86
 %
\def\pstSinCos#1#2#3{%
%\begingroup%
%  \pst@getsinandcos{#1}
%  \edef\pst@values{\endgroup%
%    \def\noexpand#2{\ifcase\pst@quadrant\or\or-\or-\fi\pst@sin}%
%    \def\noexpand#3{\ifcase\pst@quadrant\or-\or-\or\fi\pst@cos}}\pst@values%
  \CalculateSin#1
  \CalculateCos#1
  \edef#2{\UseSin#1}%
  \edef#3{\UseCos#1}%
}
%
\def\pstRotPointIIID{\def\pst@par{}\pst@object{RotPointIIID}}% A real TeX solution
\def\RotPointIIID@i(#1,#2,#3)#4#5#6{%
  \pst@killglue%
  \begingroup%
  \use@par%
% x- axis
  \pstSinCos{\psk@ThreeD@RotX}\pst@sinTheta\pst@cosTheta
  \def\pst@xVala{#1}
  \pstMul{#2}{\pst@cosTheta}\pst@tempA
  \pstMul{#3}{\pst@sinTheta}\pst@tempB
  \pstSub{\pst@tempA}{\pst@tempB}\pst@yVala
  \pstMul{#2}{\pst@sinTheta}\pst@tempA
  \pstMul{#3}{\pst@cosTheta}\pst@tempB
  \pstAdd{\pst@tempA}{\pst@tempB}\pst@zVala
% y- axis
  \pstSinCos{\psk@ThreeD@RotY}\pst@sinTheta\pst@cosTheta
  \pstMul{\pst@xVala}{\pst@cosTheta}\pst@tempA
  \pstMul{\pst@zVala}{\pst@sinTheta}\pst@tempB
  \pstAdd{\pst@tempA}{\pst@tempB}\pst@xValb
  \let\pst@yValb\pst@yVala
  \pstMul{\pst@xVala}{\pst@sinTheta}\pst@tempA
  \pstMul{\pst@zVala}{\pst@cosTheta}\pst@tempB
  \pstSub{\pst@tempB}{\pst@tempA}\pst@zValb
% z- axis
  \pstSinCos{\psk@ThreeD@RotZ}\pst@sinTheta\pst@cosTheta
  \pstMul{\pst@xValb}{\pst@cosTheta}\pst@tempA
  \pstMul{\pst@yValb}{\pst@sinTheta}\pst@tempB
  \pstSub{\pst@tempA}{\pst@tempB}\pst@xValc
  \pstMul{\pst@xValb}{\pst@sinTheta}\pst@tempA
  \pstMul{\pst@yValb}{\pst@cosTheta}\pst@tempB
  \pstAdd{\pst@tempA}{\pst@tempB}\pst@yValc
  \let\pst@zValc\pst@zValb
  %  
  \edef\pst@values{\endgroup%
    \def\noexpand#4{\pst@xValc}%
    \def\noexpand#5{\pst@yValc}%
    \def\noexpand#6{\pst@zValc}}\pst@values%
  \ignorespaces%
}
%
\define@key[psset]{pst-3dplot}{stepFactor}[0.67]{\pst@checknum{#1}\psk@stepFactor }
\psset[pst-3dplot]{stepFactor=0.67}
%
\newdimen\pszunit \pszunit 1cm
%
\def\psplotImpIIID{\pst@object{psplotImpIIID}}% 20060420
\def\psplotImpIIID@i(#1,#2,#3)(#4,#5,#6){%
  \@ifnextchar[{\psplotImpIIID@ii(#1,#2,#3)(#4,#5,#6)}{\psplotImpIIID@ii(#1,#2,#3)(#4,#5,#6)[]}}
\def\psplotImpIIID@ii(#1,#2,#3)(#4,#5,#6)[#7]#8{%
  \begin@OpenObj%
  \addto@pscode{
    /xMin #1 def
    /xMax #4 def
    /yMin #2 def
    /yMax #5 def
    /zMin #3 def
    /zMax #6 def
    \IIIDplot@variables
    #7 % additional PS code
    /Func \ifPst@algebraic (#8) AlgParser cvx \else { #8 } \fi  def
    /xPixel xMax xMin sub \pst@number\psxunit mul round cvi def
    /yPixel yMax yMin sub \pst@number\psyunit mul round cvi def
    /zPixel zMax zMin sub \pst@number\pszunit mul round cvi def
    /dx xMax xMin sub xPixel div def
    /dy yMax yMin sub yPixel div def
    /dz zMax zMin sub zPixel div def
    /setpixel { 
      dz div 3 1 roll
      dy div 3 1 roll
      dx div 3 1 roll
      tx@3DPlotDict begin Conv3D2D end 
      \pst@number\pslinewidth 2 div 0 360 arc fill } bind def
%
    /VZ true def % suppose that F(x,y,z)>=0
    /x xMin def /y yMin def /z zMin def
    Func 0.0 lt { /VZ false def } if % erster Wert
    xMin dx \psk@stepFactor\space mul xMax {
      /x exch def
      yMin dy \psk@stepFactor\space mul yMax {
	/y exch def
        zMin dz \psk@stepFactor\space mul zMax {
  	  /z exch def
	  Func 0 lt 
	    { VZ { x y z setpixel /VZ false def} if }
	    { VZ {}{ x y z setpixel /VZ true def } ifelse } ifelse
	} for
      } for
    } for
%
    /x xMin def /y yMin def /z zMin def
    Func 0.0 lt { /VZ false def } if % erster Wert
    zMin dz \psk@stepFactor\space mul zMax {
      /z exch def
      yMin dy \psk@stepFactor\space mul yMax {
        /y exch def
        xMin dx \psk@stepFactor\space mul xMax {
	  /x exch def
	    Func 0 lt 
	      { VZ { x y z setpixel /VZ false def} if }
	      { VZ {}{ x y z setpixel /VZ true def } ifelse } ifelse
	} for
      } for
    } for
  }%
  \end@OpenObj%
}
%
\catcode`\@=\PstAtCode\relax
%
%% END: pst-3dplot.tex
\endinput

