Алгоритм или формула для кратчайшего направления движения между двумя градусами по окружности?
учитывая два градуса на круге 360 градусов. Назовем их источником и пунктом назначения.
например, источник может быть 120 градусов, а пункт назначения может быть 30 градусов.
есть ли элегантное решение вопроса о том, какое направление движения от источника к месту назначения короче, т. е. короче по часовой стрелке (увеличение градусов) или против часовой стрелки (уменьшение градусов)?
например, со степенями, указанными выше, тогда решение будет be: идите против часовой стрелки. С другой стороны, с источником как 350 и назначением как 20, тогда решение будет: идти по часовой стрелке.
5 ответов
вычислите разницу, затем нормализуйте ее до + / -180. Положительные числа указывают на перемещение в направлении увеличения угла (по часовой стрелке в вашем случае).
if ((dest - source + 360) % 360 < 180)
// clockwise
else
// anti-clockwise
кстати, ваша конвенция, что по часовой стрелке = = "увеличение градусов" is противоположность конвенции тригонометрии 101 что остальной мир использует и, следовательно, путает (был для меня, во всяком случае).
это функция, которую я использую для вывода кратчайшего расстояния между двумя градусами с отрицательными и положительными числами. Он также работает на degress вне рядов 0-360.
function shortestDistDegrees(start, stop) {
const modDiff = (stop - start) % 360;
let shortestDistance = 180 - Math.abs(Math.abs(modDiff) - 180);
return (modDiff + 360) % 360 < 180 ? shortestDistance *= 1 : shortestDistance *= -1;
}
shortestDistDegrees(50, -20) // Output: -70
shortestDistDegrees(-30, -370) // Output: 20
shortestDistDegrees(160, -710) // Output: -150
это алгоритм, который я использую для моих игровых камер:
rotSpeed = 0.25; //arbitrary speed of rotation
angleDiff = 180-abs(abs(source-dest)-180); //find difference and wrap
angleDiffPlus = 180-abs(abs((source+rotSpeed)-dest)-180); //calculate effect of adding
angleDiffMinus = 180-abs(abs((source-rotSpeed)-dest)-180); // ... subtracting
if(angleDiffPlus < angleDiff){ //if adding to ∠source reduces difference
source += rotSpeed; //add to ∠source
}else if(angleDiffMinus < angleDiff){ //if SUBTRACTING from ∠source reduces difference
source -= rotSpeed; //subtract from ∠source
}else{ //if difference smaller than rotation speed
source = dest; //set ∠source to ∠destination
}
"оборачивая" угол, мы можем рассчитать разницу. Затем мы можем проверить текущую разницу по сравнению с предсказаниями, чтобы увидеть, в каком направлении фактически уменьшится разница.