```/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        C O N S T R U C T I O N   D ' U N   R E F E R E N T I E L   O R T H O N O R M E                                            */
/*        D O N T   L ' A X E   ' Z '   E S T   D O N N E  :                                                                         */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Author of '\$xtc/referentiel.01\$c' :                                                                                        */
/*                                                                                                                                   */
/*                    Jean-Francois Colonna (LACTAMME, 20161220135707).                                                              */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

#include  "INCLUDES.01.I"

extern    double    acos();

#define   Definition_OX(a1,a2,a3,c1,c2,c3)                                                                                              \
{                                                                                                                   \
if        (c1 != 0)                                                                                                 \
{                                                                                                         \
a2 = +1;                                                                                                  \
a3 = +1;                                                                                                  \
a1 = -((a2*c2)+(a3*c3))/c1;                                                                               \
/* Le vecteur {a1,a2,a3} est calcule "arbitrairement" tel qu'il soit orthogonal au           */ \
/* vecteur {c1,c2,c3}. Leur produit scalaire est donc nul :                                  */ \
/*                                                                                           */ \
/*                  a1.c1 + a2.c2 + a3.c3 = 0                                                */ \
/*                                                                                           */ \
/* en supposant que la coordonnee 'c1' n'est pas nulle (ce que l'on teste avant d'appeler    */ \
/* 'Definition_OX(...)' et ce que l'on reverifie ici), on fixe arbitrairement :              */ \
/*                                                                                           */ \
/*                  a2 = 1                                                                   */ \
/*                  a3 = 1                                                                   */ \
/*                                                                                           */ \
/* d'ou la valeur de 'a1'...                                                                 */ \
}                                                                                                         \
else                                                                                                                \
{                                                                                                         \
printf("Erreur de logique.\n");                                                                           \
/* Et oui, puisqu'un tel test a ete deja fait juste avant l'appel a 'Definition_OX(...)'...  */ \
}                                                                                                         \
}

#define   ProduitVectoriel_1(c1,c2,c3,a1,a2,a3)                                                                                         \
NEUT(DET2(c2,c3                                                                                                     \
,a2,a3                                                                                                     \
)                                                                                                         \
)
#define   ProduitVectoriel_2(c1,c2,c3,a1,a2,a3)                                                                                         \
NEGA(DET2(c1,c3                                                                                                     \
,a1,a3                                                                                                     \
)                                                                                                         \
)
#define   ProduitVectoriel_3(c1,c2,c3,a1,a2,a3)                                                                                         \
NEUT(DET2(c1,c2                                                                                                     \
,a1,a2                                                                                                     \
)                                                                                                         \
)
/* Produit vectoriel :                                                                       */
/*                                                                                           */
/*                  (b1,b2,b3) = (c1,c2,c3) /\ (a1,a2,a3)                                    */
/*                                                                                           */

#define   NORME(a1,a2,a3)                                                                                                               \
sqrt(((a1)*(a1))+((a2)*(a2))+((a3)*(a3)))
#define   NormalisationVecteur(a1,a2,a3)                                                                                                \
{                                                                                                                   \
double    norme=NORME(a1,a2,a3);                                                                                    \
\
a1 = a1/norme;                                                                                                      \
a2 = a2/norme;                                                                                                      \
a3 = a3/norme;                                                                                                      \
}

int       main()
{
int       calculer=VRAI;

double    X1,X2,X3;
double    Y1,Y2,Y3;
double    Z1,Z2,Z3;
/* Definition d'un nouveeau referentiel 'XYZ' par rapport a l'ancien 'xyz'...                */

double    alpha,beta,gamma;

Z1 = +1;
Z2 = 0;
Z3 = 0;
/* Definition de l'axe 'OZ' (arbitraire...) "autour" duquel on souhaite creer un             */
/* referentiel {OX,OY,OZ} direct et orthornome...                                            */
/*                                                                                           */
/* Cet axe 'OZ' c'est, par exemple, un vecteur tangent a une courbe...                       */

if        (Z1 != 0)
{
Definition_OX(X1,X2,X3,Z1,Z2,Z3);
}
else
{
if        (Z2 != 0)
{
Definition_OX(X2,X3,X1,Z2,Z3,Z1);
}
else
{
if        (Z3 != 0)
{
Definition_OX(X3,X1,X2,Z3,Z1,Z2);
/* Definition de l'axe 'OX' tel qu'il soit orthogonal a l'axe 'OZ' (mais de facon            */
/* arbitraire...).                                                                           */
}
else
{
printf("Le vecteur (Z1,Z2,Z3) est le vecteur nul, le calcul est donc impossible.\n");
calculer=FAUX;
}
}
}

if        (calculer == VRAI)
{
Y1 = ProduitVectoriel_1(Z1,Z2,Z3,X1,X2,X3);
Y2 = ProduitVectoriel_2(Z1,Z2,Z3,X1,X2,X3);
Y3 = ProduitVectoriel_3(Z1,Z2,Z3,X1,X2,X3);
/* Definition de l'axe 'OY' tel qu'il soit orthogonal au plan {OX,OZ} et en faisant que      */
/* le referentiel {OX,OY,OZ} ainsi cree soit direct et orthornome...                         */

NormalisationVecteur(X1,X2,X3);
NormalisationVecteur(Y1,Y2,Y3);
NormalisationVecteur(Z1,Z2,Z3);

printf("OX=(%+f,%+f,%+f)     OY=(%+f,%+f,%+f)     OZ=(%+f,%+f,%+f)\n",X1,X2,X3,Y1,Y2,Y3,Z1,Z2,Z3);
/* Edition du nouveau referentiel {OX,OY,OZ}...                                              */

if        (Z3 != 1)
{
alpha = acos(Z2/sqrt(1-EXP2(Z3)));
beta  = acos(Z3);
gamma = acos(Y3/sqrt(1-EXP2(Z3)));
/* Calcul des trois angles d'Euler {alpha,beta,gamma} dans le cas general...                 */

}
else
{
alpha = acos(X1);
beta  = acos(Z3);
gamma = 0;
/* Cas ou la ligne des noeuds, intersection des plans {Ox,Oy} de l'ancien referentiel        */
/* et {OX,OY} du nouveau, n'est pas definie, ces deux plans etant confondus puisque          */
/* 'Z3=1', ce qui signifie que les deux referentiels {x,y,z} et {X,Y,Z} ont le meme          */
/* troisieme axe ('z' et 'Z')...                                                             */
}

printf("alpha=%f     beta=%f     gamma=%f\n",alpha,beta,gamma);
/* Definition des trois angles d'Euler {alpha,beta,gamma} permettant de passer de l'ancien   */
/* referentiel {x,y,z} au nouveau {X,Y,Z} :                                                  */
/*                                                                                           */
/*                                                                                           */
/*                                    z *                                                    */
/*                                      *                                                    */
/*                                      *                                                    */
/*                                      *                                                    */
/*                                      *                                                    */
/*                                      *                                                    */
/*                                      *                                                    */
/*                                      *     Y                                              */
/*                                      *      .                                             */
/*                                      *                                                    */
/*                         Z +          *     .                                              */
/*                            +         *                                                    */
/*                             +--beta--*    .                                               */
/*                              +       *                                                    */
/*                               +      *   .                . X                             */
/*                                +     *                 .                                  */
/*                                 +    *  .           .                                     */
/*                                  +   *           .                                        */
/*                                   +  * .      .                                           */
/*                                    + *     .                                              */
/*                                     +*  .  |                                              */
/*                                      O* * *g* * * * * * * * * * * * * * * * * * y         */
/*                                    *       a                                              */
/*                                  *     \   m                                              */
/*                                *           m                                              */
/*                              *           \ a                                              */
/*                            *               |                                              */
/*                          *------alpha------\                                              */
/*                        *                                                                  */
/*                      *                       \                                            */
/*                    *                                                                      */
/*                  *                             \                                          */
/*                *                                                                          */
/*            x *                                   \ A                                      */
/*                                                                                           */
/*                                                                                           */
/*                                         OA = {Ox,Oy} .INTER. {OX,OY}                      */
/*                                         (ou "ligne des noeuds")                           */
}
else
{
}
}
```