将角度风向转换为文字

问题描述 投票:0回答:17

我有来自风向标的风向数据,数据以 0 到 359 度表示。

我想将其转换为具有 16 个不同方向的文本格式(罗盘)。

基本上我想知道是否有一种快速灵活的方法可以将角度读数缩放为 16 个字符串数组,以打印出正确的风向,而无需使用一堆 if 语句并检查角度范围

可以在这里找到风向。

谢谢!

angle
17个回答
95
投票

编辑:

由于每 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

步骤:

  1. 将角度除以 22.5,因为 360 度/16 个方向 = 22.5 度/方向变化。
  2. 添加 .5,以便在截断值时可以打破更改阈值之间的“联系”。
  3. 使用整数除法截断值(因此没有舍入)。
  4. 直接索引到数组并打印值(mod 16)。

44
投票

这是 steve-gregory 答案的 javascript 实现,它对我有用。

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)];
}

请参阅他的回答以获取逻辑解释。


21
投票

此 JavaScript 适用于任何只需要 8 个基本方向并想要相应箭头的人。

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

对于风,箭头按照惯例是相反的,因为角度表示源的方向而不是运动的方向。

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

12
投票

注意舍入,349...11 之间的角度应为“N”,因此先添加半个扇区 (+(360/16)/2),然后按 %360 处理超过 360 的溢出,然后除以 360/16 :

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

8
投票

我检查了这个,效果很好而且看起来很准确。 资料来源:http://www.themethodology.net/2013/12/how-to-convert- Degrees-to-cardinal.html,作者:Adrian Stevens

    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
投票

我相信更容易:

  1. 将方向移动 11.25
  2. 在方向列表末尾添加“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)];

4
投票

这是一个单行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


3
投票

如果您到达这里并且只想将您的学位分为 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)]

2
投票

我可能只会做简单的度数除法来获取数组中的位置或枚举值或可以为您提供所需文本的内容。将您的所有部门向下舍入。 360/16 = 22.5,因此您需要除以 22.5 以获得位置。

字符串[] a = [N,NNW,NW,WNW,...,NNE]


2
投票

这个效果很好

#!/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

2
投票

进行反向转换(罗盘字母缩写为度数):

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'=>337.5, 'N'=>0,'North'=>0,'East'=>90,'West'=>270,'South'=>180);
   return $dirs[$b];
}

1
投票

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) ] ;
}

步骤

  1. 给定 360 度角
  2. 由于北在 -11.25 到 11.25 之间,我们减去 11.25 以获得准确度
  3. 将角度除以 22.5,因为 360 度/16 个方向 = 22.5 度/方向变化
  4. Math.abs 因为负数仍然是北
  5. 从答案中选择 arr 中的片段

希望有帮助


1
投票

我大量使用 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)])
}

1
投票

想要使用@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))]

借用@Hristo markow来检查结果:

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

1
投票
compass_direction =["NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW","N"]

for i in range (0,365):
    index = (int) ((((i / 11.25) - 1) /2) % 16) 
    print(f"Angle: {i:3}, Index: {index}, Compass: {compass_direction[index]}")

1
投票

这是 flutter/dart 版本:

const windDirections = [
  "↑N",
  "NNE",
  "↗NE",
  "ENE",
  "→E",
  "ESE",
  "↘SE",
  "SSE",
  "↓S",
  "SSW",
  "↙SW",
  "WSW",
  "←W",
  "WNW",
  "↖NW",
  "NNW"
];
String degToCompass(final int degrees) =>
    windDirections[((degrees / 22.5) + 0.5).toInt() % 16];

0
投票

在 Excel 中使用此: VLOOKUP(MROUND(N12,22.5),N14:O29,2,FALSE)

单元格 N12 是需要答案的方向(以度为单位)。 范围 N14:O29 正在查找扇区(A 到 R):

风电领域 0A 22.5乙 45℃ 67.5D 90E 112.5 华氏度 135克 157.5小时 180焦耳 202.5K 225升 247.5 M 270牛 292.5P 第315章 337.5R

© www.soinside.com 2019 - 2024. All rights reserved.