Мне нужно реализовать такое же поведение, как и в MultipleByInverseOfAttitude из класса CMAttitude iOS. Обратите внимание, что я не могу использовать его напрямую, но у меня есть правильные объекты CMAttitude. Кто-нибудь может указать мне правильное направление?
Как реализуется multipleByInverseOfAttitude (класс CMAttitude)?
Ответы (1)
Поскольку вам не разрешено создавать экземпляр CMAttitude самостоятельно, единственный способ — создать новый кватернион и использовать его для любых дальнейших вычислений. Я рекомендую использовать собственный настраиваемый класс кватернионов вместо простой структуры CMQuaternion. Хорошей отправной точкой является проект cocoamath, где вы можете использовать Quaternion.m, Quaternion.h и QuaternionOperations.m из ствола, и я буду использовать его для этого примера кода.
Сначала вам нужно сохранить экземпляр из комплексного сопряжения вашего эталонный кватернион (взятый из CMAttitude.quaternion
) для использования во всех последующих умножениях, т.е.
МойКласс.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:Tutorials: Использование кватернионов для представления вращения или Силы кватернионов.