2017-02-15 54 views
4

我需要一个将角度(以度数为单位)限制在任意范围[min,max]的功能。以下是一些示例: Angle range examples将夹角限制在任意范围

彩色区域表示有效的角度范围。

  • 在图像#1,应钳位到最大(-90)
  • 在图像#2,ANG应钳位到分钟(135)
  • 在图像#3,ANG应钳位到分钟(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_rangetrue如果角度的范围内,否则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

假设您使用顺时针顺序。 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)mod N dist(A,max)=(max-A)modN。如果一个外部区域,那么距离的总和应该是N + dist(min,max),如果它内部应该相等dist(min,max)

在你的情况N = 360,所有值都在[0,360 )

编辑:在大多数语言中,(-x)modX的行为是未定义的,所以您应该手动将-x转换为正数,例如(-x + X)modX其中x位于[0,X)