lundi 30 décembre 2013

Dessiner l’ombre d’un objet avec pst-solides3d

La source de lumière étant ponctuelle, il est simple avec pst-solides3d, de dessiner l’ombre portée d’un objet sur un plan, horizontal(le sol) ou vertical (un mur).

Ombres sur un sol horizontal
Pour que l’ombre de l’objet soit visible, il faut que les coordonnées de la source de lumière et du point de vue soient différentes.

Ombres sur un mur vertical
Les explications théoriques et les macros sont dans le document "ombre1.pdf" (fichier source : ombre1.tex) du répertoire :

 Les fichiers de données de la tête de Néfertiti sont inclus dans ce répertoire.

Le listing du fichier :

\documentclass{article}
\usepackage[a4paper,margin=2cm]{geometry}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{amsmath}
\usepackage{pst-solides3d}
\title{Dessiner l'ombre d'un objet avec pst-solides3d}
\date{29 décembre 2013}
\begin{document}
\maketitle

La source de lumière étant ponctuelle, il est simple avec pst-solides3d, de dessiner l'ombre portée d'un objet sur un plan, horizontal(le sol) ou vertical (un mur). Ce court document décrit une méthode pour le faire.
\section{Ombre sur un sol horizontal}
\begin{center}
\psset{viewpoint=100 30 30 rtp2xyz,Decran=30,lightsrc=20 120 30 rtp2xyz,a=4}%
\begin{pspicture}(-5,-4)(5,3)
\pstVerb{
20 120 30 rtp2xyz
/zV exch def
/yV exch def
/xV exch def
/hZ -2 def
/Hshadow {
5 dict begin
/M defpoint3d
 M
/z exch def
/y exch def
/x exch def
/lambda hZ zV sub z zV sub div def
    xV lambda x xV sub mul add % x
    yV lambda y yV sub mul add % y
    hZ % z
end
 } def }%
\psSolid[object=plan,definition=equation,
         args={[0 0 1 hZ neg]},action=draw,
         base=-15 15 -15 15,
         ngrid=5 5]%
\psSolid[object=cube,
         grid,fillcolor=black,
         transform=Hshadow,
         ](0,0,0)%
