Я читаю эту книгу, и я столкнулся с этой функцией 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;
}
В этой строке есть ошибка:
if ( fabs( theta ) <= PI ) {
Должен быть
if ( fabs( theta ) > PI ) {
Это единственное условие, при котором вы не можете просто вернуть существующее значение theta
. Остальная часть инструкции if
показывает, сколько раз вам нужно добавить или вычесть 2 * PI, чтобы найти угол, эквивалентный theta
в правильном диапазоне.
Лично я предпочитаю писать отдельные блоки кода для if (theta <= -PI)
и if (theta > PI)
, но, возможно, это предрассудок из-за того, что в прошлом он сталкивался с очень медленной реализацией fabs
.
float
/ double
которые могут не существовать, использовали код fabsf()
?
double
ввода, поэтому предположительно не было преобразований. Это для Visual C ++. Последний тест лично я побежал на VS2010 показал fabs
принимая около половины времени modf
, floor
или ceil
, а также между 25-30% временем sin
или cos
. Гораздо медленнее, чем умножение двух double
переменных.
Он отображает угол тета с (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 ;
}
тета находится в раде
if ( fabs( theta ) > PI )
хотя :-(.
float
, лучше использоватьfabsf()
иfloorf()