2017-02-15 20 views
4

Мне нужна функция, чтобы зажать угол (в градусах) в произвольный диапазон [min,max]. Вот несколько примеров: Angle range examplesУгол зажима в произвольном диапазоне

Цветные области представляют собой допустимый диапазон углов.

  • В изображении # 1, анг должна быть прижата к макс (-90)
  • В изображении # 2, анг должна быть прижата к мин (135)
  • в изображении # 3, анг должна быть прижата к мин (135)

Это то, что я до сих пор:

static float clamp_angle(float ang,float min,float max) 
{ 
    ang = normalize_angle(ang); // normalize_angle transforms angle into [-180,180) range 
    min = normalize_angle(min); 
    max = normalize_angle(max); 
    if(angle_in_range(ang,min,max) == false) 
    { 
     if(abs(get_angle_difference(ang,min)) < abs(get_angle_difference(ang,max)) 
      ang = min; // Clamp to min if we're closer to min than max 
     else 
      ang = max; 
    } 
    return ang; 
} 

Что я пропускаю функция angle_in_range (true, если угол находится в пределах диапазона, в противном случае false).
Каким будет самый простой способ определить, находится ли угол в пределах диапазона или нет?

+0

Это звучит похоже на http://stackoverflow.com/questions/13652518/efficiently-find-points- внутри-круг-сектор? По крайней мере, математические требования. – Zze

ответ

2

Вы можете нормализовать углы таким образом, чтобы ang становился 0, а min и max отображались на [-180; 180). Затем вы можете проверить, если угол находится в указанном диапазоне, как это:

float clamp_angle(const float ang, const float min, const float max) 
{ 
    float n_min = normalize180(min-ang); 
    float n_max = normalize180(max-ang); 

    if (n_min <= 0 && n_max >= 0) 
    { 
     return ang; 
    } 
    if (abs(n_min) < abs(n_max)) 
     return min; 
    return max; 
} 

Live On Coliru

0

Предположим, вы используете по часовой стрелке. Расстояние между min и max в cw-порядке - dist (min, max) = (max-min) mod N Предположим, что внутри области. Тогда dist (min, A) + dist (A, max) = dist (min, max). Теперь вы можете измерить расстояние между точками A, min и max: dist (min, A) = (A - min) modN dist (A, max) = (max-A) modN. Если A внешняя область, то сумма расстояний должна быть N + dist (min, max), если внутри она должна быть равна dist (min, max)

В вашем случае N = 360 все значения находятся в [0,360)

Редактировать: На большинстве языков поведение (-x) modX не определено, поэтому вы должны вручную преобразовать -x в положительное число, например (-x + X) modX, где x лежит в [0, X)