|
|||||||
Нормировка угла на диапазон 0-360 и -180/+180 на языке C/C++
Время создания: 21.02.2018 13:26
Текстовые метки: язык Си, c++, угол, нормировка, нормализация, диапазон
Раздел: Компьютер - Программирование - Алгоритмы
Запись: xintrea/mytetra_syncro/master/base/15192088058hw46jy9cz/text.html на raw.github.com
|
|||||||
|
|||||||
Пример кода, который нормализует (ограничивает) угол в указанном диапазоне. Если значение выходит за диапазон, угол пересчитывается так, чтобы "визуально" он остался прежним, но его значение укладывалось бы в заданный диапазон. #include <iostream> #include <cmath> using namespace std; // Диапазон (0, 360) double constrainAngle360(double x) { x = fmod(x ,360.0); if (x < 0.0) x += 360.0; return x; } // Диапазон (-180, +180) double constrainAngle180(double x) { x = fmod(x + 180.0, 360.0); if (x < 0.0) x += 360.0; return x - 180.0; } int main() { cout << "Constrain 360:" << "\n";
cout << 0.5 << " : " << constrainAngle360(0.5) << "\n"; cout << 10 << " : " << constrainAngle360(10) << "\n"; cout << 380 << " : " << constrainAngle360(380) << "\n"; cout << 730 << " : " << constrainAngle360(730) << "\n"; cout << 730.5 << " : " << constrainAngle360(730.5) << "\n"; cout << -0.5 << " : " << constrainAngle360(-0.5) << "\n"; cout << -10 << " : " << constrainAngle360(-10) << "\n"; cout << -380 << " : " << constrainAngle360(-380) << "\n"; cout << -730 << " : " << constrainAngle360(-730) << "\n"; cout << -730.5 << " : " << constrainAngle360(-730.5) << "\n"; cout << "Constrain 180:" << "\n";
cout << 0.5 << " : " << constrainAngle180(0.5) << "\n"; cout << 10 << " : " << constrainAngle180(10) << "\n"; cout << 380 << " : " << constrainAngle180(380) << "\n"; cout << 730 << " : " << constrainAngle180(730) << "\n"; cout << 730.5 << " : " << constrainAngle180(730.5) << "\n"; cout << -0.5 << " : " << constrainAngle180(-0.5) << "\n"; cout << -10 << " : " << constrainAngle180(-10) << "\n"; cout << -380 << " : " << constrainAngle180(-380) << "\n"; cout << -730 << " : " << constrainAngle180(-730) << "\n"; cout << -730.5 << " : " << constrainAngle180(-730.5) << "\n";
return 0; } Результат: Constrain 360: 0.5 : 0.5 10 : 10 380 : 20 730 : 10 730.5 : 10.5 -0.5 : 359.5 -10 : 350 -380 : 340 -730 : 350 -730.5 : 349.5 Constrain 180: 0.5 : 0.5 10 : 10 380 : 20 730 : 10 730.5 : 10.5 -0.5 : -0.5 -10 : -10 -380 : -20 -730 : -10 -730.5 : -10.5 Однако при использовании языка C99 следует учитывать вот что: Вычисление остатка от деления в JavaScript Цитата: если хотите снова запутаться, то попробуйте отрицательные числа (% операция является взятием остатка в Питоне (0<=(a%b)<b), но не в Си(99), где (a % b) может быть отрицательным: -1 % 7 == 6 // в Питоне и -1 % 7 == -1 // в Си(99). Деление с остатком определяется формулой: a = b * (a / b) + (a % b) плюс условие: 0<=(a%b)<b — это достаточно, чтобы уникально получить a/b и a%b. В Си(99) -a/b == -(a/b) (симметрия, нарушает свойство остатка), в Питоне (a+k*b)//b == (a//b)+ k (периодичность, ведёт к "настоящему" "делению по модулю" stackoverflow.com/a/1907889/4279 А чтобы получить остаток и в Си, можно (b + (a % b)) % b формулу использовать. См. Деление с остатком, Euclidean division Другими словами, значение a%b следует из свойств a/b. До C99 a/b зависело от реализации. C99 к нулю округляет потому что Fortran так делал, который вероятно в свою очередь использовал то что на CPU быстрее (про Фортран—со слов человека, который черновик стандарта правил<-здесь ещё более robust формулы, для остатка в Си) stackoverflow.com/q/3602827/4279 |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|