Этот пример показывает, как использовать сферическую линейную интерполяцию (SLERP), чтобы создать последовательности кватернионов, и lowpass фильтруют шумные траектории. SLERP является обычно используемым методом компьютерной графики для создания анимаций вращающегося объекта.
Рассмотрите пару кватернионов и
. Сферическая линейная интерполяция позволяет вам создавать последовательность кватернионов, которые отличаются гладко между
и
с постоянной угловой скоростью. SLERP использует параметр интерполяции
h
, который может находиться в интервале между 0 и 1 и определяет, как близко выходной кватернион или к или к
.
Исходная формулировка кватерниона SLERP была дана Кеном Шоемэйком [1] как:
Альтернативная формулировка с синусоидами (используемый в реализации функции slerp
):
где скалярное произведение частей кватерниона. Обратите внимание на то, что
.
Рассмотрите следующий пример. Создайте два кватерниона из Углов Эйлера.
q0 = quaternion([-80 10 0], 'eulerd', 'ZYX', 'frame'); q1 = quaternion([80 70 70], 'eulerd', 'ZYX', 'frame');
Чтобы найти кватернион 30 процентами пути от q0
до q1
, задайте параметр slerp
как 0,3.
p30 = slerp(q0, q1, 0.3);
Чтобы просмотреть представление Угла Эйлера интерполированного кватерниона, используйте функцию eulerd
.
eulerd(p30, 'ZYX', 'frame')
ans = -56.6792 33.2464 -9.6740
Чтобы создать сглаженную траекторию между q0
и q1
, задайте параметр интерполяции slerp
как вектор равномерно расположенных с интервалами чисел между 0 и 1.
dt = 0.01; h = (0:dt:1).'; trajSlerped = slerp(q0, q1, h);
Сравните результаты алгоритма SLERP с траекторией между q0
и q1
, с помощью простой линейной интерполяции (LERP) каждой части кватерниона.
partsLinInterp = interp1( [0;1], compact([q0;q1]), h, 'linear');
Обратите внимание на то, что линейная интерполяция не дает модульные кватернионы, таким образом, они должны быть нормированы.
trajLerped = normalize(quaternion(partsLinInterp));
Вычислите угловые скорости из каждого подхода.
avSlerp = helperQuat2AV(trajSlerped, dt); avLerp = helperQuat2AV(trajLerped, dt);
Постройте оба набора угловых скоростей. Заметьте, что угловая скорость для SLERP является постоянной, но это отличается для линейной интерполяции.
sp = HelperSlerpPlotting; sp.plotAngularVelocities(avSlerp, avLerp);
SLERP производит сглаженное вращение на постоянном уровне.
SLERP может также использоваться, чтобы сделать более комплексные функции. Здесь, SLERP используется к фильтру lowpass шумная траектория.
Вращательный шум может быть создан путем формирования кватерниона из шумного вектора вращения.
rcurr = rng(1);
sigma = 1e-1;
noiserv = sigma .* ( rand(numel(h), 3) - 0.5);
qnoise = quaternion(noiserv, 'rotvec');
rng(rcurr);
Чтобы повредить траекторию trajSlerped
с шумом, инкрементно вращайте траекторию с шумовым векторным qnoise
.
trajNoisy = trajSlerped .* qnoise;
Можно сглаживать сигналы с действительным знаком с помощью однополюсного фильтра формы:
Эта формула по существу говорит, что новое состояние фильтра должно быть перемещено к текущему входу
размером шага, который пропорционален расстоянию между текущим входом и текущим состоянием фильтра
.
Дух этого подхода сообщает, как последовательность кватерниона может быть отфильтрованным lowpass. Для этого и dist
и функции slerp
используются.
Функция dist
возвращает измерение в радианах различия, попеременно примененного двумя кватернионами. Область значений функции dist
является полуоткрытым интервалом [0, пи).
Функция slerp
используется, чтобы регулировать состояние фильтра к текущему входу. Это управляется больше к входу, когда различие между входом и текущим состоянием фильтра имеет большой dist
, и меньше к входу, когда dist
дает маленькое значение. Параметр интерполяции к slerp
находится в закрытом интервале [0,1], таким образом, вывод dist
должен быть повторно нормирован к этой области значений. Однако полный спектр [0,1] для параметра интерполяции дает низкую производительность, таким образом, это ограничивается меньшей областью значений hrange
, сосредоточенный в hbias
.
hrange = 0.4; hbias = 0.4;
Ограничьте low
и high
к интервалу [0, 1].
low = max(min(hbias - (hrange./2), 1), 0); high = max(min(hbias + (hrange./2), 1), 0); hrangeLimited = high - low;
Инициализируйте фильтр и предварительно выделите выходные параметры.
y = trajNoisy(1); % initial filter state qout = zeros(size(y), 'like', y); % preallocate filter output qout(1) = y;
Отфильтруйте шумную траекторию, выборку выборкой.
for ii=2:numel(trajNoisy) x = trajNoisy(ii); d = dist(y, x); % Renormalize dist output to the range [low, high] hlpf = (d./pi).*hrangeLimited + low; y = slerp(y,x,hlpf); qout(ii) = y; end f = figure; sp.plotEulerd(f, trajNoisy, 'o'); sp.plotEulerd(f, trajSlerped, 'k-.', 'LineWidth', 2); sp.plotEulerd(f, qout, '-', 'LineWidth', 2); sp.addAnnotations(f, hrange, hbias);
SLERP может использоваться для создания и короткие траектории между двумя ориентациями и для фильтрации lowpass или сглаживания. Это нашло широкое использование во множестве отраслей промышленности.
Shoemake, Кен. "Анимируя Вращение с Кривыми Кватерниона". Компьютерная графика ACM SIGRAPH 19, № 3 (1985):245-54, doi:10.1145/325165.325242