如何确定点在罗盘上的两点之间

时间:2010-10-11 15:12:03

标签: math geometry

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

如果Wind(在上面的第3点)从海上或从陆地吹来,我试图编写一些代码来解决这个问题,那里的土地是由开始范围和结束范围定义的。

非常感谢 安迪

更新: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

3 个答案:

答案 0 :(得分:2)

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

假设单位圆上的所有点都是由角度描述的,对于描述单位圆上的点的角度t,我们需要0 <= t < 2 * pi

假设您的弧被描述为弧(t_1, t_2)(即,从单位圆上与角度t_1对应的点到点的横向逆时针在对应于角度t_2 * )的单位圆上。然后,给定单位圆上具有相应角度t的点,如果t t_1确实在t_2t_2 > t_1的逆时针弧上和t_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;
}

答案 1 :(得分:1)

如果您的所有积分都像0 <= point < 360

,这应该有用
def between(lower, upper, point):
   if upper < lower:
      upper += 360
   if point < lower:
      point += 360
   return (point <= upper)

答案 2 :(得分:1)

这是一个单行函数,它使用模(%)运算符来处理环绕式情况。假设输入值在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;
}

请注意,由于+ 360处理负值的不幸方式,C / C ++中需要测试每一侧的%项。