Retour

pst-V3D.tex

Télécharger le fichier
%%
%% This is file `pst-V3D.tex',
%%
%% IMPORTANT NOTICE:
%%
%% Package `pst-V3D.tex'
%%
%% Manuel Luque <mluque5130@aol.com>
%%
%% 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-V3D' is a PSTricks package to draw  graphical objects
%%
\csname PSTVIIIDLoaded\endcsname
\let\PSTVIIILoaded\endinput
% Requires PSTricks, pst-node, pst-plot, multido packages
\ifx\PSTricksLoaded\endinput\else\input pstricks.tex\fi
\ifx\PSTnodesLoaded\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{0.3}
\def\filedate{2006/08/18}
\message{`PST-V3D' v\fileversion, \filedate}
%
\edef\PstAtCode{\the\catcode`\@} \catcode`\@=11\relax
\pst@addfams{pst-V3D}
\SpecialCoor
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
\newif\ifPst@visibility%
\define@key[psset]{pst-V3D}{visibility}[true]{\@nameuse{Pst@visibility#1}}
\psset[pst-V3D]{visibility=true}
%
\newif\ifPst@arete%
\define@key[psset]{pst-V3D}{arete}[true]{\@nameuse{Pst@arete#1}}
\psset[pst-V3D]{arete=true}
 
\newif\ifPst@interior%
\define@key[psset]{pst-V3D}{interior}[false]{\@nameuse{Pst@interior#1}}
\psset[pst-V3D]{interior=false}
 
\newif\ifPst@todraw%
\define@key[psset]{pst-V3D}{todraw}[true]{\@nameuse{Pst@todraw#1}}
\psset[pst-V3D]{todraw=true}
 
\newif\ifPst@nocolor%
\define@key[psset]{pst-V3D}{nocolor}[false]{\@nameuse{Pst@nocolor#1}}
\psset[pst-V3D]{nocolor=false}
%
\define@key[psset]{pst-V3D}{THETA}{\def\pst@VIIID@THETA{#1}} % longitude
\define@key[psset]{pst-V3D}{PHI}{\def\pst@VIIID@PHI{#1}}  % latitude
\define@key[psset]{pst-V3D}{Dobs}{\def\pst@VIIID@Dobs{#1}} % distance observateur
\define@key[psset]{pst-V3D}{Decran}{\def\pst@VIIID@Decran{#1}} % distance de l'écran
\define@key[psset]{pst-V3D}{xO}{\def\pst@VIIID@xO{#1}} % origine du texte
\define@key[psset]{pst-V3D}{yO}{\def\pst@VIIID@yO{#1}}
\define@key[psset]{pst-V3D}{RotX}{\def\psk@IIID@RotX{#1}} % rotation autour de Ox en degrés
\define@key[psset]{pst-V3D}{RotY}{\def\psk@IIID@RotY{#1}} % rotation autour de Oy en degrés
\define@key[psset]{pst-V3D}{RotZ}{\def\psk@IIID@RotZ{#1}} % rotation autour de Oz en degrés
\define@key[psset]{pst-V3D}{translation}{\def\psk@IIID@translation{#1}} % vecteur translation
\define@key[psset]{pst-V3D}{ColorFace1}{\def\psk@IIID@ColorFaceOne{#1}} % couleur de la face 1 du cube ou octaedre
\define@key[psset]{pst-V3D}{ColorFace2}{\def\psk@IIID@ColorFaceTwo{#1}} % couleur de la face 2 du cube ou octaedre
\define@key[psset]{pst-V3D}{ColorFace3}{\def\psk@IIID@ColorFaceThree{#1}} % couleur de la face 3 du cube ou octaedre
\define@key[psset]{pst-V3D}{ColorFace4}{\def\psk@IIID@ColorFaceFour{#1}} % couleur de la face 4 du cube ou octaedre
\define@key[psset]{pst-V3D}{ColorFace5}{\def\psk@IIID@ColorFaceFive{#1}} % couleur de la face 5 du cube ou octaedre
\define@key[psset]{pst-V3D}{ColorFace6}{\def\psk@IIID@ColorFaceSix{#1}} % couleur de la face 6 du cube ou octaedre
\define@key[psset]{pst-V3D}{ColorFace7}{\def\psk@IIID@ColorFaceSeven{#1}} % couleur de la face 6 du cube ou octaedre
\define@key[psset]{pst-V3D}{ColorFace8}{\def\psk@IIID@ColorFaceEight{#1}} % couleur de la face 6 du cube ou octaedre
\define@key[psset]{pst-V3D}{ColorFacette}{\def\psk@IIID@ColorFacette{#1}} % couleur de la face 6 du cube ou octaedre
\psset[pst-V3D]{ColorFace1= 1 1 0 ,
                ColorFace2= 0.9 0.9 0 ,
                ColorFace3= 0.8 0.8 0 ,
                ColorFace4= 0.7 0.7 0 ,
                ColorFace5= 0.6 0.6 0 ,
                ColorFace6= 0.5 0.5 0 ,
                ColorFace7= 0.4 0.4 0 ,
                ColorFace8= 0.3 0.3 0 ,
                ColorFacette=1 0.2 0.2}
 
% choix de la police et de la taille des caractères en cm !!
\define@key[psset]{pst-V3D}{PSfont}{\def\psk@PSfont{/#1 }}
\define@key[psset]{pst-V3D}{fontscale}{\def\psk@fontscale{#1 }}
\define@key[psset]{pst-V3D}{xlabelsep}{\def\psk@xlabelsep{#1 }}
\define@key[psset]{pst-V3D}{ylabelsep}{\def\psk@ylabelsep{#1 }}
\psset[pst-V3D]{PSfont=Times-Roman,fontscale=1,xlabelsep=-0.5,ylabelsep=-0.5}
%
 
\define@key[psset]{pst-V3D}{normale}{\def\psk@normale{#1}}
\psset[pst-V3D]{normale=30 45}
 
\psset[pst-V3D]{RotZ=0,RotX=0,RotY=0,translation=0 0 0 ,%
                THETA=70,PHI=30,Dobs=50,Decran=50,xO=0,yO=0}%
%
\define@key[psset]{pst-V3D}{origine}{\def\pst@VIIID@origine{#1}} % origine du plan
 
\psset[pst-V3D]{origine=0 0 0 }%
 
% teinte de l'objet
\define@key[psset]{pst-V3D}{hsbcolor}{\def\pst@VIIID@hsbcolor{#1}} % couleur H et B de (H S B)
% source de la lumière
\define@key[psset]{pst-V3D}{thetaLight}{\def\pst@VIIID@thetaLight{#1}} % longitude
\define@key[psset]{pst-V3D}{phiLight}{\def\pst@VIIID@phiLight{#1}}  % latitude
\define@key[psset]{pst-V3D}{dLight}{\def\pst@VIIID@dLight{#1}} % distance source
 
\psset[pst-V3D]{thetaLight=70,phiLight=30,dLight=10000,hsbcolor=0.17 0.5}%
 
%
%\pstheader{pst-V3D.pro}
%
\pst@def{parametresIIID}<%
%% Caractères accentués
/ReEncode { exch findfont
dup length dict begin { 1 index /FID eq {pop pop} {def} ifelse
}forall
/Encoding ISOLatin1Encoding def
currentdict end definefont
pop }bind def
/Font \psk@PSfont\space /ISOfont ReEncode /ISOfont def
% transformer pts -> cm
/cm {\pst@number\psunit mul} def
/cm_1 {\pst@number\psunit div} def
% le point de vue
/THETA \pst@VIIID@THETA\space def
/PHI \pst@VIIID@PHI\space def
/Dobs \pst@VIIID@Dobs\space def % distance observateur
/Decran \pst@VIIID@Decran\space def % distance de l'écran
/x0 \pst@VIIID@xO\space def % pour positionner le texte
/y0 \pst@VIIID@yO\space def %
/xLabelSep \psk@xlabelsep\space cm def
/yLabelSep \psk@ylabelsep\space cm def
/ColorFace1 {\psk@IIID@ColorFaceOne} def
/ColorFace2 {\psk@IIID@ColorFaceTwo} def
/ColorFace3 {\psk@IIID@ColorFaceThree} def
/ColorFace4 {\psk@IIID@ColorFaceFive} def
/ColorFace5 {\psk@IIID@ColorFaceFour} def
/ColorFace6 {\psk@IIID@ColorFaceSix} def
/ColorFace7 {\psk@IIID@ColorFaceSeven} def
/ColorFace8 {\psk@IIID@ColorFaceEight} def
/ColorFacette {\psk@IIID@ColorFacette} def
\ifPst@arete
/Trace_arete {facette
 1 setlinewidth
 0 setgray
stroke } def \else
/Trace_arete { null} def \fi
/xLight {\pst@VIIID@thetaLight\space cos
         \pst@VIIID@phiLight\space cos mul
         \pst@VIIID@dLight\space mul} bind def
/yLight {\pst@VIIID@thetaLight\space sin
         \pst@VIIID@phiLight\space cos mul
         \pst@VIIID@dLight\space mul} bind def
/zLight {\pst@VIIID@phiLight\space sin
         \pst@VIIID@dLight\space mul} bind def
/H_S {\pst@VIIID@hsbcolor} def
\ifPst@todraw /toDraw {facette 0 setgray stroke} def \else /toDraw { } def\fi
\ifPst@nocolor /nocolor {1 setgray fill} def \else /nocolor {H_S CosCouleur sethsbcolor fill } def\fi
\ifPst@visibility /condition { PSfacette 0 gt } def \else /condition { PSfacette 0 le} def \fi
%% calcul des coefficients de la matrice
%% de transformation
/Sin1 {THETA sin} bind def
/Sin2 {PHI sin} bind def
/Cos1 {THETA cos} bind def
/Cos2 {PHI cos} bind def
/Cos1Sin2 {Cos1 Sin2 mul} bind def
/Sin1Sin2 {Sin1 Sin2 mul} bind def
/Cos1Cos2 {Cos1 Cos2 mul} bind def
/Sin1Cos2 {Sin1 Cos2 mul} bind def
%
/XpointVue {Dobs Cos1Cos2 mul} bind def
/YpointVue {Dobs Sin1Cos2 mul} bind def
/ZpointVue {Dobs Sin2 mul} bind def
/3dto2d {
6 dict begin
   /Zcote exch def
   /Yordonnee exch def
   /Xabscisse exch def
   /xObservateur Xabscisse Sin1 mul neg Yordonnee Cos1 mul add def
   /yObservateur Xabscisse Cos1Sin2 mul neg Yordonnee Sin1Sin2 mul sub Zcote Cos2 mul add def
   /zObservateur Xabscisse neg Cos1Cos2 mul Yordonnee Sin1Cos2 mul sub Zcote Sin2 mul sub Dobs add def
   %% maintenant on depose les resultats sur la pile
   Decran xObservateur mul zObservateur div cm %% c'est Xi cm
   Decran yObservateur mul zObservateur div cm %% c'est Yi cm
end} def
         /RotX \psk@IIID@RotX\space def
         /RotY \psk@IIID@RotY\space def
         /RotZ \psk@IIID@RotZ\space def
         /translation {\psk@IIID@translation} def
         translation /vz exch def /vy exch def /vx exch def
         /c2 {RotY cos} bind def
         /s2 {RotY sin} bind def
         /c3 {RotZ cos} bind def
         /s3 {RotZ sin} bind def
         /c1 {RotX cos} bind def
         /s1 {RotX sin} bind def
%% les coefficients de la matrice de transformation
%% translation, rotations du plan
/M11 {c2 c3 mul} bind def
/M12 {c3 s1 mul s2 mul c1 s3 mul sub} bind def
/M13 {c1 c3 mul s2 mul s1 s3 mul add} bind def
/M21 {c2 s3 mul} bind def
/M22 {s1 s2 mul s3 mul c1 c3 mul add} bind def
/M23 {s3 s2 mul c1 mul c3 s1 mul sub} bind def
/M31 {s2 neg} bind def
/M32 {s1 c2 mul} bind def
/M33 {c1 c2 mul} bind def
%%
/CalculsPointsAfterTransformations {
3 dict begin
   M11 Xpoint mul M12 Ypoint mul add M13 Zpoint mul add vx add
   M21 Xpoint mul M22 Ypoint mul add M23 Zpoint mul add vy add
   M31 Xpoint mul M32 Ypoint mul add M33 Zpoint mul add vz add
end
} def
/SizeFont {\psk@fontscale\space cm} bind def
SizeFont 0 eq { /SizeFont 0.001 def} if % Jean-Michel Sarlat
Font findfont SizeFont scalefont setfont
>%
 
\pst@def{WARP}<%
/warpmove{
   %% on teste le booleen place 2 tokens plus en avant sur la pile
   %% si c'est 'true', alors on en est au 1er appel => on initialise
   %% le chemin
   2 index {
     newpath
   } if
   %% puis on applique warp a notre point
   warp  moveto
   %% on enleve le 'true' pour mettre un 'false' a la place
   pop false
} bind def
%% pour remplacer 'lineto
/warpline {
   warp lineto
} bind def
%% pour remplacer 'curveto'
/warpcurve {
   6 2 roll warp
   6 2  roll warp
   6 2 roll warp
   curveto
}  bind def
%% 'warpit' declenche la transformation du chemin courant
/warpit {
true
{ warpmove } { warpline } { warpcurve } { closepath } pathforall
pop
}  bind def
>%
 
\pst@def{PathForAll}<%
/warp {
4 dict begin
    /Ypoint exch def %
    /Xpoint exch def %
%% coordonnées dans le repère absolu
   2dto3d
   /Zpoint exch def
   /Ypoint exch def
   /Xpoint exch def
   CalculsPointsAfterTransformations
%% les coordonnées sur l'écran dans la représentation en perspective
   3dto2d
end
} bind def
\tx@WARP
%% maintenant on y va
% 0 0 moveto
 warpit                  %% on applique le pathforall
 >%
 
\pst@def{PathForTexT}<%
/warptxt exch def % le texte
/warpwidth {warptxt stringwidth pop} bind def  %% largeur horizontale du texte
/warpheigth {SizeFont 2 div} bind def %% hauteur verticale du texte
/warpxhalf warpwidth 2 div def                 %% demi-largeur horizontale
/warpyhalf warpheigth 2 div def                %% demi-hauteur
/x0 warpxhalf neg  cm_1 def % centre le texte
/y0 0 def % warpyhalf neg  cm_1 add def
/warp {
4 dict begin
    /Ypoint exch cm_1 def
    /Xpoint exch cm_1 x0 add def
%% coordonnées dans le repère absolu
   2dto3d
   /Zpoint exch def
   /Ypoint exch def
   /Xpoint exch def
CalculsPointsAfterTransformations
   3dto2d
end
} bind def
\tx@WARP              %% on applique le pathforall
 >%
 
\pst@def{TransformPlan}< % le calcul des coefficients
%% pour passer des coordonnées du plan aux coordonnées
%% (x,y,z) du repère absolu
%% les coordonnées sphériques du vecteur normal
%% au plan
/K_theta exch def % longitude
/K_phi exch def   % latitude
%% l'origine du plan
/zO' exch def
/yO' exch def
/xO' exch def
%% les coefficients de la matrice de transformation
/C11 {K_theta sin neg} def
/C12 {K_theta cos K_phi sin mul neg} bind def
/C21 {K_theta cos} bind def
/C22 {K_phi sin K_theta sin mul neg } bind def
/C31 {K_phi cos} bind def
/2dto3d{
%% coordonnées dans le repère absolu
3 dict begin
  C11 Xpoint mul C12 Ypoint mul add xO' add % x
  C21 Xpoint mul C22 Ypoint mul add yO' add % y
  C31 Ypoint mul zO' add
end }
  def
  >%
 
\def\textThreeDput{\def\pst@par{}\pst@object{textThreeDput}}
\def\textThreeDput@i{\@ifnextchar({\textThreeDput@ii}{\textThreeDput@ii(0,0,0)}}
\def\textThreeDput@ii(#1,#2,#3)#4{{%
  \begin@ClosedObj
    \addto@pscode{%
         \tx@parametresIIID
\ifPst@visibility /Condition { gt } def \else /Condition { le } def \fi
/warptxt (#4) def % le texte
/warpwidth {warptxt stringwidth pop} bind def  %% largeur horizontale du texte
/warpheigth {SizeFont 2 div} bind def %% hauteur verticale du texte
/warpxhalf warpwidth 2 div def                 %% demi-largeur horizontale
/warpyhalf warpheigth 2 div def                %% demi-hauteur
/x0 x0 warpxhalf neg  cm_1 add def % centre le texte
/y0 y0 warpyhalf neg  cm_1 add def
%
/warp {
4 dict begin
    /Ypoint exch cm_1 y0 add def
    /Xpoint exch cm_1 x0 add def
%% coordonnées dans le repère absolu
   2dto3d
   /Zpoint exch def
   /Ypoint exch def
   /Xpoint exch def
CalculsPointsAfterTransformations
   3dto2d
end
} bind def
%% condition de visibilité
% détermination des composantes de la normale
        \psk@normale
        /k_theta exch def
        /k_phi exch def
        /nx {k_phi cos k_theta cos mul} bind def
        /ny {k_phi cos k_theta sin mul} bind def
        /nz {k_phi sin } bind def
%% coordonnées après translation et rotations
   /Zpoint nz def
   /Ypoint ny def
   /Xpoint nx def
CalculsPointsAfterTransformations
   /Nz exch vz sub def
   /Ny exch vy sub def
   /Nx exch vx sub def
%% coordonnées de l'origine du plan après translation et rotations
   /Zpoint #3 def
   /Ypoint #2 def
   /Xpoint #1 def
CalculsPointsAfterTransformations
   /ZO exch def
   /YO exch def
   /XO exch def
%% vecteur dirigé de l'origine du plan -> le point de vue
   /Vx {XpointVue XO sub} bind def
   /Vy {YpointVue YO sub} bind def
   /Vz {ZpointVue ZO sub} bind def
%% le produit scalaire
  /PS {Nx Vx mul Ny Vy mul Nz Vz mul add add} bind def
 PS 0 Condition { % s'il est > 0 le plan est vu !!!
         #1
         #2
         #3
          \psk@normale
          \tx@TransformPlan
\tx@WARP
%% maintenant on y va
 0 0 moveto
warptxt true charpath   %% on cree le chemin
  warpit
 } if
 }%
    \end@ClosedObj}%
  \ignorespaces}
 
%
 
\def\planThreeDput{\def\pst@par{}\pst@object{planThreeDput}}
\def\planThreeDput@i{\@ifnextchar({\planThreeDput@ii}{\planThreeDput@ii(0,0,0)}}
\def\planThreeDput@ii(#1,#2,#3)#4{{%
  \begin@OpenObj
    \addto@pscode{%
         \tx@parametresIIID
\ifPst@visibility /Condition { gt } def \else /Condition { le } def \fi
/warp {
4 dict begin
    /Ypoint exch def
    /Xpoint exch def
%% coordonnées dans le repère absolu
   2dto3d
   /Zpoint exch def
   /Ypoint exch def
   /Xpoint exch def
CalculsPointsAfterTransformations
   3dto2d
end
} bind def
         #1
         #2
         #3
          \psk@normale
          \tx@TransformPlan
% \ifPst@visibility
%% condition de visibilité
% détermination des composantes de la normale
        \psk@normale
        /k_theta exch def
        /k_phi exch def
        /nx {k_phi cos k_theta cos mul} bind def
        /ny {k_phi cos k_theta sin mul} bind def
        /nz {k_phi sin } bind def
%% coordonnées après translation et rotations
   /Zpoint nz def
   /Ypoint ny def
   /Xpoint nx def
CalculsPointsAfterTransformations
   /Nz exch vz sub def
   /Ny exch vy sub def
   /Nx exch vx sub def
%% coordonnées de l'origine du plan après translation et rotations
   /Zpoint #3 def
   /Ypoint #2 def
   /Xpoint #1 def
CalculsPointsAfterTransformations
   /ZO exch def
   /YO exch def
   /XO exch def
%% vecteur dirigé de l'origine du plan -> le point de vue
   /Vx {XpointVue XO sub} bind def
   /Vy {YpointVue YO sub} bind def
   /Vz {ZpointVue ZO sub} bind def
%% le produit scalaire
  /PS {Nx Vx mul Ny Vy mul Nz Vz mul add add} bind def
PS 0 Condition { % s'il est > 0 le plan est vu !!!
%\fi
         #4
\tx@WARP
 warpit
 } if
 }%
    \end@OpenObj}%
  \ignorespaces}
 
%% tracer une ligne dans un plan
 
\def\pst@getcoorsIIID#1{%
\def\pst@aftercoors{#1}%
\def\pst@coorprev{}%
\pst@@getcoorsIIID}
 
\def\pst@@getcoorsIIID(#1){%
\ifx\pst@coorprev\@empty
\else
  \pst@getcoor{\pst@coorprev}{\pst@tempa}%
  \pst@@getcoor{#1}%
  \addto@pscode{\pst@getcoorsIIID@PsCode}%
\fi
\def\pst@coorprev{#1}%
\@ifnextchar({\pst@@getcoorsIIID}{\pst@aftercoors}}
 
% Built from \psline
\def\PslineIIID{\pst@object{PslineIIID}}
 
\def\PslineIIID@i{%
\showpointsfalse
\def\pst@getcoorsIIID@PsCode{%
\pst@tempa \pst@coor
/YB ED /XB ED /YA ED /XA ED
         /Xpoint XA cm_1 def
         /Ypoint YA cm_1 def
%% coordonnées dans le repère absolu
   2dto3d
   /Zpoint exch def
   /Ypoint exch def
   /Xpoint exch def
CalculsPointsAfterTransformations
%% projection conique
   3dto2d
   moveto
         /Xpoint XB cm_1 def
         /Ypoint YB cm_1 def
%% coordonnées dans le repère absolu
   2dto3d
   /Zpoint exch def
   /Ypoint exch def
   /Xpoint exch def
CalculsPointsAfterTransformations
%% projection conique
   3dto2d
   lineto   }%
\pst@getarrows{%
\begin@OpenObj
\addto@pscode{
          \tx@parametresIIID
          \pst@VIIID@origine\space
          \psk@normale
          \tx@TransformPlan}%
\pst@getcoorsIIID{\end@OpenObj}}}
 
\def\Grille(#1,#2)(#3,#4){
/Font /Helvetica /ISOfont ReEncode /ISOfont def
/str 20 string def
/incrementx {#3 #1 sub #3 #1 sub abs div} bind def
#1 incrementx #3 {
2 setlinecap
   /x exch def
   newpath
      x #2 moveto
      x #4 lineto
\tx@PathForAll
\psk@gridwidth SLW
\pst@usecolor\psgridcolor
stroke
x cvi str cvs
\tx@PathForTexT
%% maintenant on y va
 x cm xLabelSep 2 div add yLabelSep moveto
warptxt true charpath   %% on cree le chemin
  warpit
0 setgray
fill
} for
/incrementy {#4 #2 sub #4 #2 sub abs div} bind def
#2 incrementy #4 {
   /y exch def
   newpath
      #1  y moveto
      #3  y lineto
\tx@PathForAll
\psk@gridwidth SLW
\pst@usecolor\psgridcolor
stroke
y cvi str cvs
\tx@PathForTexT
%% maintenant on y va
 xLabelSep y cm moveto
warptxt true charpath   %% on cree le chemin
  warpit
0 setgray
fill
} for }
 
 
\def\axesIIID{\def\pst@par{}\pst@object{axesIIID}}
\def\axesIIID@i(#1,#2,#3){%
\begin@SpecialObj
\addto@pscode{%
         \tx@parametresIIID
%% les axes
% gsave
   %% axe Ox
   1 setlinecap
   0 0 moveto
   #1 0 0 3dto2d lineto
   2 setlinewidth
   1 0 0 setrgbcolor
stroke
   #1 0.4 sub -0.2 0 3dto2d moveto
   #1 0 0 3dto2d lineto
   #1 0.4 sub 0.2 0 3dto2d lineto
stroke
    %% axe Oy
   0 0 moveto
   0 #2 0 3dto2d lineto
   2 setlinewidth
   0 1 0 setrgbcolor
stroke
   -0.2 #2 0.4 sub 0 3dto2d moveto
   0 #2 0 3dto2d lineto
   0.2 #2 0.4 sub 0 3dto2d lineto
stroke
   %% axe Oz
   0 0 moveto
   0 0 #3 3dto2d lineto
   2 setlinewidth
   0 0 1 setrgbcolor
stroke
   -0.2 0 #3 0.4 sub 3dto2d moveto
   0 0 #3 3dto2d lineto
   0.2 0 #3 0.4 sub 3dto2d lineto
 stroke
% grestore
}%
\end@SpecialObj}
 
% placer un point du plan
 
\def\NodeIIItoIID{\def\pst@par{}\pst@object{NodeIIItoIID}}
\def\NodeIIItoIID@i(#1,#2)#3{{%
  \begin@ClosedObj
\pnode(!
         \tx@parametresIIID
          \pst@VIIID@origine\space % pour positionner l'origine du plan
          \psk@normale
          \tx@TransformPlan
         /Xpoint #1 def
         /Ypoint #2 def
%% coordonnées dans le repère absolu
   2dto3d
   /Zpoint exch def
   /Ypoint exch def
   /Xpoint exch def
CalculsPointsAfterTransformations
%% projection conique
   3dto2d
   cm_1 exch cm_1 exch){#3}%
     \end@ClosedObj
  }\ignorespaces%
}
 
\def\pnodeXYZ{\def\pst@par{}\pst@object{pnodeXYZ}}
\def\pnodeXYZ@i(#1,#2,#3)#4{{% coordonnées cartésiennes
  \begin@ClosedObj
\pnode(!
         \tx@parametresIIID
         #1
         #2
         #3
%% projection conique
   3dto2d
   cm_1 exch cm_1 exch){#4}%
   \end@ClosedObj
  }\ignorespaces%
}
 
\def\pnodeSphericalCoor{\def\pst@par{}\pst@object{pnodeSphericalCoor}}
\def\pnodeSphericalCoor@i(#1,#2,#3)#4{{% coordonnées sphériques
  \begin@ClosedObj
\pnode(!
         \tx@parametresIIID
         #1 % radius
         #2 % longitude
         #3 % latitude
      #1 #3 cos mul #2 cos mul  % x
      #1 #3 cos mul #2 sin mul  % y
      #1 #3 sin mul             % z
%% projection conique
   3dto2d
   cm_1 exch cm_1 exch){#4}%
   \end@ClosedObj
  }\ignorespaces%
}
 
\catcode`\@=\PstAtCode\relax
\endinput