Чтобы вычислить векторы v и w так, чтобы u, v, w были ортонормированным базисом:
void make_basis3( const double* u, double* v, double* w)
{ double h[3];
double d;
double s = ( u[0] > 0.0) ? 1.0 : -1.0;
double f = s/(s+u[0]);
h[0] = u[0]+s; h[1] = u[1]; h[2] = u[2];
d = f*h[1]; v[0] = -d*h[0]; v[1] = 1.0-d*h[1]; v[2] = -d*h[2];
d = f*h[2]; w[0] = -d*h[0]; w[1] = -d*h[1]; w[2] = 1.0-d*h[2];
}
Здесь предполагается, что длина u равна 1.
Что здесь происходитв том, что первые несколько строк вычисляют вектор h так, что матрица домохозяев, основанная на h (то есть Q = I - 2 * h * h '/ h' * h, где 'является транспонированной), отображает u в (+ -1,0,0) и две последние строки применяют эту матрицу к (0,1,0) для получения v и к (0,0,1) для получения w.Поскольку Q ортогональна и симметрична, u, v, w - ортонормированный базис.
Я думаю, что этот метод предпочтительнее использования перекрестных продуктов, потому что: он короче, он более эффективен, он менее подвержен ошибкам округления иобобщается на более высокие измерения.
Если P - точка, Pv и Pu - координаты P, спроецированные на плоскость, ортогональную к u через начало координат.