Итак, у меня есть радианные углы без какого-либо диапазона (в основном от -inf до + inf), и мне нужно как можно быстрее их интерполировать. Есть ли какой-нибудь способ сделать это?
PS: мне нужно только интерполировать 2 значения за раз, так что a + f * (b-a) в основном
PPS: выход НЕ ДОЛЖЕН быть в каком-то определенном диапазоне (от -PI до PI или от 0 до 2PI)
PPPS: Конкретная проблема заключается в том, как наиболее эффективно сделать перенос значений вокруг -PI / + PI и их кратных.
ЛУЧШЕ На самом деле забудь, что я написал первым. Вы можете просто сделать:
template<typename K>
K lerpAngle(K u, K v, K p) {
return u + p*wrapMP(v - u);
}
где wrapMP
перемещает угол к интервалу [-pi | + pi]. Оба входа u
а также v
может быть любым радианым углом, и результат также не будет в определенном интервале.
Идея на самом деле довольно проста. Переместите свою точку зрения в точку u
такой, что u=0
, Сейчас v
может быть произвольным, поскольку углы не нормированы, но мы просто обернуть расстояние v-u = v
на [-pi | + pi] и пройти на заданный процент p
в этом направлении.
СТАРЫЙ (и неэффективный) Я написал этот код один раз:
template<typename K>
K lerpAngle(K u, K v, K p) {
K a = wrap2Pi(u);
K b = wrap2Pi(v);
K d = b - a;
if(d < -PI) {
b += 2*PI;
}
if(d > +PI) {
b -= 2*PI;
}
return wrap2Pi(a + p*(b - a));
}
где wrap2i
сдвигает угол к интервалу [0,2 * пи [.
Сначала «нормализуйте» входные углы, чтобы они находились в определенном диапазоне, например (-π, π]
, Если вы уже делаете это, пропустите эту часть.
Тогда возьмите их разницу. Если абсолютное значение этой разности больше, чем π
затем отрегулируйте один из входов, добавив / вычитая 2π
так что абсолютное значение разности становится меньше или равно π
,
Затем просто интерполируйте между этими двумя значениями.
Если результат этой интерполяции всегда должен быть в диапазоне (-π, π]
еще раз (примечание: вероятно, это не обязательно, в зависимости от того, где вам нужен этот угол), затем добавьте / вычтите 2π
еще раз, если это не так.