Как отобразить atan2 () на градусы 0-360
atan2 (y,x) имеет этот разрыв на 180°, где он переключается на -180°..0° по часовой стрелке.
Как мне сопоставить диапазон значений до 0°..°360?
вот мой код:
CGSize deltaPoint = CGSizeMake(endPoint.x - startPoint.x, endPoint.y - startPoint.y);
float swipeBearing = atan2f(deltaPoint.height, deltaPoint.width);
я вычисляю направление прокручивания сенсорного события с учетом начальной и конечной точек, как XY точечных структур. Код для iPhone, но любой язык, который поддерживает atan2f() будет делать.
Спасибо за вашу помощь, ребята, как с общим решением и код.
обновление: я сделал ответ эриккаллена в функцию с хорошими длинными именами переменных, поэтому я пойму это через 6 месяцев. Может быть, это поможет какой-то другой iPhone noob.
float PointPairToBearingDegrees(CGPoint startingPoint, CGPoint endingPoint)
{
CGPoint originPoint = CGPointMake(endingPoint.x - startingPoint.x, endingPoint.y - startingPoint.y); // get origin point to origin by subtracting end from start
float bearingRadians = atan2f(originPoint.y, originPoint.x); // get bearing in radians
float bearingDegrees = bearingRadians * (180.0 / M_PI); // convert to degrees
bearingDegrees = (bearingDegrees > 0.0 ? bearingDegrees : (360.0 + bearingDegrees)); // correct discontinuity
return bearingDegrees;
}
13 ответов:
решение, используя по модулю
простое решение, которое ловит всех случаях.
degrees = (degrees + 360) % 360; // +360 for implementations where mod returns negative numbersобъяснение
положительный: от 1 до 180
Если вы мод любое положительное число между 1 и 180 на 360, вы получите точно такое же число вы положили В. Мод здесь просто гарантирует, что эти положительные числа возвращаются как одно и то же значение.
отрицательные: -180 до -1
используя мод здесь будут возвращены значения в диапазоне 180 и 359 градусов.
особые случаи: 0 и 360
использование mod означает, что возвращается 0, что делает это безопасным решением 0-359 градусов.
@erikkallen близко, но не совсем правильно.
theta_rad = atan2(y,x); theta_deg = (theta_rad/M_PI*180) + (theta_rad > 0 ? 0 : 360);Это должно работать в C++: (в зависимости от того, как реализован fmod, он может быть быстрее или медленнее, чем условное выражение)
theta_deg = fmod(atan2(y,x)/M_PI*180,360);В качестве альтернативы вы можете сделать это:
theta_deg = atan2(-y,-x)/M_PI*180 + 180;так как (x,y) и (- x,-y) отличаются по углам на 180 градусов.
@Jason S: ваш вариант" fmod " не будет работать в соответствии со стандартами реализации. Стандарт C является явным и ясным (7.12.10.1, "функции fmod"):
если y не равно нулю, то результат имеет тот же знак, что и x
таким образом,
fmod(atan2(y,x)/M_PI*180,360)на самом деле это просто многословное переписывание:
atan2(y,x)/M_PI*180ваше третье предложение, однако, на месте.
у меня есть 2 решения, которые, кажется, работают для всех комбинаций положительных и отрицательных x и y.
1) злоупотребление atan2 ()
согласно документам atan2 принимает параметры y и x в этом порядке. Однако, если вы отмените их, вы можете сделать следующее:
double radians = std::atan2(x, y); double degrees = radians * 180 / M_PI; if (radians < 0) { degrees += 360; }2) Правильно используйте atan2 () и конвертируйте впоследствии
double degrees = std::atan2(y, x) * 180 / M_PI; if (degrees > 90) { degrees = 450 - degrees; } else { degrees = 90 - degrees; }
angle = Math.atan2(x,y)*180/Math.PI;Я сделал формулу для ориентации угла в 0 до 360
angle + Math.ceil( -angle / 360 ) * 360;
альтернативным решением является использование mod (функция) определяется как:
function mod(a, b) {return a - Math.floor (a / b) * b;}затем, с помощью следующей функции, угол между ini (x,y) и конец(x, y) очки получается. Угол выражается в градусах, нормированных к [0, 360] град. и Северная ссылка 360 град.
function angleInDegrees(ini, end) { var radian = Math.atan2((end.y - ini.y), (end.x - ini.x));//radian [-PI,PI] return mod(radian * 180 / Math.PI + 90, 360); }
Это то, что я обычно делаю:
float rads = atan2(y, x); if (y < 0) rads = M_PI*2.f + rads; float degrees = rads*180.f/M_PI;
геосфера пакетов R вычислит bearingrumb, который является постоянной несущей линией, заданной точкой начала координат и восточным/северным направлением. На восток и Север, должны быть в матрице или векторе. Точка начала координат для розы ветров равна 0,0. Следующий код, кажется, легко решить эту проблему:
windE<-wind$uasE windN<-wind$vasN wind_matrix<-cbind(windE, windN) wind$wind_dir<-bearingRhumb(c(0,0), wind_matrix) wind$wind_dir<-round(wind$wind_dir, 0)
theta_rad = Math.Atan2(y,x); if(theta_rad < 0) theta_rad = theta_rad + 2 * Math.PI; //if neg., add 2 PI to it theta_deg = (theta_rad/M_PI*180) ; //convert from radian to degree //or theta_rad = Math.Atan2(y,x); theta_rad = (theta_rad < 0) ? theta_rad + 2 * Math.PI : theta_rad; theta_deg = (theta_rad/M_PI*180) ;-1 град становится (-1 + 360) = 359 град
-179 град становится (-179 + 360) = 181 град
double degree = fmodf((atan2(x, y) * (180.0 / M_PI)) + 360, 360);это вернет градус от 0°-360° против часовой стрелки, 0° в 3 часа.
Comments