Программа, демонстрирующая эффект Джанибекова.
Для запуска программы нажмите на кнопочку (Start). Гайку можно вращать и масштабировать кнопками мышки и роликом.
Эффект Джанибекова заключается в том, что тело, свободно вращающееся в невесомости и имеющее определённые моменты инерции и начальные скорости вращения, ведёт себя следующим образом: сначала оно вращается вокруг одной оси, потом эта ось вдруг неожиданно переворачивается в противоположную сторону, после чего тело продолжает вращаться как и до переворота, потом ось опять переворачивается в противоположную сторону, возвращаясь в исходное положение, и тело опять вращаться как в начале, а потом опять ось переворачивается и так далее.
Поскольку в земных условиях посмотреть на эффект Джанибекова сложно, из-за отсутствия невесомости, то как это происходит можно посмотреть в приведённой программе, которая эффект Джанибекова неплохо моделирует. Делается это так:
Методика моделирования эффекта Джанибекова
В качестве начальных условий нужно задать три момента инерции (Iteration moments) тела. Вместо них можно задать размеры условного параллелепипеда который будем вращать (Cube sides) и плотность его материала (density), тогда его моменты инерции вычисляются по следующим формулам:
1. Ix = density·x·y·z·(y2 + z2) / 12
2. Iy = density·x·y·z·(x2 + z2) / 12
3. Iz = density·x·y·z·(x2 + y2) / 12
Также задаются три начальные скорости вращения по осям (?x, ?y, ?z) в оборотах в секунду. Чтобы превратить их в углы поворотов (?X, ?Y, ?Z), их надо домножить на 2·?.
Далее вычисляются комплексы моментов из формулы Эйлера:
1. Dix = (Iz – Iy) / Ix
2. Diy = (Iz – Iy) / Ix
3. Diz = (Iy – Ix) / Iz
После чего начинается итерирование, то есть последовательное вычисление новых углов поворота, по ним находятся положения осей гайки, по положениям осей рисуется на экране сама гайка, и так продолжается по кругу. Углы поворотов (?X, ?Y, ?Z) вычисляются по таким формулам:
1. ??X = –Dix·?Y·?Z·Speed·?T
2. ??Y = –Dix·?X·?Z·Speed·?T
3. ??Z = –Dix·?X·?Y·Speed·?T
1. ?X = ?X + ??X
2. ?Y = ?Y + ??Y
3. ?Z = ?Z + ??Z
Здесь ?T — время прошедшее с предыдущей итерации, Speed — это параметр в окошке программы, чтобы просто регулировать скорость работы. Если возникают глюки в работе, то надо сделать его поменьше.
Далее надо повернуть объект на указанные углы. Ротации (то куда повёрнут объект в пространстве) в OpenGL задаются матрицами 3x
3. Матрица — это три вектора задающие направления трёх взаимно-перпендикулярные осей объекта. Называются они Right (право, тангаж), Direction (вперёд, крен), Up (вверх, рысканье). Матрица по-умолчанию из этих трёх векторов выглядит так:
Матрица
[ 1 0 0 ] — вектор Right
[ 0 1 0 ] — вектор Direction
[ 0 0 1 ] — вектор Up
Чтобы повернуть эту матрицу на найденные нами углы (?X, ?Y, ?Z), нужно создать три матрицы вращений вокруг осей X, Y и Z и домножить её на них.
Матрицы вращений выглядят так:
Вокруг оси X:
[ 1 0 0 ]
[ 0 cos(?X) –sin(?X) ]
[ 0 sin(?X) cos(?X) ]
Вокруг оси Y:
[ cos(?Y) 0 sin(?YY) ]
[ 0 1 0 ]
[ –sin(?Y) 0 cos(?Y) ]
Вокруг оси Z:
[ cos(?Z) –sin(?Z) 0 ]
[ sin(?Z) cos(?Z) 1 ]
[ 0 0 0 ]
Угол alfa здесь — это соответственно углы (?X, ?Y, ?Z).
Получив три матрицы вращений последовательно умножаем их на матрицу гайки. Делается это по следующим формулам.
1. ResultMatrix[0, 0] = M1[0, 0]·M2[0, 0] + M1[0, 1]·M2[1, 0] + M1[0, 2]·M2[2, 0]
2. ResultMatrix[0, 1] = M1[0, 0]·M2[0, 1] + M1[0, 1]·M2[1, 1] + M1[0, 2]·M2[2, 1]
3. ResultMatrix[0, 2] = M1[0, 0]·M2[0, 2] + M1[0, 1]·M2[1, 2] + M1[0, 2]·M2[2, 2]
4. ResultMatrix[1, 0] = M1[1, 0]·M2[0, 0] + M1[1, 1]·M2[1, 0] + M1[1, 2]·M2[2, 0]
5. ResultMatrix[1, 1] = M1[1, 0]·M2[0, 1] + M1[1, 1]·M2[1, 1] + M1[1, 2]·M2[2, 1]
6. ResultMatrix[1, 2] = M1[1, 0]·M2[0, 2] + M1[1, 1]·M2[1, 2] + M1[1, 2]·M2[2, 2]
7. ResultMatrix[2, 0] = M1[2, 0]·M2[0, 0] + M1[2, 1]·M2[1, 0] + M1[2, 2]·M2[2, 0]
8. ResultMatrix[2, 1] = M1[2, 0]·M2[0, 1] + M1[2, 1]·M2[1, 1] + M1[2, 2]·M2[2, 1]
9. ResultMatrix[2, 2] = M1[2, 0]·M2[0, 2] + M1[2, 1]·M2[1, 2] + M1[2, 2]·M2[2, 2]
Здесь M1 — это исходная матрица, а М2 — матрицы вращений, сначала первая, потом вторая, потом третья. Получив результат, мы получаем новые положения осей гайки в пространстве.
Интересные начальные условия
Если поставить стороны куба (Cube sides) в 10, 10, 1, то характер вращения изменится. Гайка уже не будет резко переворачиваться, а её ось вращения будет периодически плавно переходить из зелёной в красную, и из красной в зелёную, при этом синяя ось будет двигаться строго по кругу, в чём легко убедиться включив в программе опцию (Lines).
Если выставить стороны куба в 10, 1, 1, то будет происходить примерно тоже самое, только меняться местами будут уже не зелёная и красная, а зелёная и синяя оси.
Выставлять скорость слишком большой нельзя, потому, что тогда омеги начнут рости, и когда превысят предел допустимый для вещественных чисел, программа это зафиксирует и остановится. В прочем это можно изменить изменив параметр (Stop on error) c omega на none.
Если интересно посмотреть расчёты, то это можно сделать поставив галочку (Type log) и заглянув на закладку (Log). Отслеживать расчёты удобнее в пошаговом режиме (Step by step running), нажимая на кнопку (Step) для расчёта следующего шага.
Для запуска программы нажмите на кнопочку (Start). Гайку можно вращать и масштабировать кнопками мышки и роликом.
Эффект Джанибекова заключается в том, что тело, свободно вращающееся в невесомости и имеющее определённые моменты инерции и начальные скорости вращения, ведёт себя следующим образом: сначала оно вращается вокруг одной оси, потом эта ось вдруг неожиданно переворачивается в противоположную сторону, после чего тело продолжает вращаться как и до переворота, потом ось опять переворачивается в противоположную сторону, возвращаясь в исходное положение, и тело опять вращаться как в начале, а потом опять ось переворачивается и так далее.
Поскольку в земных условиях посмотреть на эффект Джанибекова сложно, из-за отсутствия невесомости, то как это происходит можно посмотреть в приведённой программе, которая эффект Джанибекова неплохо моделирует. Делается это так:
Методика моделирования эффекта Джанибекова
В качестве начальных условий нужно задать три момента инерции (Iteration moments) тела. Вместо них можно задать размеры условного параллелепипеда который будем вращать (Cube sides) и плотность его материала (density), тогда его моменты инерции вычисляются по следующим формулам:
1. Ix = density·x·y·z·(y2 + z2) / 12
2. Iy = density·x·y·z·(x2 + z2) / 12
3. Iz = density·x·y·z·(x2 + y2) / 12
Также задаются три начальные скорости вращения по осям (?x, ?y, ?z) в оборотах в секунду. Чтобы превратить их в углы поворотов (?X, ?Y, ?Z), их надо домножить на 2·?.
Далее вычисляются комплексы моментов из формулы Эйлера:
1. Dix = (Iz – Iy) / Ix
2. Diy = (Iz – Iy) / Ix
3. Diz = (Iy – Ix) / Iz
После чего начинается итерирование, то есть последовательное вычисление новых углов поворота, по ним находятся положения осей гайки, по положениям осей рисуется на экране сама гайка, и так продолжается по кругу. Углы поворотов (?X, ?Y, ?Z) вычисляются по таким формулам:
1. ??X = –Dix·?Y·?Z·Speed·?T
2. ??Y = –Dix·?X·?Z·Speed·?T
3. ??Z = –Dix·?X·?Y·Speed·?T
1. ?X = ?X + ??X
2. ?Y = ?Y + ??Y
3. ?Z = ?Z + ??Z
Здесь ?T — время прошедшее с предыдущей итерации, Speed — это параметр в окошке программы, чтобы просто регулировать скорость работы. Если возникают глюки в работе, то надо сделать его поменьше.
Далее надо повернуть объект на указанные углы. Ротации (то куда повёрнут объект в пространстве) в OpenGL задаются матрицами 3x
3. Матрица — это три вектора задающие направления трёх взаимно-перпендикулярные осей объекта. Называются они Right (право, тангаж), Direction (вперёд, крен), Up (вверх, рысканье). Матрица по-умолчанию из этих трёх векторов выглядит так:
Матрица
[ 1 0 0 ] — вектор Right
[ 0 1 0 ] — вектор Direction
[ 0 0 1 ] — вектор Up
Чтобы повернуть эту матрицу на найденные нами углы (?X, ?Y, ?Z), нужно создать три матрицы вращений вокруг осей X, Y и Z и домножить её на них.
Матрицы вращений выглядят так:
Вокруг оси X:
[ 1 0 0 ]
[ 0 cos(?X) –sin(?X) ]
[ 0 sin(?X) cos(?X) ]
Вокруг оси Y:
[ cos(?Y) 0 sin(?YY) ]
[ 0 1 0 ]
[ –sin(?Y) 0 cos(?Y) ]
Вокруг оси Z:
[ cos(?Z) –sin(?Z) 0 ]
[ sin(?Z) cos(?Z) 1 ]
[ 0 0 0 ]
Угол alfa здесь — это соответственно углы (?X, ?Y, ?Z).
Получив три матрицы вращений последовательно умножаем их на матрицу гайки. Делается это по следующим формулам.
1. ResultMatrix[0, 0] = M1[0, 0]·M2[0, 0] + M1[0, 1]·M2[1, 0] + M1[0, 2]·M2[2, 0]
2. ResultMatrix[0, 1] = M1[0, 0]·M2[0, 1] + M1[0, 1]·M2[1, 1] + M1[0, 2]·M2[2, 1]
3. ResultMatrix[0, 2] = M1[0, 0]·M2[0, 2] + M1[0, 1]·M2[1, 2] + M1[0, 2]·M2[2, 2]
4. ResultMatrix[1, 0] = M1[1, 0]·M2[0, 0] + M1[1, 1]·M2[1, 0] + M1[1, 2]·M2[2, 0]
5. ResultMatrix[1, 1] = M1[1, 0]·M2[0, 1] + M1[1, 1]·M2[1, 1] + M1[1, 2]·M2[2, 1]
6. ResultMatrix[1, 2] = M1[1, 0]·M2[0, 2] + M1[1, 1]·M2[1, 2] + M1[1, 2]·M2[2, 2]
7. ResultMatrix[2, 0] = M1[2, 0]·M2[0, 0] + M1[2, 1]·M2[1, 0] + M1[2, 2]·M2[2, 0]
8. ResultMatrix[2, 1] = M1[2, 0]·M2[0, 1] + M1[2, 1]·M2[1, 1] + M1[2, 2]·M2[2, 1]
9. ResultMatrix[2, 2] = M1[2, 0]·M2[0, 2] + M1[2, 1]·M2[1, 2] + M1[2, 2]·M2[2, 2]
Здесь M1 — это исходная матрица, а М2 — матрицы вращений, сначала первая, потом вторая, потом третья. Получив результат, мы получаем новые положения осей гайки в пространстве.
Интересные начальные условия
Если поставить стороны куба (Cube sides) в 10, 10, 1, то характер вращения изменится. Гайка уже не будет резко переворачиваться, а её ось вращения будет периодически плавно переходить из зелёной в красную, и из красной в зелёную, при этом синяя ось будет двигаться строго по кругу, в чём легко убедиться включив в программе опцию (Lines).
Если выставить стороны куба в 10, 1, 1, то будет происходить примерно тоже самое, только меняться местами будут уже не зелёная и красная, а зелёная и синяя оси.
Выставлять скорость слишком большой нельзя, потому, что тогда омеги начнут рости, и когда превысят предел допустимый для вещественных чисел, программа это зафиксирует и остановится. В прочем это можно изменить изменив параметр (Stop on error) c omega на none.
Если интересно посмотреть расчёты, то это можно сделать поставив галочку (Type log) и заглянув на закладку (Log). Отслеживать расчёты удобнее в пошаговом режиме (Step by step running), нажимая на кнопку (Step) для расчёта следующего шага.