Как реализован multiplyByInverseOfAttitude (класс CMAttitude)?

Мне нужно реализовать то же поведение, которое используется multiplyByInverseOfAttitude из класса CMAttitude iOS. Обратите внимание, что я не могу использовать его напрямую, но у меня есть нужные объекты CMAttitude. Кто-нибудь может указать мне правильное направление?

1 ответ

Решение

Поскольку вам не разрешено создавать экземпляр CMAttitude самостоятельно, единственный способ - создать новый кватернион и использовать его для любых дальнейших вычислений. Я рекомендую использовать ваш собственный настроенный класс кватернионов вместо простой структуры CMQuaternion. Хорошей отправной точкой является проект cocoamath, в котором вы можете взять Quaternion.m, Quaternion.h и QuaternionOperations.m из транка, и я буду использовать его для этого примера кода.

Сначала вы должны сохранить экземпляр из комплексного сопряжения вашего эталонного кватерниона (взят из CMAttitude.quaternion) использовать для всех последующих умножений, т.е.

MyClass.h

Quaternion* inverseReferenceQuaternion;

MyClass.c

// initialising code run only once after each call to [motionManager startDeviceMotionUpdates];
CMAttitude firstAttitude = [motionManager deviceMotion].attitude;
CMQuaternion q = firstAttitude.quaternion;
inverseReferenceQuaternion = [[Quaternion alloc] initWithRe:q.w i:-q.x j:-q.y k:-q.z];

В вашем цикле таймера (или блока обработчика) вам нужно умножение кватернионов:

// on every update
CMAttitude attitude = [motionManager deviceMotion].attitude;
CMQuaternion current = attitude.quaternion;
Quaternion currentMultiplied = initAsProductOf:inverseReferenceQuaternion And:current

Сейчас currentMultiplied должен содержать то, что вы ищете.

Кватернионы хороши, если вы новичок в этом предмете, но стоит прочитать некоторые учебные пособия, такие как, например, OpenGL: Учебники: использование кватернионов для представления вращения или кватернионных сил.

Другие вопросы по тегам