Это правильный код для переноса угла (-180,180]

0

Я читаю эту книгу, и я столкнулся с этой функцией wrapPi(). Я знаю, как обернуть угол, но то, что именно этот код делает

float wrapPi ( float theta ) {
// Check if already in range. This is not strictly necessary,
// but it will be a very common sit u a t i o n . We don  t want to
// incur a speed hit and perhaps floating precision loss if
// its not necessary
if ( fabs( theta ) <= PI ) {
    // One revolution is 2PI .
    const float TWOPPI = 2.0f∗PI ;
    // Out of range. Determine how many "revolutions"
    // we need to add .
    float revolutions = floor (( theta + PI ) ∗ ( 1.0f /TWOPPI )) ;
    // Subtract it off
    theta −= revolutions ∗ TWOPPI ;
}
return theta;
}
  • 0
    пожалуйста, укажите, если тета в градусах или в радианах
  • 0
    Примечание: если код использует float , лучше использовать fabsf() и floorf()
Показать ещё 1 комментарий
Теги:
angle
wrap

2 ответа

2

В этой строке есть ошибка:

if ( fabs( theta ) <= PI ) {

Должен быть

if ( fabs( theta ) > PI ) {

Это единственное условие, при котором вы не можете просто вернуть существующее значение theta. Остальная часть инструкции if показывает, сколько раз вам нужно добавить или вычесть 2 * PI, чтобы найти угол, эквивалентный theta в правильном диапазоне.

Лично я предпочитаю писать отдельные блоки кода для if (theta <= -PI) и if (theta > PI), но, возможно, это предрассудок из-за того, что в прошлом он сталкивался с очень медленной реализацией fabs.

  • 0
    "очень медленная реализация fabs" Хм, это из-за того, что преобразования float / double которые могут не существовать, использовали код fabsf() ?
  • 0
    Проблема, которую я наблюдал, на самом деле заключалась в использовании double ввода, поэтому предположительно не было преобразований. Это для Visual C ++. Последний тест лично я побежал на VS2010 показал fabs принимая около половины времени modf , floor или ceil , а также между 25-30% временем sin или cos . Гораздо медленнее, чем умножение двух double переменных.
Показать ещё 1 комментарий
0

Он отображает угол тета с (theta <= -pi || theta> = pi) в диапазон -pi... pi.

// if false theta is already >=-PI && <=PI
if ( fabs( theta ) <= PI ) {
    // This is the range between -PI and PI
    const float TWOPPI = 2.0f∗PI ;

    // The next two steps are kind of an floating point modulo(theta,2PI)
    float revolutions = floor (( theta + PI ) ∗ ( 1.0f /TWOPPI )) ;
    theta −= revolutions ∗ TWOPPI ;
}

тета находится в раде

  • 0
    Тривиально, это не так. Если theta = 2 pi, условие является пропущенным, и функция возвращает theta (= 2 pi)
  • 0
    @ Олотиар Блин - ты прав! Насколько я вижу, (1) оставляет все тета> = 0 такими, какие они есть (хотя он и делает некоторые ненужные вычисления, если тета находится в диапазоне 0 ... PI). (2) отображает каждый тэта <0 &&> -PI в диапазон> 2 * PI и (3) еще раз оставляет каждый тэта <= - PI как есть. Было бы намного лучше с if ( fabs( theta ) > PI ) хотя :-(.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню