как определить точку между двумя точками на компасе - PullRequest
1 голос
/ 11 октября 2010

Учитывая любые две точки на компасе (начальный диапазон и конечный диапазон), чтобы сформировать диапазон. Пример от 270 (начальный диапазон) градусов до 45 (конечный диапазон) градусов и с учетом другой точки, скажем, 7, как я могу работать, если эта точка находится между начальным и конечным диапазоном?

Я пытаюсь написать какой-нибудь код, чтобы он работал, если ветер (в вышеуказанном пункте 3) дует с моря или с суши, где земля определяется по диапазону начала и конца диапазона.

Большое спасибо Andy

Обновление: 10.11.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 ]

2 голосов
/ 11 октября 2010

По точкам на компасе я предполагаю, что вы имеете в виду точки на круге единицы. И "между" двумя точками на круге единицы вы подразумеваете, что описали дугу на круге единицы и хотите знать, находится ли данная точка в этой дуге.

Предположим, что все точки на единичной окружности описываются углами, и для такого угла t, описывающего точку на единичной окружности, нам требуется 0 <= t < 2 * pi.

Допустим, что ваша дуга описывается как дуга (t_1, t_2) (то есть перемещение против часовой стрелки от точки на круге единицы, соответствующей углу t_1, до точки на круге единицы, соответствующей под углом t_2*). Тогда, учитывая точку на окружности с соответствующим углом t, верно, что t находится на дуге против часовой стрелки от t_1 до t_2, если t_2 > t_1 и t_1 <= t <= t_2 или t_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 голос
/ 12 октября 2010

Вот однострочная функция, которая использует оператор по модулю (%) для обработки случая с циклом. Предполагается, что входные значения находятся в диапазоне 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 ++ из-за неудачного способа, которым % обрабатывает отрицательные значения.

1 голос
/ 11 октября 2010

Это должно работать, если все ваши очки похожи на 0 <= point < 360:

def between(lower, upper, point):
   if upper < lower:
      upper += 360
   if point < lower:
      point += 360
   return (point <= upper)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...