%% %% 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