Необходим алгоритм трехмерного вращения - PullRequest
3 голосов
/ 31 августа 2010

Учитывая два ортогональных единичных вектора, A и B, и два разных ортогональных единичных вектора C и D, мне нужна косинус-матрица направления 3x3 или кватернион, который будет вращаться A, чтобы совпасть с C, и будет вращаться B, чтобы совпасть с D.

Все векторы являются 3-векторами (x, y, z).

У меня есть алгоритм грубой силы, но я почти уверен, что есть гораздо более простое решение.И мои поиски в Интернете еще не выявили его.

Я использую C #, но если у вас есть что-то в C, или FORTRAN, или Basic (и т. Д.), Я могу преобразовать это.Или я могу использовать математически написанные термины.

Приложение определяет ориентацию, необходимую для космического корабля, поэтому оптическое устройство, жестко прикрепленное к нему, будет правильно выровнено для съемки.(Как направление визирования канала, так и соответствующее вращение оптического устройства относительно визирования канала должны быть достигнуты, поэтому необходимо одновременно выравнивать ДВА вектора.) Вычисление может использоваться в цикле, снабженном данными, полученными в режиме реального времени, иперебор слишком медленный.

Ответы [ 4 ]

3 голосов
/ 31 августа 2010

Я перечитал ваш вопрос, и ответ ниже (хотя и правый) не дает вам то, что вы хотите.Эта ссылка о построении матрицы вращения 3x3 .

, так как они оба являются ортогональными единичными векторами, вам просто нужно добавить еще один, чтобы построить базис (используйте для этого перекрестный продукт).Итак, теперь у вас есть два базиса {A, B, AxB} и {C, D, CxD}.Вращение, которое перемещает {A, B} на {C, D}, будет повторно выражать вектор a1A + a2B + a3 (AXB) как b1C + b2D + b3 (CxD).потому что он линейный, вам нужно только знать, как он ведет себя на основе (это однозначно определяет линейное преобразование).Итак, взяв {A, B, ..} за основу и допустив преобразование равным T, мы видим, что T (1, 0, 0) = C, T (0, 1, 0) = D и T (0,0, 1) = CxD.Помните A = (1, 0, 0) и т. Д. Но столбцы этой матрицы просто M = (C, D, CxD)

Чтобы использовать эту матрицу в том виде, в каком она есть, вы должны выразить каждый вектор вБазис {A, B, CxD} перед тем, как вы ушли влево, умножьте на M. Вы делаете это таким же образом.Фактически, это N - это матрица, которая переводит из вашего обычного базиса в {A, B, ..}, а M выше переводит это в {C, D ...}, тогда MN (умножение слева здесь) будет переводить из вашего базисана {C, D, ..} и укажите желаемое вращение.

Итак, теперь все ваши векторы выражены в базисе {C, D, ..}: (

Решением является еще одна матрица преобразования. Эта карта отображается из {A, B, ..} к вашей основной базе и отменяет N, также известное как обратное и обозначаемое N ^ -1. Таким образом, ваша конечная матрица (N ^ -1) MN. Хорошая новость заключается в том, что, поскольку N ортогонально, вам просто нужноэто транспонирование.

Хитрость заключается в том, чтобы выбрать первичную основу так, чтобы матрицы, с которыми вы имеете дело больше всего, были симпатичными.

1 голос
/ 31 августа 2010

Учитывая, что космические корабли стоят сотни миллионов долларов, вы, возможно, захотите найти кого-то, кто может делать подобные вещи во сне, и попросить их создать пуленепробиваемое и оптимизированное решение с кодом, а не полагаться на описания здесь.(Если это не просто упражнение.)

Кроме того, решение, которое вы выбираете, должно очень сильно зависеть от двигателей, доступных на космическом корабле;Вы хотите, чтобы вращение использовало как можно меньше топлива, и это будет зависеть от того, что они по сути делают с космическим кораблем.Я предполагаю, что вы установили проблему так, чтобы одна ось вращения была вокруг оси z;Можете ли вы вращаться независимо вокруг x и y, или у вас есть только одна ось?Являются ли некоторые повороты более дорогими, чем другие (например, из-за другого момента инерции вдоль некоторых осей)?

Учитывая эти предостережения, я довольно не решаюсь давать советы, такие как: найти (A x C), осьвращения, необходимого для перемещения A на C и вращения (см. Википедию для вращения вдоль оси).Затем выясните, что это делает с B (умножив матрицу вращения на B) и вычислите угол между B и D;наконец, вращайте вдоль оси (B x D) - которая в этой точке лучше совпадает с осью C - чтобы исправить это различие (давая другую матрицу вращения).Mutliply две матрицы, и вуаля, вы сделали.

1 голос
/ 31 августа 2010

https://alleg.svn.sourceforge.net/svnroot/alleg/allegro_outdated/branches/allegro/src/math3d.c

почти полный код для трехмерной графики .... посмотрите функции внизу, начиная с ..

get_align_matrix_f

и то же самое относится и к кватериану ...

https://alleg.svn.sourceforge.net/svnroot/alleg/allegro_outdated/branches/allegro/src/quat.c

также в матрице, он может не дать вам кратчайший (или прямой) путь от Вактора А до С, поэтому, если вы анимируете визуальные эффекты, лучше использовать quats.

0 голосов
/ 16 июня 2014

Несколько позже после оригинального поста, который я знаю, но в случае, если вы тоже страдаете от проблем со столбцами / строками и проблемами с левой / правой рукой, если вы хотите закодировать великолепный результат Марка Т в WPF, вы сделаете это так:

static public Matrix3D TwistToNewAxes(Vector3D A, Vector3D B, Vector3D D, Vector3D E)
    {
        Vector3D C = Vector3D.CrossProduct(B, A);
        Vector3D F = Vector3D.CrossProduct(E, D);

        Matrix3D result = Matrix3D.Identity;

        result.M11 = D.X * A.X + E.X * B.X + F.X * C.X;
        result.M21 = D.X * A.Y + E.X * B.Y + F.X * C.Y;
        result.M31 = D.X * A.Z + E.X * B.Z + F.X * C.Z;
        result.M12 = D.Y * A.X + E.Y * B.X + F.Y * C.X;
        result.M22 = D.Y * A.Y + E.Y * B.Y + F.Y * C.Y;
        result.M32 = D.Y * A.Z + E.Y * B.Z + F.Y * C.Z;
        result.M13 = D.Z * A.X + E.Z * B.X + F.Z * C.X;
        result.M23 = D.Z * A.Y + E.Z * B.Y + F.Z * C.Y;
        result.M33 = D.Z * A.Z + E.Z * B.Z + F.Z * C.Z;

        return result;


    }

Большое спасибо, Марк!

...