web-dev-qa-db-ja.com

角度で風向をテキストワードに変換する

風向計からの風向データがあり、データは0〜359度で表されています。

これを16方向のテキスト形式(コンパスローズ)に変換したいと思います。

基本的に私は、一連のifステートメントを使用せずに角度の範囲をチェックせずに、角度の読み取りを16文字列配列にスケーリングして正しい風向を出力する高速で滑らかな方法があるかどうかを知りたい

風向を見つけることができます ここ

ありがとう!

34
zacharoni

編集:

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. 360deg/16方向= 22.5deg /方向の変化なので、角度を22.5で割ります。
  2. .5を追加すると、値を切り捨てたときに、変更しきい値間の「タイ」を破ることができます。
  3. 整数除算を使用して値を切り捨てます(丸めは行われません)。
  4. 配列に直接インデックスを付け、値(mod 16)を出力します。
71
steve-gregory

これが、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)];
}

ロジックの説明については 彼の回答 を参照してください。

28
Matt Frear

丸めに注意してください。349... 11の間の角度は "N"である必要があります。したがって、最初に半分のセクター(+(360/16)/ 2)を追加してから、360を超えるオーバーフローを%360で処理してから、360/16で除算します。

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

私はこれをチェックしました、そしてそれは非常にうまくいき正確であるようです。出典: http://www.themethodology.net/2013/12/how-to-convert-degrees-to-cardinal.html by 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)];
    }
6
user2675312

次の方が簡単だと思います。

  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)];
3
edom-plc

このJavaScriptは、基本的な方向が8つだけ必要で、対応する矢印が必要なすべてのユーザーに使用できます。

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

逆変換(文字の省略形を度に変換)するには:

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];
}
2
Arne Kaas

配列内の位置や列挙値など、必要なテキストを取得できるように、単純な度数の除算を実行するだけでしょう。すべての部門を切り捨ててください。 360/16 = 22.5なので、位置を取得するには22.5で割ります。

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

2
Joseph

これはうまくいきます

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

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. 360度/ 16方向= 22.5度/方向の変更であるため、角度を22.5で割ります
  4. Math.abs for as negativeはまだ北です
  5. 回答からarrからセグメントを選択してください

それが役に立てば幸い

1
Pascal

ここに到着し、学位を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)]
1
Enda Molloy

これが1行の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

0
Hack5

@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))
0
Bruce

これをExcelで使用:VLOOKUP(MROUND(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 J 202.5 K 225 L 247.5 M 270 N 292.5 P 315 Q 337.5 R

0
John Babin

私は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)])
}
0
azdatasci