\psSolid[object=cube](0,0,0)%
% la source de lumière
\pstVerb{20 120 30 rtp2xyz /zL exch def /yL exch def /xL exch def}%
\psPoint(xL,yL,zL){L}
%Un sommet du cube
\psPoint(2,2,2){A}
\psPoint(-2,-2,2){B}
\psPoint(2,-2,2){C}
\pcline[nodesepB=4cm]{->}(L)(A)
\pcline[nodesepB=4cm]{->}(L)(B)
\pcline[nodesepB=5cm]{->}(L)(C)
\psline{->}(L)(A)\psline{->}(L)(B)\psline{->}(L)(C)
\pstVerb{2 2 2 Hshadow /zA' exch def /yA' exch def /xA' exch def}%
\psPoint(xA',yA',zA'){A'}
\pstVerb{-2 -2 2 Hshadow /zB' exch def /yB' exch def /xB' exch def}%
\psPoint(xB',yB',zB'){B'}
\pstVerb{2 -2 2 Hshadow /zC' exch def /yC' exch def /xC' exch def}%
\psPoint(xC',yC',zC'){C'}
\psline[linecolor=gray!20](A)(A')
\psline[linecolor=gray!20](B)(B')
\psline[linecolor=gray!20](C)(C')
\uput[r](L){L}
\uput[u](A){A}
\uput[d](A'){A'}
\end{pspicture}
\end{center}
Connaissant les coordonnées de la source de lumière $(x_L,y_L,z_L)$, celles du point à projeter, par exemple un sommet du cube $(x_A,y_A,z_A)$ et l'équation du plan $(z=h$, on en déduit les coordonnées de l'ombre portée du sommet sur le plan horizontal :
\[
\left\{
\begin{array}[m]{l}
x'=x_V+\lambda(x_A-x_V)\\
y'=y_V+\lambda(y_A-y_V)
\end{array}
\right.
\text{avec}\quad\lambda=\displaystyle\frac{h-z_V}{z_A-z_V}
\]
Pour que l'ombre de l'objet soit visible, il faut que les coordonnées de la source de lumière et du point de vue soient différentes. On utilise l'option \texttt{trasform=Hshadow} de pst-solides3d après avoir défini la transformation \texttt{Hshadow} :
\begin{verbatim}
\psset{viewpoint=100 60 30 rtp2xyz,Decran=50,lightsrc=100 120 30 rtp2xyz,a=2}%
\pstVerb{
100 120 30 rtp2xyz
/zV exch def
/yV exch def
/xV exch def
/hZ -1 def % position du plan horizontal (le sol)
/Hshadow {
5 dict begin
/z exch def
/y exch def
/x exch def
/lambda hZ zV sub z zV sub div def
    xV lambda x xV sub mul add % x
    yV lambda y yV sub mul add % y
    hZ % z
end
 } def }%
\end{verbatim}
\newpage
Quelques exemples, la source de lumière n'est pas toujours représentée. On dessine d'abord le plan de projection, puis l'ombre et enfin l'objet.

%\begin{center}
\begin{minipage}{9cm}
\begin{pspicture}(-5,-5)(5,5)
\psset{viewpoint=100 60 30 rtp2xyz,Decran=40,lightsrc=100 120 30 rtp2xyz,a=4}%
\pstVerb{
100 120 30 rtp2xyz
/zV exch def
/yV exch def
/xV exch def
/hZ -2 def
/Hshadow {
5 dict begin
/z exch def
/y exch def
/x exch def
/lambda hZ zV sub z zV sub div def
    xV lambda x xV sub mul add % x
    yV lambda y yV sub mul add % y
    hZ % z
end
 } def }%
\psSolid[object=plan,definition=equation,
         args={[0 0 1 hZ neg]},
         base=-10 10 -10 10,
         ngrid=5 5,
         linecolor=green!20!black,
         fillcolor=green!20]%
\psSolid[object=cube,
         trunccoeff=.2,
         trunc=all,
         grid,fillcolor=gray,linecolor=gray,
         transform=Hshadow,
%         opacity=0.9
         ](0,0,0)%
\psSolid[object=cube,
         trunccoeff=.2,
         trunc=all,
         fcol=6 1 13 { (rouge) } for,
         ](0,0,0)%
\end{pspicture}
\end{minipage}
\begin{minipage}{6cm}
\begin{verbatim}
\begin{pspicture}(-5,-5)(5,5)
\psset{viewpoint=100 60 30 rtp2xyz,Decran=50,lightsrc=100 120 30 rtp2xyz,a=2}%
\pstVerb{
100 120 30 rtp2xyz
/zV exch def
/yV exch def
/xV exch def
/hZ -1 def
/Hshadow {
5 dict begin
/z exch def
/y exch def
/x exch def
/lambda hZ zV sub z zV sub div def
    xV lambda x xV sub mul add % x
    yV lambda y yV sub mul add % y
    hZ % z
end
 } def }%
\psSolid[object=plan,definition=equation,
         args={[0 0 1 hZ neg]},
         base=-10 10 -10 10,
         ngrid=5 5,
         linecolor=green!20!black,
         fillcolor=green!20]%
\psSolid[object=cube,
         trunccoeff=.2,
         trunc=all,
         grid,fillcolor=gray,linecolor=gray,
         transform=Hshadow,
         opacity=0.9
         ](0,0,0)%
\psSolid[object=cube,
         trunccoeff=.2,
         trunc=all,
         fcol=6 1 13 { (rouge) } for,
         ](0,0,0)%
\end{pspicture}
\end{verbatim}
\end{minipage}
%\end{center}

\begin{center}
\psset{viewpoint=50 60 20 rtp2xyz,Decran=25,lightsrc=20 120 60 rtp2xyz}%
\begin{pspicture}(-5,-5)(5,5)
\psframe(-5,-5)(5,5)
\pstVerb{
20 120 60 rtp2xyz
/zV exch def
/yV exch def
/xV exch def
/hZ 0 def
/Hshadow {
5 dict begin
/z exch def
/y exch def
/x exch def
/lambda hZ zV sub z zV sub div def
    xV lambda x xV sub mul add % x
    yV lambda y yV sub mul add % y
    hZ % z
end
 } def }%
\psSolid[object=plan,definition=equation,
         args={[0 0 1 0]},
         base=-10 10 -10 10,
         ngrid=5 5,
         linecolor=green!20!black,
         fillcolor=green!20]%
\psSolid[object=sphere,r=2,
         grid,fillcolor=black,linecolor=black,
         transform=Hshadow,
         opacity=0.9,
         ngrid=18 18,
         ](0,0,2)%
\psSolid[object=sphere,
         ngrid=18 18
         ](0,0,2)%
\pstVerb{20 120 30 rtp2xyz /zL exch def /yL exch def /xL exch def}%
\psPoint(xL,yL,zL){L}
\psdot(L)
\end{pspicture}

\psset{viewpoint=50 60 20 rtp2xyz,Decran=25,lightsrc=50 20 30 rtp2xyz}%
\begin{pspicture}(-5,-5)(5,5)
\psframe(-5,-5)(5,5)
\pstVerb{
50 20 30 rtp2xyz
/zV exch def
/yV exch def
/xV exch def
/hZ 0 def
/Hshadow {
5 dict begin
/z exch def
/y exch def
/x exch def
/lambda hZ zV sub z zV sub div def
    xV lambda x xV sub mul add % x
    yV lambda y yV sub mul add % y
    hZ % z
end
 } def }%
\psSolid[object=plan,definition=equation,
         args={[0 0 1 0]},
         base=-10 10 -10 10,
         ngrid=5 5,
         linecolor=green!20!black,
         fillcolor=green!20]%
\psSolid[object=sphere,r=2,
         grid,fillcolor=black,%linecolor=gray,
         transform=Hshadow,
%         linewidth=0.001,
         ngrid=18 18,
%         opacity=0.95,
%         strokeopacity=0.95
         ](0,0,2)%
\psSolid[object=sphere,
         ngrid=18 18
         ](0,0,2)%
\end{pspicture}

\begin{pspicture}(-5,-5)(5,5)
\psframe(-5,-5)(5,5)
\pstVerb{
50 20 30 rtp2xyz
/zV exch def
/yV exch def
/xV exch def
/hZ 0 def
/Hshadow {
5 dict begin
/z exch def
/y exch def
/x exch def
/lambda hZ zV sub z zV sub div def
    xV lambda x xV sub mul add % x
    yV lambda y yV sub mul add % y
    hZ % z
end
 } def }%
\psSolid[object=plan,definition=equation,
         args={[0 0 1 0]},
         base=-10 10 -10 10,
         ngrid=5 5,
         linecolor=green!20!black,
         fillcolor=green!20]%
\psSolid[object=cylindre,r=2,h=6,
         grid,fillcolor=black,%linecolor=gray,
         transform=Hshadow,
%         linewidth=0.001,
         ngrid=1 36,
%         opacity=0.95,
%         strokeopacity=0.95
         ](5,0,0)%
\psSolid[object=cylindre,h=6,
         ngrid=1 36
         ](5,0,0)%
\end{pspicture}

\begin{pspicture}(-5,-5)(5,5)
\psset{viewpoint=50 60 5 rtp2xyz,Decran=25,lightsrc=10 120 30 rtp2xyz}%
\psframe(-5,-5)(5,5)
\pstVerb{
10 120 30 rtp2xyz
/zV exch def
/yV exch def
/xV exch def
/hZ -4 def
/Hshadow {
5 dict begin
/z exch def
/y exch def
/x exch def
/lambda hZ zV sub z zV sub div def
    xV lambda x xV sub mul add % x
    yV lambda y yV sub mul add % y
    hZ % z
end
 } def }%
\psSolid[object=plan,definition=equation,
         args={[0 0 1 hZ neg]},
         base=-10 10 -10 10,
         ngrid=5 5,
         linecolor=green!20!black,
         fillcolor=green!20]%
\psSolid[r1=2.5,r0=1.5,
         object=tore,
         ngrid=18 36,
         grid,fillcolor=black,%linecolor=gray,
         transform=Hshadow,
         ngrid=1 36,
         ](0,0,0)%
\psSolid[r1=2.5,r0=1.5,
         object=tore,
         ngrid=18 36
         ](0,0,0)%
\pstVerb{10 120 30 rtp2xyz /zL exch def /yL exch def /xL exch def}%
\psPoint(xL,yL,zL){L}
\psdot[linecolor=red](L)
\end{pspicture}
\end{center}
\newpage
\section{Ombre sur un mur vertical}
Mur parallèle au plan $Oyz$ : $x=x_0$. Les équations précédentes s'écrivent :
\[
\left\{
\begin{array}[m]{l}
y'=y_V+\lambda(y_A-y_V)\\
z'=z_V+\lambda(z_A-z_V)
\end{array}
\right.
\text{avec}\quad\lambda=\displaystyle\frac{x_0-x_V}{x_A-x_V}
\]
\begin{center}
\psset{viewpoint=50 60 20 rtp2xyz,Decran=25,lightsrc=10 0 20 rtp2xyz}%
\begin{pspicture}(-5,-6)(5,7)
\psframe(-5,-6)(5,7)
\pstVerb{
10 0 20 rtp2xyz
/zV exch def
/yV exch def
/xV exch def
/x_0 -8 def
/Vshadow {
4 dict begin
/z exch def
/y exch def
/x exch def
/lambda x_0 xV sub x xV sub div def
    x_0
    yV lambda y yV sub mul add % y
    zV lambda z zV sub mul add % z
end
 } def }%
\psSolid[object=plan,definition=equation,
         args={[1 0 0 x_0 neg]},
         base=-10 10 -10 10,
         ngrid=5 5,
         linecolor=green!20!black,
         fillcolor=green!20]%
\psSolid[object=sphere,r=2,
         grid,fillcolor=black,linecolor=black,
         transform=Vshadow,
         ngrid=18 18,
         ](0,0,0)%
\psSolid[object=sphere,
         ngrid=18 18
         ](0,0,0)%
\pstVerb{10 0 20 rtp2xyz /zL exch def /yL exch def /xL exch def}%
\psPoint(xL,yL,zL){L}
\psdot[linecolor=red](L)
\end{pspicture}
\end{center}
\newpage
Mur parallèle au plan $Oxz$ : $y=y_0$. Les équations précédentes s'écrivent :
\[
\left\{
\begin{array}[m]{l}
x'=x_V+\lambda(x_A-x_V)\\
z'=z_V+\lambda(z_A-z_V)
\end{array}
\right.
\text{avec}\quad\lambda=\displaystyle\frac{y_0-y_V}{y_A-y_V}
\]
\begin{center}
%\psset{unit=0.4}
\psset{viewpoint=50 60 0 rtp2xyz,Decran=25,lightsrc=50 100 -10 rtp2xyz}
\begin{pspicture}(-5,-7)(6,6)
\definecolor{AntiqueWhite}{rgb}{0.98,0.92,0.84}
\definecolor{rose}{rgb}{1,0.75,0.74}
\psframe*[linecolor=AntiqueWhite](-7,-7)(6,6)
\pstVerb{
50 100 -10 rtp2xyz
/zV exch def
/yV exch def
/xV exch def
/y_0 -8 def
/Vshadow {
4 dict begin
/z exch def
/y exch def
/x exch def
/lambda y_0 yV sub y yV sub div def
    xV lambda x xV sub mul add % x
    y_0
    zV lambda z zV sub mul add % z
end
 } def }%
\psSolid[object=plan,definition=equation,
         args={[0 1 0 y_0 neg]},
         base=-10 10 -10 15,
         ngrid=5 5,
         linecolor=green!20!black,
         fillcolor=green!20]%
\psset{RotX=90,RotZ=90,sommets= (sommets_nefer0.dat) run}
\psSolid[object=new,hollow,
         grid,fillcolor=black,linecolor=black,incolor=black,
         transform=Vshadow,
         faces={(faces_nefer.dat) run}
         ](0,0,0)%
\psSolid[object=new,fillcolor=rose,linewidth=0.5\pslinewidth,hollow,incolor=yellow!50,
    faces={(faces_nefer.dat) run}]%
\psSolid[object=new,fillcolor=red,linewidth=0.5\pslinewidth,
    faces={(faces_nefer_levres.dat) run}]%
\psSolid[object=new,fillcolor=black,
    faces={(faces_nefer_sourcils.dat) run}]%
\end{pspicture}
\end{center}
\end{document}


jeudi 19 décembre 2013

Jeu de dés avec pst-solides3d

La commande : \psDie[options](x,y) construite à partir d’un cube dont on a tronqué les sommets comprend les options suivantes :
  1. [sidecolor=white],
  2. [dotcolor=black],
  3. [truncationcolor=red].
 permettant de choisir la couleur des faces, des points et des facettes résultant des troncatures aux sommets, les couleurs indiquées sont celles par défaut. Entre parenthèses (x,y) on indique les coordonnées de la projection du centre du dé sur le tapis de jeu.
On pourra modifier l’arête du cube avec [a=value]. Une option permet de dessiner ou d’occulter le tapis de jeu : [carpet=true].
Le générateur de nombres aléatoires est celui de Donald Arseneau :
 http://www.ctan.org/pkg/random
Il utilise pour nombre initial un nombre calculé à partir de la date de compilation : année, mois, jour, heure et minutes. On peut choisir soi-même ce nombre initial avec la variable randomi=nombre entier, cette valeur initiale ne doit pas dépasser : 2^31 −1 = 2147483647.
Pour placer les cubes aléatoirement sur le tapis, j’ai introduit une variable \CY, qu’on peut utiliser ou pas, il faut éviter que les cubes se chevauchent après le lancer. Voici un exemple de lancé “simultané” de trois dés.

Dans le premier épisode de ``La légende de Zatoichi", au tout début, une partie de dés très étonnante, se joue entre Zatoichi et les hommes de main du \textit{parrain} chez lequel Zatoichi est en visite. En attendant l'arrivée du parrain, on l'installe dans une pièce où les yakusas  sont en train de disputer une partie de dés. Ce jeu consiste à placer deux dés dans un cornet à dés, un joueur ou le maître de jeu secoue le gobelet puis retourne le brusquement sur le tapis cachant ainsi la répartition des dés à l'intérieur du gobelet. Les joueurs misent alors pair ou impair sur la somme des points des faces supérieures et, les mises faites, un joueur soulève alors le cornet pour faire apparaître les dés. Zatoichi sollicite la permission de participer au jeu, qui lui est accordée, les yakusas pensant berner Zatoichi qui est aveugle. Pour ceux qui ne connaissent pas le personnage, je précise que Zatoichi est un masseur aveugle itinérant, mais aussi un redoutable sabreur dont les autres sens, l'ouïe et l'odorat sont particulièrement développés. Cette partie où Zatoichi plume les yakusas et leur fait une leçon de morale est un superbe moment cinématographique. Dans la suite des épisodes Zatoichi participe à de nombreuses autres parties de dés.

Les fichiers "dice-games.pdf" et "dice-games.tex" sont dans le dossier :
En fait, cette commande est une adaptation d'un ancien fichier "Die3D.pdf" et "Die3D.tex", pour les archives(?) qui est dans le dossier indiqué précedemment.

==================================================================
Le listing du nouveau fichier :

\documentclass{article}
\usepackage[a4paper,margin=2cm]{geometry}
\usepackage[latin1]{inputenc}
\usepackage[garamond]{mathdesign}
\usepackage[T1]{fontenc}
\usepackage{pst-solides3d}
\usepackage{url}
%\usepackage{datetime}
% Le générateur de nombres aléatoires est de
% Donald Arseneau
\input random
\pagestyle {empty}
\newpsstyle{sol}{fillstyle=crosshatch,hatchcolor=green,hatchwidth=0.25\pslinewidth,hatchsep=5\pslinewidth}
% variables aléatoires
% rotations du dé autour de Ox, Oy et Oz
\newcount\diex
\newcount\diey
\newcount\diez
% position du dé suivant l'axe Oy
\newcount\CY
\makeatletter
\pst@addfams{pst-die3d}
\define@key[psset]{pst-die3d}{sidecolor}{\edef\psk@sidecolor{#1}}%
\psset[pst-die3d]{sidecolor=white}
%color truncations
\define@key[psset]{pst-die3d}{truncationcolor}[red]{\pst@getcolor{#1}\truncationcolor}
\psset[pst-die3d]{truncationcolor=red}
%
\define@key[psset]{pst-die3d}{dotcolor}{\edef\psk@dotcolor{#1}}%
\psset[pst-die3d]{dotcolor=black}
%
\newif\ifPst@carpet%
\define@key[psset]{pst-die3d}{carpet}[false]{\@nameuse{Pst@carpet#1}}%
\psset[pst-die3d]{carpet=true}
%
\def\psDie{\def\pst@par{}\pst@object{psDie}}
\def\psDie@i(#1,#2){%
\begin@SpecialObj
\pstVerb{
         /carpet \pst@solides@a\space 5 mul def
         /posP \pst@solides@a\space 0.3 mul def
         /rP \pst@solides@a\space 0.1 mul def
         /dP \pst@solides@a\space 2 div def
         /a_2 \pst@solides@a\space 2 div def
         /truncationcolor {\pst@usecolor\truncationcolor } def}%
\ifPst@carpet
\psSolid[object=plan,definition=equation,
         args={[0 0 1 dP]},
         base=carpet neg carpet carpet neg carpet,
%         plangrid,
         ngrid=\pst@solides@a\space 5 mul cvi \pst@solides@a\space 5 mul cvi,
         linecolor=green!20!black,
         fillcolor=green!20]%
\fi
\psset{solidmemory}
\setrannum{\diex}{-1}{2}
\setrannum{\diey}{-1}{2}
\setrannum{\diez}{1}{360}
\multiply\diex90
\multiply\diey90
\psSolid[object=cube,
         trunccoeff=.1,
         trunc=all,
         RotX=\the\diex,RotY=\the\diey,RotZ=\the\diez,
         fillcolor=\psk@sidecolor,
         fcol=6 1 13 { (truncationcolor) } for,
         name=A
         ](#1,#2,0)%
\psSolid[object=plan,action=none,
         definition=solidface,args=A 0,name=P0]
\psset{plan=P0}
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=0 0 rP,
              range=0 360]
\psSolid[object=plan,action=none,
         definition=solidface,args=A 1,name=P1]
\psset{plan=P1}
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=0 0 rP,
              range=0 360]
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP posP rP,
              range=0 360]
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP neg posP neg rP,
              range=0 360]
\psSolid[object=plan,action=none,
         definition=solidface,args=A 2,name=P2]
\psset{plan=P2}
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP posP rP,
              range=0 360]
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP neg posP neg rP,
              range=0 360]
\psSolid[object=plan,action=none,
         definition=solidface,args=A 3,name=P3]
\psset{plan=P3}
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP posP rP,
              range=0 360]
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP posP neg rP,
              range=0 360]
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP neg posP rP,
              range=0 360]
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP neg posP neg rP,
              range=0 360]
\psSolid[object=plan,action=none,
         definition=solidface,args=A 4,name=P4]
\psset{plan=P4}
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=0 0 rP,
              range=0 360]
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP posP rP,
              range=0 360]
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP neg posP neg rP,
              range=0 360]
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP posP neg rP,
              range=0 360]
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP neg posP rP,
              range=0 360]
\psSolid[object=plan,action=none,
         definition=solidface,args=A 5,name=P5]
\psset{plan=P5}
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=0 posP rP,
              range=0 360]
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=0 posP neg rP,
              range=0 360]
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP posP rP,
              range=0 360]
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP neg posP neg rP,
              range=0 360]
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP posP neg rP,
              range=0 360]
