Drehung eines Vektors in Richtung eines anderen Vektors

Figure: Drehung des Vektors $\vec{EP}$ in Richtung des anderen Vektors $\vec{AP}$
\includegraphics[width=9cm]{HTMLBilder/Drehungen3D}

Eine Drehung, die einen Anfangspunkt $\vec{AP}$ in einen Endpunkt $\vec{EP} \frac{\left\vert \vec{AP} \right\vert }{ \left\vert \vec{EP} \right\vert} $ überführt und die durch den Punkt $\vec{T} $ gehende Drehachse $\vec{V} = (\vec{AP}-\vec{T}) \times (\vec{EP}-\vec{T}) $ hat, kann wie folgt ausgeführt werden.

$\displaystyle \vec{EP} = \vec{T} + M \left(\vec{AP}-\vec{T} \right)
\frac{\left\vert \vec{EP}-\vec{T} \right\vert }{ \left\vert \vec{AP}-\vec{T} \right\vert}$     (1.24)

Dabei ist $M$ eine Drehmatrix für eine Drehung um den Ursprung. Wie in Abbildung [*] von links nach rechts dargestellt wird zunächst die Drehachse in den Ursprung verschoben, dann die Drehung ausgeführt und dann alles wieder um die ursprüngliche Strecke zurckgeschoben. Bleibt nur noch die Bestimmung der Matrixelemente von M und die Aufgabe ist allgemein gelöst. Der zu $M$ gehörende Drehwinkel $\varphi$ beträgt

$\displaystyle \cos\varphi = \frac{(\vec{AP}-\vec{T}) (\vec{EP}-\vec{T})}{\left\...
...vec{EP}-\vec{T} \right\vert }
\qquad
\sin\varphi = \sqrt[]{1-\cos^2\varphi}
$

Um diese Drehung auszufhren benötigt man jeden Richtungskosinus der Drehachse

$\displaystyle c_{x} = \frac{V_{x}}{\left\vert \vec{V} \right\vert} \qquad
c_{y...
...ght\vert} \qquad
c_{z} = \frac{V_{z}}{\left\vert \vec{V} \right\vert} \qquad
$

$\displaystyle d = \sqrt[]{c_{y}^2 + c_{z}^2}
$

Durch Vertauschen der Koordinaten kann man verhindern, daß $d=0$ ist.

$\displaystyle c\alpha = \frac{c_{z}}{d} \qquad s\alpha = \frac{c_{y}}{d} \qquad c\beta = d \qquad s\beta = c_{x}
$

Damit haben wir schon alle elementaren Matrixelemente gebildet. Mit ihrer Hilfe drehen wir zunächst das Koordinatensystem so, daß wir die Drehung von $\vec{AP}-\vec{T} $ nach $\vec{EP}-\vec{T} $ um die $\vec{e}_{z}$ - Achse des gedrehten Koordinatensystems ausführen können. Anschließend wird das ganze System wieder zurückgedreht. Diese Drehmatrix sieht aus wie folgt.
$\displaystyle M = D_{\vec{e}_{x}} D_{\vec{e}_{y}} D_{\vec{e}_{z}}\left( \varphi \right) D_{\vec{e}_{y}}^{-1} D_{\vec{e}_{x}}^{-1}$     (1.25)

oder ausgeschrieben :
\begin{displaymath}M=
\left[
\begin{array}{ccc}
1 & 0 & 0 \\ 0 & c\alpha & -s\al...
...lpha & s\alpha \\ 0 & -s\alpha & c\alpha \\
\end{array}\right]\end{displaymath}     (1.26)


$\displaystyle m_{1,1}$ $\displaystyle =$ $\displaystyle c\beta^2 \; \cos \varphi + s\beta^2$  
$\displaystyle m_{2,2}$ $\displaystyle =$ $\displaystyle c\alpha^2 \; \cos \varphi + s\alpha^2 \; s\beta^2 \; \cos \varphi + s\alpha^2 \; c\beta^2$  
$\displaystyle m_{3,3}$ $\displaystyle =$ $\displaystyle s\alpha^2 \; \cos \varphi + c\alpha^2 \; s\beta^2 \; \cos \varphi + c\alpha^2 \; c\beta^2$  
$\displaystyle m_{1,2}$ $\displaystyle =$ $\displaystyle s\alpha \; c\beta \; s\beta \left( 1- \cos \varphi \right) - c\alpha \; c\beta \; \sin \varphi$  
$\displaystyle m_{2,1}$ $\displaystyle =$ $\displaystyle s\alpha \; c\beta \; s\beta \left( 1- \cos \varphi \right) + c\alpha \; c\beta \; \sin \varphi$  
$\displaystyle m_{2,3}$ $\displaystyle =$ $\displaystyle c\alpha \; s\alpha \; c\beta^2 \left(1 - \cos \varphi \right) - s\beta \; \sin \varphi$  
$\displaystyle m_{3,2}$ $\displaystyle =$ $\displaystyle c\alpha \; s\alpha \; c\beta^2 \left(1 - \cos \varphi \right) + s\beta \; \sin \varphi$  
$\displaystyle m_{1,3}$ $\displaystyle =$ $\displaystyle c\alpha \; c\beta \; s\beta \left( 1- \cos \varphi \right) + s\alpha \; c\beta \; \sin \varphi$  
$\displaystyle m_{3,1}$ $\displaystyle =$ $\displaystyle c\alpha \; c\beta \; s\beta \left( 1- \cos \varphi \right) - s\alpha \; c\beta \; \sin \varphi$  

