Преобразование направления ветра под углом к текстовым словам
У меня есть данные о направлении ветра, поступающие из флюгера, и данные представлены в диапазоне от 0 до 359 градусов.
Я хочу преобразовать это в текстовый формат (компас роза) с 16 различными направлениями.
В принципе, я хочу знать, есть ли быстрый способ масштабирования показаний угла в 16-строчном массиве, чтобы распечатать правильное направление ветра, не используя кучу операторов if и проверяя диапазоны углов
Направление ветра можно найти здесь.
спасибо!
Ответы
Ответ 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