如何确定点位于罗盘上两点之间

发布于 2024-09-27 14:56:01 字数 1462 浏览 2 评论 0原文

给定罗盘上的任意两点(开始范围和结束范围)以形成一个范围。例如从 270(开始范围)度到 45(结束范围)度,并给出另一个点(例如 7),我如何计算出该点是否在开始范围和结束范围之间?

我正在尝试编写一些代码来计算风(在上述第3点中)是从海上吹还是从陆地吹,其中陆地由 Start range 和 End range 定义。

非常感谢 安迪

更新:11/10/2010 18:46BST 从 @sth 的解决方案来看,以下内容似乎按预期工作。

#!/usr/bin/perl -w

sub isoffshore {

        my ( $beachstart,$beachend,$wind) = @_;

        if( $beachend < $beachstart) {
                $beachend += 360;
        }

        if ($wind < $beachstart){
                $wind += 360;
        }

        if ($wind <= $beachend){
                print ("Wind is Onshore\n");
                return 0;
        }else{
                print ("Wind is Offshore\n");
                return 1;

        }

}

isoffshore ("0","190","3"); #Should be onshore
isoffshore ("350","10","11"); #Should be offshore
isoffshore ("270","90","180");#Should be offshore
isoffshore ("90","240","0"); #Should be offshore
isoffshore ("270","90","180");#Should be offshore
isoffshore ("0","180","90"); #Should be onshore
isoffshore ("190","0","160"); #Should be offshore
isoffshore ("110","240","9"); #Should be offshore
isoffshore ("0","180","9"); #Should be onshore
isoffshore ("0","180","179"); #Should be onshore

结果

@localhost ~]$ ./offshore2.pl
Wind is Onshore
Wind is Offshore
Wind is Offshore
Wind is Offshore
Wind is Offshore
Wind is Onshore
Wind is Offshore
Wind is Offshore
Wind is Onshore
Wind is Onshore

Given any two points on compass (Start range and End Range) to form a range. Example from 270(Start range) degrees to 45(End range)degrees and given another point say 7 , how can I work out if that point is between Start and End range ?

I'm trying to write some code to work out if the Wind (in the above point 3) is blowing from the sea or from the land , where the land is defind by Start range and End range .

Many Thanks
Andy

Update:11/10/2010 18:46BST
From @sth's solution the following seems to work for as expected.

#!/usr/bin/perl -w

sub isoffshore {

        my ( $beachstart,$beachend,$wind) = @_;

        if( $beachend < $beachstart) {
                $beachend += 360;
        }

        if ($wind < $beachstart){
                $wind += 360;
        }

        if ($wind <= $beachend){
                print ("Wind is Onshore\n");
                return 0;
        }else{
                print ("Wind is Offshore\n");
                return 1;

        }

}

isoffshore ("0","190","3"); #Should be onshore
isoffshore ("350","10","11"); #Should be offshore
isoffshore ("270","90","180");#Should be offshore
isoffshore ("90","240","0"); #Should be offshore
isoffshore ("270","90","180");#Should be offshore
isoffshore ("0","180","90"); #Should be onshore
isoffshore ("190","0","160"); #Should be offshore
isoffshore ("110","240","9"); #Should be offshore
isoffshore ("0","180","9"); #Should be onshore
isoffshore ("0","180","179"); #Should be onshore

Results

@localhost ~]$ ./offshore2.pl
Wind is Onshore
Wind is Offshore
Wind is Offshore
Wind is Offshore
Wind is Offshore
Wind is Onshore
Wind is Offshore
Wind is Offshore
Wind is Onshore
Wind is Onshore

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我的痛♀有谁懂 2024-10-04 14:56:01

我认为罗盘上的点是指单位圆上的点。通过单位圆上的两点“之间”,您的意思是您已经在单位圆上描述了一条弧,并且想知道给定点是否在该弧中。

假设单位圆上的所有点都用角度来描述,对于描述单位圆上的点的角度t,我们要求0 <= t << 2 * 圆周率。

假设您的弧被描述为弧 (t_1, t_2)(即,从单位圆上与角度 t_1 对应的点逆时针遍历 到单位圆上与角度 t_2* 对应的点)。然后,给定单位圆上具有相应角度t的点,t确实位于从t_1的逆时针圆弧上>t_2 如果 t_2 > t_1t_1 <= t <= t_2t_1 > t_2 而不是 t_2 <= t <= t_1

因此,

