風向計からの風向データがあり、データは0〜359度で表されています。
これを16方向のテキスト形式(コンパスローズ)に変換したいと思います。
基本的に私は、一連のifステートメントを使用せずに角度の範囲をチェックせずに、角度の読み取りを16文字列配列にスケーリングして正しい風向を出力する高速で滑らかな方法があるかどうかを知りたい
風向を見つけることができます ここ 。
ありがとう!
編集:
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
ステップ:
これが、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)];
}
ロジックの説明については 彼の回答 を参照してください。
丸めに注意してください。349... 11の間の角度は "N"である必要があります。したがって、最初に半分のセクター(+(360/16)/ 2)を追加してから、360を超えるオーバーフローを%360で処理してから、360/16で除算します。
["N","NNW",...,"NNE"][((d+(360/16)/2)%360)/(360/16)]
私はこれをチェックしました、そしてそれは非常にうまくいき正確であるようです。出典: 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)];
}
次の方が簡単だと思います。
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)];
このJavaScriptは、基本的な方向が8つだけ必要で、対応する矢印が必要なすべてのユーザーに使用できます。
function getCardinalDirection(angle) {
const directions = ['↑ N', '↗ NE', '→ E', '↘ SE', '↓ S', '↙ SW', '← W', '↖ NW'];
return directions[Math.round(angle / 45) % 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'=>337.5, 'N'=>0,'North'=>0,'East'=>90,'West'=>270,'South'=>180);
return $dirs[$b];
}
配列内の位置や列挙値など、必要なテキストを取得できるように、単純な度数の除算を実行するだけでしょう。すべての部門を切り捨ててください。 360/16 = 22.5なので、位置を取得するには22.5で割ります。
String [] a = [N、NNW、NW、WNW、...、NNE]
これはうまくいきます
#!/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
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) ] ;
}
ステップ
それが役に立てば幸い
ここに到着し、学位を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行の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
@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))
これを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
私は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)])
}