Kinect SDK - преобразование угла поворота по градусам

Я достаточно новичок в разработке Kinect и пытаюсь создать компонент, который позволяет вращать суставы Kinect. Цель этого состоит в том, чтобы вручную «исправить» любые данные скелета, которые я захватил, после захвата, когда скелет начинает прыгать.

Я показываю скелет Kinect в трехмерном пространстве с помощью набора инструментов helix. Я могу приостановить поток скелета в любой заданной точке и увидеть значения матрицы, содержащиеся в объекте BoneRotations для AbsoluteRotation и HierarchicalRotation.

Я создал три ползунка, которые представляют ось X, ось Y и ось Z. Я установил их минимальные / максимальные значения на то, что имеет отношение к естественному движению кости, которым нужно управлять (например, на Yaxis плечо не перемещается выше примерно 40 градусов). Если мы возьмем плечевой (правый) сустав в качестве примера, я хочу иметь возможность применять вращения по каждой оси, чтобы я мог изменять положение кости в трехмерном пространстве. Я считаю, что терминология, относящаяся к этому виду действий, - это прямая кинематика.

Мои вопросы:

а) Kinect SDK предоставляет абсолютную и иерархическую матрицу для сустава. На что я должен смотреть, чтобы манипулировать?

б) Что дает вам Quaternion, чего нет в матрице?

c) Как мне взять информацию о матрице 4x4 и найти угол (в градусах или радианах) для оси X, оси Y и оси Z?

г) Я видел, как преобразовывать матрицы 3x3, умножая их, используя такой расчет:

    Matrix3X3 matrixx = new Matrix3X3();
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            matrixx.elements[(i * 3) + j] = ((R2.elements[i * 3] * R1.elements[j]) + (R2.elements[(i * 3) + 1] * R1.elements[3 + j])) + (R2.elements[(i * 3) + 2] * R1.elements[6 + j]);
        }
    }
    return matrixx;

Как преобразовать матрицу 4x4, предоставленную Kinect SDK?

Более конкретно, могу ли я преобразовать матрицу 4x4 на каждой оси, чтобы у меня был ползунок для каждой оси? Итак, как мне применить поворот оси X на 10 градусов? Я видел следующие повороты матриц 3x3:

    public static Matrix3D NewRotateAroundX(double radians)
    {
        var matrix = new Matrix3D();
        matrix._matrix[1, 1] = Math.Cos(radians);
        matrix._matrix[1, 2] = Math.Sin(radians);
        matrix._matrix[2, 1] = -(Math.Sin(radians));
        matrix._matrix[2, 2] = Math.Cos(radians);
        return matrix;
    }
    public static Matrix3D NewRotateAroundY(double radians)
    {
        var matrix = new Matrix3D();
        matrix._matrix[0, 0] = Math.Cos(radians);
        matrix._matrix[0, 2] = -(Math.Sin(radians));
        matrix._matrix[2, 0] = Math.Sin(radians);
        matrix._matrix[2, 2] = Math.Cos(radians);
        return matrix;
    }
    public static Matrix3D NewRotateAroundZ(double radians)
    {
        var matrix = new Matrix3D();
        matrix._matrix[0, 0] = Math.Cos(radians);
        matrix._matrix[0, 1] = Math.Sin(radians);
        matrix._matrix[1, 0] = -(Math.Sin(radians));
        matrix._matrix[1, 1] = Math.Cos(radians);
        return matrix;
    }

Заранее благодарим за помощь!


person Rob McCabe    schedule 06.12.2013    source источник


Ответы (1)


Это несколько вопросов, и вам, вероятно, следует разбить их и задать каждый отдельно.

а) Я не играл с Kinect, но, вообще говоря, абсолютное относится к мировому пространству, а иерархическое относится к родительскому. В большинстве случаев вы хотите переместить сустав относительно его родителя.

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

c) Первые 3 элемента первых 3 строк в матрице дают вам каждую ось, то есть X, Y и Z (опять же либо в мировом пространстве, либо в родительском пространстве, в зависимости от того, с каким из них вы работаете). Извлеките их, выберите 2, которые вам нужны, и Google "угол между любыми двумя 3D линиями" (это обратный косинус скалярного произведения между ними).

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

person Mark Feldman    schedule 09.12.2013
comment
Спасибо за это, Марк. Ответ А имеет смысл. Вопрос B. ›Я знаю, что вы не особо знакомы с Kinect SDK, но он дает Quaternion, поэтому я просто не понимаю, что он содержит. На какой оси основана информация о его вращении? (может быть, просто мое непонимание). Вопрос C- ›Думаю, я смогу с этим разобраться, спасибо. Вопрос D - ›Пора читать и понимать! :-) - person Rob McCabe; 09.12.2013
comment
Существует множество руководств, которые объясняют кватернионы гораздо более подробно, чем я могу здесь, хороший - cprogramming.com/tutorial/3d/quaternions.html. Кватернион состоит из 4 компонентов (XYZW) и обычно используется для вращения, т.е. поворота точки вокруг линии P1 = ‹0,0,0› и P2 = ‹X, Y, Z› и поворота на W радиан. Как показано в этой статье, вы можете преобразовать кватернион в матрицу, хотя вы не всегда можете преобразовать матрицу в кватернион, потому что у нее могут быть другие вещи, такие как перевод и т. Д. - person Mark Feldman; 10.12.2013
comment
Все это вызывает вопрос: зачем вообще использовать кватерионы? Кватернионы имеют математические операции так же, как и матрицы, но если вы имеете дело только с поворотами, математика кватернионов имеет тенденцию быть немного проще и быстрее. Тем не менее, я проработал 16 лет программистом 3D-графики и особо не использовал их, кроме случаев, когда мне нужно было импортировать их откуда-то еще, как вы сейчас. Если у вас есть хорошая библиотека матриц, и ваше приложение не критично по времени, просто преобразуйте их в матрицы и используйте обычные матричные операции для всего, вы сэкономите много головной боли IMO. - person Mark Feldman; 10.12.2013
comment
Спасибо за помощь, Марк! - person Rob McCabe; 10.12.2013