\psProjection[object=cercle,fillstyle=solid,fillcolor=\psk@dotcolor,
              args=posP neg posP rP,
              range=0 360]
 \end@SpecialObj
}
\makeatother
\title{Jeu de dés avec pst-solides3d}
\date{19 décembre 2013}
\begin{document}
\maketitle
La commande : \verb+\psDie[options](x,y)+ construite à partir d'un cube dont on a tronqué les sommets  comprend les options suivantes :
\begin{enumerate}
  \item \texttt{[sidecolor=white]},
  \item \texttt{[dotcolor=black]},
  \item \texttt{[truncationcolor=red]}.
\end{enumerate}
permettant de choisir la couleur des faces, des points et des facettes résultant des troncatures aux sommets, les couleurs indiquées sont celles par défaut. Entre parenthèses \verb+(x,y)+ on indique les coordonnées de la projection du centre du dé sur le tapis de jeu.

On pourra modifier l'arête du cube avec \verb+[a=value]+.
Une option permet de dessiner ou d'occulter le tapis de jeu :
\begin{itemize}
  \item \texttt{[carpet=true]}
\end{itemize}
Le générateur de nombres aléatoires est celui de Donald Arseneau :
\url{http://www.ctan.org/pkg/random}

Il utilise pour nombre initial un nombre calculé à partir de la date de compilation : année, mois, jour, heure et minutes. On peut choisir soi-même ce nombre initial avec la variable \verb+randomi=nombre entier+, cette valeur initiale ne doit pas dépasser : $2^{31}-1=2147483647$.

Pour placer les cubes aléatoirement sur le tapis, j'ai introduit une variable \verb+\CY+, qu'on peut utiliser ou pas, il faut éviter que les cubes se chevauchent après le lancer. Voici un exemple de lancé ``\textit{simultané}'' de trois dés.
\begin{center}
\psset{viewpoint=30 60 25 rtp2xyz,Decran=12,lightsrc=viewpoint,a=2}%
\begin{pspicture}(-7,-5)(7,2)
\psframe*(-7,-5)(7,2)
\setrannum{\CY}{-2}{8}
\psDie[sidecolor=yellow](6,\the\CY)%
\setrannum{\CY}{-2}{8}
\psDie[carpet=false](-4,\the\CY)%
\setrannum{\CY}{-2}{8}
\psDie[carpet=false,dotcolor=red,sidecolor=cyan!50](0,\the\CY)%
\end{pspicture}
\end{center}
\begin{verbatim}
\begin{center}
\psset{viewpoint=30 60 25 rtp2xyz,Decran=12,lightsrc=viewpoint,a=2}%
\begin{pspicture}(-7,-5)(7,2)
\psframe*(-7,-5)(7,2)
\setrannum{\CY}{-2}{8}
\psDie[sidecolor=yellow](6,\the\CY)%
\setrannum{\CY}{-2}{8}
\psDie[carpet=false](-4,\the\CY)%
\setrannum{\CY}{-2}{8}
\psDie[carpet=false,dotcolor=red,sidecolor=cyan!50](0,\the\CY)%
\end{pspicture}
\end{center}
\end{verbatim}
Dans le premier épisode de ``La légende de Zatoichi", au tout début, une partie de dés très étonnante, se joue entre Zatoichi et les hommes de main du \textit{parrain} chez lequel Zatoichi est en visite. En attendant l'arrivée du parrain, on l'installe dans une pièce où les yakusas  sont en train de disputer une partie de dés. Ce jeu consiste à placer deux dés dans un cornet à dés, un joueur ou le maître de jeu secoue le gobelet puis retourne le brusquement sur le tapis cachant ainsi la répartition des dés à l'intérieur du gobelet. Les joueurs misent alors pair ou impair sur la somme des points des faces supérieures et, les mises faites, un joueur soulève alors le cornet pour faire apparaître les dés. Zatoichi sollicite la permission de participer au jeu, qui lui est accordée, les yakusas pensant berner Zatoichi qui est aveugle. Pour ceux qui ne connaissent pas le personnage, je précise que Zatoichi est un masseur aveugle itinérant, mais aussi un redoutable sabreur dont les autres sens, l'ouïe et l'odorat sont particulièrement développés. Cette partie où Zatoichi plume les yakusas et leur fait une leçon de morale est un superbe moment cinématographique. Dans la suite des épisodes Zatoichi participe à de nombreuses autres parties de dés.

\begin{center}
\psset{viewpoint=30 30 45 rtp2xyz,Decran=10,lightsrc=viewpoint,a=2}%
\begin{pspicture}(-5,-5)(4,3)
\psframe*(-5,-5)(4,3)
\psDie[sidecolor=yellow](0,0)%
\psDie[sidecolor=yellow,carpet=false](2.5,2.5)%
\psSolid[object=cylindre,
         h=7,r=4,rm=1,
         fillcolor={[rgb]{0.875 0.75 0.5}},
         opacity=0.5,grid,
         ngrid=4 32](0,2,-1)
\end{pspicture}
\end{center}
\newpage
\begin{center}
\psset{viewpoint=30 60 25 rtp2xyz,Decran=14,lightsrc=viewpoint,a=2}%
\begin{pspicture*}(-2,-2)(2,2)
\psframe(-2,-2)(2,2)
\psDie[sidecolor=yellow,dotcolor=blue,truncationcolor=green,linecolor=red](0,0)
\end{pspicture*}
\begin{pspicture*}(-2,-2)(2,2)
\psframe(-2,-2)(2,2)
\psDie(3,2)
\end{pspicture*}
\begin{pspicture*}(-2,-2)(2,2)
\psframe(-2,-2)(2,2)
\psDie(3,2)
\end{pspicture*}
\end{center}
\begin{center}
\psset{viewpoint=50 60 25 rtp2xyz,Decran=25,lightsrc=viewpoint,a=2}%
\begin{pspicture*}(-2,-2)(2,2)
\psframe(-2,-2)(2,2)
\psDie(3,2)
\end{pspicture*}
\begin{pspicture*}(-2,-2)(2,2)
\psframe(-2,-2)(2,2)
\psDie(3,2)
\end{pspicture*}
\begin{pspicture*}(-2,-2)(2,2)
\psframe(-2,-2)(2,2)
\psDie(3,2)
\end{pspicture*}
\end{center}
\begin{center}
\psset{viewpoint=50 60 25 rtp2xyz,Decran=25,lightsrc=viewpoint,a=2}%
\begin{pspicture*}(-2,-2)(2,2)
\psframe(-2,-2)(2,2)
\psDie(3,2)
\end{pspicture*}
\begin{pspicture*}(-2,-2)(2,2)
\psframe(-2,-2)(2,2)
\psDie(-2,-2)
\end{pspicture*}
\begin{pspicture*}(-2,-2)(2,2)
\psframe(-2,-2)(2,2)
\psDie(3,2)
\end{pspicture*}
\end{center}
\begin{center}
\psset{viewpoint=50 60 25 rtp2xyz,Decran=25,lightsrc=viewpoint,a=2}%
\begin{pspicture*}(-2,-2)(2,2)
\psframe(-2,-2)(2,2)
\psDie(3,2)
\end{pspicture*}
\begin{pspicture*}(-2,-2)(2,2)
\psframe(-2,-2)(2,2)
\psDie(3,2)
\end{pspicture*}
\begin{pspicture*}(-2,-2)(2,2)
\psframe(-2,-2)(2,2)
\psDie(3,2)
\end{pspicture*}
\end{center}
\end{document}



mardi 17 décembre 2013

pst-solides3d : choisir la séquence des rotations

pst-solides3d  ne permet pas de choisir, tout au moins directement, l'ordre des rotations d'un solide autour des axes Ox, Oy et Oz. Cet ordre est imposé : d'abord autour de Ox, puis de Oy et ensuite de Oz. On peut, si cet ordre ne convient pas, faire la rotation autour du premier axe choisi,  puis sauvegarder le solide et continuer dans l'ordre des rotations souhaité. C'est fastidieux. Cette modification des fichiers de pst-solides3d.tex et pst-solides3d.pro,  permet grâce à une commande supplémentaire de choisir l'ordre des rotations autour des axes, il s'agit de la commande :
RotSequence=xyz,xzy, etc.
qui donne l'ordre des rotations. Les schémas ci-dessous sont une illustration de cette commande :
Les fichiers se trouvent ici :