Подтвердить что ты не робот

Преобразование направления ветра под углом к ​​текстовым словам

У меня есть данные о направлении ветра, поступающие из флюгера, и данные представлены в диапазоне от 0 до 359 градусов.

Я хочу преобразовать это в текстовый формат (компас роза) с 16 различными направлениями.

В принципе, я хочу знать, есть ли быстрый способ масштабирования показаний угла в 16-строчном массиве, чтобы распечатать правильное направление ветра, не используя кучу операторов if и проверяя диапазоны углов

Направление ветра можно найти здесь.

спасибо!

4b9b3361

Ответ 1

EDIT:

Так как есть изменение угла при каждых 22,5 градусах, направление должно менять руки после 11,25 градусов.

Таким образом:

349-360//0-11 = N
12-33 = NNE
34-56 = NE

Использование значений из 327-348 (всего спектра NNW) не дало результата для ответа eudoxos. Подумав, я не мог найти недостаток в своей логике, поэтому я переписал свои собственные.

def degToCompass(num):
    val=int((num/22.5)+.5)
    arr=["N","NNE","NE","ENE","E","ESE", "SE", "SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"]
    print arr[(val % 16)]

>>> degToCompass(0)
N
>>> degToCompass(180)
S
>>> degToCompass(720)
N
>>> degToCompass(11)
N
>>> 12
12
>>> degToCompass(12)
NNE
>>> degToCompass(33)
NNE
>>> degToCompass(34)
NE

ШАГИ:

  • Разделите угол на 22,5, потому что 360deg/16 направлений = 22.5deg/изменение направления.
  • Добавьте .5, чтобы при усечении значения вы могли сломать "связь" между порогом изменения.
  • Усечение значения с помощью целочисленного деления (поэтому округления нет).
  • Непосредственно индексируйте в массив и распечатайте значение (mod 16).

Ответ 2

Здесь выполняется java-скрипт ответа steve-gregory, который работает для меня.

function degToCompass(num) {
    var val = Math.floor((num / 22.5) + 0.5);
    var arr = ["N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"];
    return arr[(val % 16)];
}

См. его ответ для объяснения логики.

Ответ 3

Следите за округлением, углы между 349... 11 должны быть "N", поэтому сначала добавьте половину сектора (+ (360/16)/2), затем обработайте переполнение над 360 на% 360, затем разделите на 360/16:

["N","NNW",...,"NNE"][((d+(360/16)/2)%360)/(360/16)]

Ответ 4

Я проверил это, и он работает очень хорошо и кажется точным. Источник: http://www.themethodology.net/2013/12/how-to-convert-degrees-to-cardinal.html Адриана Стивенса

    public static string DegreesToCardinal(double degrees)
    {
        string[] caridnals = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "N" };
        return caridnals[(int)Math.Round(((double)degrees % 360) / 45)];
    }

    public static string DegreesToCardinalDetailed(double degrees)
    {
        degrees *= 10;

        string[] caridnals = { "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW", "N" };
        return caridnals[(int)Math.Round(((double)degrees % 3600) / 225)];
    }

Ответ 5

Я считаю, что легче:

  • Сдвиньте направление на 11.25
  • Добавьте "N" в конец списка направлений, чтобы обработать "более 360",

DirTable = ["N","NNE","NE","ENE","E","ESE", "SE","SSE","S","SSW","SW","WSW", "W","WNW","NW","NNW",**"N"**]; 

wind_direction= DirTable[Math.floor((d+11.25)/22.5)];

Ответ 6

Я бы просто сделал простое разделение степеней, чтобы получить позицию в массиве или значение enum или что-то, что даст вам текст, который вам нужен. Просто закруглите всю свою дивизию. 360/16 = 22,5, поэтому вы хотите разделить на 22,5, чтобы получить позицию.

String [] a = [N, NNW, NW, WNW,..., NNE]

Ответ 7

Функция Javascript 100% работает

function degToCompass(num) { 
    while( num < 0 ) num += 360 ;
    while( num >= 360 ) num -= 360 ; 
    val= Math.round( (num -11.25 ) / 22.5 ) ;
    arr=["N","NNE","NE","ENE","E","ESE", "SE", 
          "SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"] ;
    return arr[ Math.abs(val) ] ;
}

шаги

  • Учитывая угол 360 градусов
  • Так как север между -11,25 и 11,25 мы вычитаем 11,25 для точности
  • Разделите угол на 22,5, потому что 360deg/16 направлений = 22.5deg/изменение направления
  • Math.abs для отрицательных по-прежнему север
  • Выберите сегмент из arr из ответа

Надеюсь, что это поможет

