夹角到任意范围

时间:2017-02-15 10:34:05

标签: c++ range angle

我需要一个函数将角度(以度为单位)钳制到任意范围 transformRequest: function (obj) { var str = []; for (var p in obj) str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); return str.join("&"); } 。这里有些例子: Angle range examples

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

  • 在图像#1中, ang 应夹紧到 max ( - 90)
  • 在图像#2中, ang 应夹紧到 min (135)
  • 在图像#3中, ang 应夹紧到 min (135)

这是我到目前为止所做的:

[min,max]

我缺少的是功能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)。
确定角度是否在范围内的最简单方法是什么?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

假设您使用顺时针顺序。 cw顺序中min和max之间的距离是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)

答案 2 :(得分:0)

如果您想限制角度以使其保持在范围内,但在达到最大值或最小值时会回绕(而不是限制到极限),那么您可以使用这个相当简单的函数,我使用python编写:

def clamp_to_range(value, min, max):
     return (value % (max - min)) + min

它的行为如下:

>>> for i in range(0, 30): print("|{:<30}|{:<30}|".format(" "*(clamp_to_range(i, 4, 15)) + "♥", " "*i + "♥"))
...
|    ♥                         |♥                             |
|     ♥                        | ♥                            |
|      ♥                       |  ♥                           |
|       ♥                      |   ♥                          |
|        ♥                     |    ♥                         |
|         ♥                    |     ♥                        |
|          ♥                   |      ♥                       |
|           ♥                  |       ♥                      |
|            ♥                 |        ♥                     |
|             ♥                |         ♥                    |
|              ♥               |          ♥                   |
|    ♥                         |           ♥                  |
|     ♥                        |            ♥                 |
|      ♥                       |             ♥                |
|       ♥                      |              ♥               |
|        ♥                     |               ♥              |
|         ♥                    |                ♥             |
|          ♥                   |                 ♥            |
|           ♥                  |                  ♥           |
|            ♥                 |                   ♥          |
|             ♥                |                    ♥         |
|              ♥               |                     ♥        |
|    ♥                         |                      ♥       |
|     ♥                        |                       ♥      |
|      ♥                       |                        ♥     |
|       ♥                      |                         ♥    |
|        ♥                     |                          ♥   |
|         ♥                    |                           ♥  |
|          ♥                   |                            ♥ |
|           ♥                  |                             ♥|
正如我提到的,

它会环绕。如果您想将该值限制为指定的限制,则可以使用以下功能:

def clip_to_range(value, min_, max_):  # underscores added to avoid name collisions
     return min(max_, max(value, min_))

在这种情况下,将会发生:

>>> for i in range(0, 30): print("|{:<30}|{:<30}|".format(" "*clip_to_range(i, 4, 15) + "♥", " "*i + "♥"))
...
|    ♥                         |♥                             |
|    ♥                         | ♥                            |
|    ♥                         |  ♥                           |
|    ♥                         |   ♥                          |
|    ♥                         |    ♥                         |
|     ♥                        |     ♥                        |
|      ♥                       |      ♥                       |
|       ♥                      |       ♥                      |
|        ♥                     |        ♥                     |
|         ♥                    |         ♥                    |
|          ♥                   |          ♥                   |
|           ♥                  |           ♥                  |
|            ♥                 |            ♥                 |
|             ♥                |             ♥                |
|              ♥               |              ♥               |
|               ♥              |               ♥              |
|               ♥              |                ♥             |
|               ♥              |                 ♥            |
|               ♥              |                  ♥           |
|               ♥              |                   ♥          |
|               ♥              |                    ♥         |
|               ♥              |                     ♥        |
|               ♥              |                      ♥       |
|               ♥              |                       ♥      |
|               ♥              |                        ♥     |
|               ♥              |                         ♥    |
|               ♥              |                          ♥   |
|               ♥              |                           ♥  |
|               ♥              |                            ♥ |
|               ♥              |                             ♥|

clamp_to_range函数的C模拟看起来像这样:

#include <math.h>

float clampInRange(float value, float min, float max)
{
    return fmod(value, max - min) + min;
}