public bool IsInArc(double t1, double t2, double t) {
     Guard.Against<ArgumentOutOfRangeException>(t1 < 0 || t1 >= 2 * Math.PI);
     Guard.Against<ArgumentOutOfRangeException>(t2 < 0 || t2 >= 2 * Math.PI);
     Guard.Against<ArgumentOutOfRangeException>(t < 0 || t >= 2 * Math.PI);
     return t2 > t1 ? IsInArcInternal(t1, t2, t) : !IsInArcInternal(t2, t1, t);
}

private bool IsInArcInternal(double t1, double t2, double t) {
     Guard.Against<ArgumentException>(t2 < t1);
     return t1 <= t && t <= t2;
}

By points on a compass, I assume that you mean points on the unit circle. And by "between" two points on the unit circle, you mean that you have described an arc on the unit circle and want to know if a given point is in that arc.

Assume that all points on the unit circle are described by angles and for such an angle t describing a point on the unit circle we require that 0 <= t < 2 * pi.

Let's say that your arc is described as the arc (t_1, t_2) (that is, traverse counterclockwise from the point on the unit circle corresponding to the angle t_1 to the point on the unit circle corresponding to the angle t_2*). Then, given a point on the unit circle with corresponding angle t, it is true that t is on the counterclockwise arc from t_1 to t_2 if t_2 > t_1 and t_1 <= t <= t_2 or t_1 > t_2 and not t_2 <= t <= t_1.

Thus,

public bool IsInArc(double t1, double t2, double t) {
     Guard.Against<ArgumentOutOfRangeException>(t1 < 0 || t1 >= 2 * Math.PI);
     Guard.Against<ArgumentOutOfRangeException>(t2 < 0 || t2 >= 2 * Math.PI);
     Guard.Against<ArgumentOutOfRangeException>(t < 0 || t >= 2 * Math.PI);
     return t2 > t1 ? IsInArcInternal(t1, t2, t) : !IsInArcInternal(t2, t1, t);
}

private bool IsInArcInternal(double t1, double t2, double t) {
     Guard.Against<ArgumentException>(t2 < t1);
     return t1 <= t && t <= t2;
}
霓裳挽歌倾城醉 2024-10-04 14:56:01

这是一个单行函数,它使用模 (%) 运算符来处理环绕情况。输入值假定在 0..359(度)范围内:

int inRange(int start, int end, int point)
{
    return (point + 360 - start) % 360 <= (end + 360 - start) % 360;
}

//
// Test harness
//

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    assert(inRange(90, 270, 0) == 0);
    assert(inRange(90, 270, 45) == 0);
    assert(inRange(90, 270, 180) == 1);
    assert(inRange(90, 270, 315) == 0);
    assert(inRange(270, 90, 0) == 1);
    assert(inRange(270, 90, 45) == 1);
    assert(inRange(270, 90, 180) == 0);
    assert(inRange(270, 90, 315) == 1);

    if (argc >= 4)
    {
        int start = atoi(argv[1]);
        int end = atoi(argv[2]);
        int point = atoi(argv[3]);
        int result = inRange(start, end, point);

        printf("start = %d, end = %d, point = %d -> result = %d\n", start, end, point, result);
    }
    return 0;
}

请注意,在 C/C++ 中,测试每一侧都需要 + 360 项,因为 >% 处理负值。

Here's a one line function which uses the modulo (%) operator to handle the wraparound case. Input values are assumed to be in the range 0..359 (degrees):

int inRange(int start, int end, int point)
{
    return (point + 360 - start) % 360 <= (end + 360 - start) % 360;
}

//
// Test harness
//

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    assert(inRange(90, 270, 0) == 0);
    assert(inRange(90, 270, 45) == 0);
    assert(inRange(90, 270, 180) == 1);
    assert(inRange(90, 270, 315) == 0);
    assert(inRange(270, 90, 0) == 1);
    assert(inRange(270, 90, 45) == 1);
    assert(inRange(270, 90, 180) == 0);
    assert(inRange(270, 90, 315) == 1);

    if (argc >= 4)
    {
        int start = atoi(argv[1]);
        int end = atoi(argv[2]);
        int point = atoi(argv[3]);
        int result = inRange(start, end, point);

        printf("start = %d, end = %d, point = %d -> result = %d\n", start, end, point, result);
    }
    return 0;
}

Note that the + 360 term on each side of the test is required in C/C++ due to the unfortunate way that % treats negative values.

花辞树 2024-10-04 14:56:01

如果你的所有点都像 0 <= point << 360:

def between(lower, upper, point):
   if upper < lower:
      upper += 360
   if point < lower:
      point += 360
   return (point <= upper)

This should work if all your points are like 0 <= point < 360:

def between(lower, upper, point):
   if upper < lower:
      upper += 360
   if point < lower:
      point += 360
   return (point <= upper)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文