Ответ 8

Другой способ:

function getDir($b)
{

   $dirs = array('N'=>0, 'NNE'=>22.5,"NE"=>45,"ENE"=>67.5, 'E'=>90,'ESE'=>112.5, 'SE'=>135,'SSE'=>157.5, 'S'=>180,'SSW'=>202.5, 'SW'=>225,'WSW'=>247.5, 'W'=>270,'WNW'=>292.5,'NW'=>315,'NNW'=>237.5, 'N'=>0,'North'=>0,'East'=>90,'West'=>270,'South'=>180);
   return $dirs[$b];
}

Ответ 9

это прекрасно работает

#!/usr/bin/env python

def wind_deg_to_str1(deg):
        if   deg >=  11.25 and deg <  33.75: return 'NNE'
        elif deg >=  33.75 and deg <  56.25: return 'NE'
        elif deg >=  56.25 and deg <  78.75: return 'ENE'
        elif deg >=  78.75 and deg < 101.25: return 'E'
        elif deg >= 101.25 and deg < 123.75: return 'ESE'
        elif deg >= 123.75 and deg < 146.25: return 'SE'
        elif deg >= 146.25 and deg < 168.75: return 'SSE'
        elif deg >= 168.75 and deg < 191.25: return 'S'
        elif deg >= 191.25 and deg < 213.75: return 'SSW'
        elif deg >= 213.75 and deg < 236.25: return 'SW'
        elif deg >= 236.25 and deg < 258.75: return 'WSW'
        elif deg >= 258.75 and deg < 281.25: return 'W'
        elif deg >= 281.25 and deg < 303.75: return 'WNW'
        elif deg >= 303.75 and deg < 326.25: return 'NW'
        elif deg >= 326.25 and deg < 348.75: return 'NNW'
        else: return 'N'

def wind_deg_to_str2(deg):
        arr = ['NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N']
        return arr[int(abs((deg - 11.25) % 360)/ 22.5)]

i = 0
while i < 360:
        s1 = wind_deg_to_str1(i)
        s2 = wind_deg_to_str2(i)
        print '%5.1f deg -> func1(%-3s), func2(%-3s), same:%s' % (i, s1, s2, ('ok' if s1 == s2 else 'different'))
        i += 0.5

Ответ 10

Если вы прибыли сюда и заинтересованы только в том, чтобы разбить свои степени в одном из 8 направлений.

function degToCompass(num){
    const val =  Math.floor((num / 45) + 0.5);
    const arr = ["N","NE","E", "SE","S","SW","W","NW"];
    return arr[(val % 8)]

Ответ 11

Этот JavaScript будет работать для всех, кому нужно только 8 основных направлений и нужны соответствующие стрелки.

function getCardinalDirection(angle) {
    const directions = ['↑ N', '↗ NE', '→ E', '↘ SE', '↓ S', '↙ SW', '← W', '↖ NW'];
    return directions[Math.round(angle / 45) % 8];
}

Ответ 12

Используется в Excel: ВПР (ОКРУГЛТ (N12,22.5), N14: O29,2, FALSE)

Ячейка N12 направлена ​​в градусах, для которых необходим ответ. Диапазон N14: O29 ищет сектор (от A до R):

ВЕТРОВОЙ СЕКТОР 0 A 22,5 B 45 C 67,5 D 90 E 112,5 F 135 G 157,5 H 180 Дж 202,5 ​​К 225 л 247,5 М 270 N 292,5oF 315 Q 337,5 R

Ответ 13

Я интенсивно использую R и мне нужно решение для этого. Это то, что я придумал и хорошо работает для всех возможных комбинаций, которые я кормил:

degToCardinal <- function(degrees) {
  val <- as.integer((degrees / 22.5) + 0.5)
  arr <- c("N","NNE","NE","ENE","E","ESE", "SE", "SSE","S","SSW","SW","WSW","W","WNW","NW","NNW")
  return(arr[((val+1) %% 16)])
}

Ответ 14

Хотел использовать @eudoxos, но нужно было собрать все части вместе:

def deg_to_compass(d):
  return ["N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE",
        "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"] [math.floor(((d+(360/16)/2)%360)/(360/16))]

Заимствовал @Христо Марков, чтобы проверить результаты:

for i in range(0,360):
  print (i,deg_to_compass(i) == wind_deg_to_str2(i))

Ответ 15

Здесь однострочная функция Python:

def deg_to_text(deg):
    return ["N","NNE","NE","ENE","E","ESE", "SE", "SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"][round(deg/22.5)%16]

Очевидно, что для удобства чтения его можно разбить на несколько строк /pep8