Eine Möglichkeit, einen Frame aus einem Vektor zu erstellen, ist Householder transformations. Dies mag kompliziert erscheinen, aber der Code ist ziemlich kurz, mindestens so effizient wie die Verwendung von Kreuzprodukten und weniger anfällig für Rundungsfehler. Außerdem funktioniert genau dieselbe Idee in einer beliebigen Anzahl von Dimensionen.
Die Ideen sind, gegeben einen Vektor v, finden Sie eine Householder - Transformation, die v auf ein Vielfaches von (1,0,0) abbildet, und wenden Sie dann das Inverse davon auf (0,1,0) und (0 , 0,1), um die anderen Rahmenvektoren zu erhalten. Da eine Householder-Transformation eine eigene Umkehrung ist und da sie einfach anzuwenden ist, ist der resultierende Code ziemlich effizient. Unten ist C-Code, den ich verwende:
static void make_frame(const double* v, double* f)
{
double lv = hypot(hypot(v[0], v[1]), v[2]); // length of v
double s = v[0] > 0.0 ? -1.0 : 1.0;
double h[3] = { v[0] - s*lv, v[1], v[2]}; // householder vector for Q
double a = 1.0/(lv*(lv + fabs(v[0]))); // == 2/(h'*h)
double b;
// first frame vector is v normalised
b = 1.0/lv;
f[3*0+0] = b*v[0]; f[3*0+1] = b*v[1]; f[3*0+2] = b*v[2];
// compute other frame vectors by applying Q to (0,1,0) and (0,0,1)
b = -v[1]*a;
f[3*1+0] = b*h[0]; f[3*1+1] = 1.0 + b*h[1]; f[3*1+2] = b*h[2];
b = -v[2]*a;
f[3*2+0] = h[0]*b; f[3*2+1] = b*h[1]; f[3*2+2] = 1.0 + b*h[2];
}
Ich markierte dies als die Antwort, weil es korrekt ist, aber nicht genau das, was ich gesucht habe. Es gibt einen schnelleren Weg, um die Kanten scheinbar zu bekommen. Finde irgendeinen Vektor namens W, der nicht mit V1 ausgerichtet ist. Dann wird V1 x W E1 geben, und V1 x E1 wird E2 ergeben. – user6682440