und es gilt:

$\displaystyle \left\vert M \right\vert = 1
\qquad \qquad
M ( \vec{AP}-\vec{T}...
...vert \vec{EP}-\vec{T} \right\vert }{ \left\vert \vec{AP}-\vec{T} \right\vert}
$

Folgende Prozedur bildet die Matrixelemente von M.
void  mbld(double *V_1 ,double *V_2 ,double *M_A){ //feldpointer Drehmatrix A (9 Elemente!)
double ca, sa, cb, sb, cd, sd, cx, cy, cz, vb, DV, Rx, Ry, Rz, temp1, temp2;
//******** Kreuzprodukt der beiden Vektoren ist Drehachse *****************
Rx = *(V_1+1) * *(V_2+2) - *(V_1+2) * *(V_2+1);// y1 * z2 - y2 * z1
Ry = *(V_1+2) * *(V_2)   - *(V_1)   * *(V_2+2);// z1 * x2 - z2 * x1
Rz = *(V_1)   * *(V_2+1) - *(V_1+1) * *(V_2)  ;// x1 * y2 - x2 * y1
if(Ry == 0 && Rz == 0){Rz = 1;};
//'******** Winkel zwischen beiden Vektoren ist Drehwinkel um diese Achse **
temp1 = *(V_1) * *(V_2) + *(V_1+1) * *(V_2+1) + *(V_1+2) * *(V_2+2) ;
temp2 = sqrt(*(V_1) * *(V_1) + *(V_1+1) * *(V_1+1) + *(V_1+2) * *(V_1+2))
      * sqrt(*(V_2) * *(V_2) + *(V_2+1) **(V_2+1) + *(V_2+2) * *(V_2+2)) ; //  'Betraege multipliziert
cd = temp1 / temp2  ;                                                      //  'Cosinus des Drehwinkels
sd = sqrt(fabs(1.0 - cd * cd)) ;                                           //  'Sinus des Drehwinkels
//'******** Im Folgenden Bestimmung der Drehachse  **********
vb = sqrt(Rx *Rx + Ry *Ry + Rz *Rz);
cx = Rx / vb ; cy = Ry / vb ; cz = Rz / vb  ;                              //  'Richtungscosinus und sinus der Drehachse
DV = sqrt(cy * cy + cz *cz);
ca = cz / DV; sa = cy / DV; cb = DV; sb = cx ;                             //  'Cosinusterme zur Drehung um x und y Achse
//'**** Matrixelemente Drehung von Vektor x1,y1,z2 in den Vektor x2,y2,z2 **
temp1 = sa * cb * sb * (1 - cd); temp2 = ca * cb * sd;
*(M_A+1)   = temp1 - temp2;
*(M_A+3) = temp1 + temp2;
temp1 = ca * sa * cb * cb * (1 - cd);
temp2 = sb * sd;
*(M_A+5) = temp1 - temp2; *(M_A+7) = temp1 + temp2;
temp1 = ca * cb * sb * (1 - cd);
temp2 = sa * cb * sd;
*(M_A+6) = temp1 - temp2; *(M_A+2) = temp1 + temp2;
*(M_A+0) = cb * cb * cd + sb *sb;
*(M_A+4) = ca * ca * cd + sa * sa * sb * sb * cd + sa * sa * cb * cb;
*(M_A+8) = sa * sa * cd + ca * ca * sb * sb * cd + ca * ca * cb * cb;
};
Und folgende Routine stellt die Determinante auf 1.
void  mdet1(double *MP){
  if(*(MP+1) * *(MP+3) - *(MP) * *(MP+4) != 0)
  {
    *(MP+8) =
 ( *(MP+1) * *(MP+5) * *(MP+6) + *(MP+2) * *(MP+3) * *(MP+7)
 - *(MP+2) * *(MP+4) * *(MP+6) - *(MP)   * *(MP+5) * *(MP+7) - 1.0)
 / (*(MP+1) * *(MP+3) - *(MP) * *(MP+4));
}};
Damit haben wir die Mathematik zusammen, um eine aus dreidimensionalen Koordinaten bestendende Geometrie am Bildschirm zu drehen. Eingegebene Eckpunkte werden in einer Liste gespeichert. Aus Mausaktionen werden die Elemente der Drehmatrix bestimmt und die Determinante anschließend zu 1 gemacht. Über eine Matrixmultiplikation wird eine, nun gedrehte, Kopie der Liste von Eckpunkten geschrieben. Von dieser Kopie werden dann 2 der 3 Dimensionen am Bildschirm ausgegeben. Vorteil des Verfahrens ist, daß wir stets die unveränderte Datenbasis verwenden und sich damit keine Rundungsfehler aufsummieren. Die unveränderte Datenbasis kann im Original manipuliert oder gespeichert werden.