あなたが何を求めているのかを理解するのは難しく、あなたの論理は数学的に/地理的に正確ではないようです。前提条件は次のようです。
- センサーから読み取った角度は0〜360度です。
- この角度の方向を印刷します。ここで、真東は角度0です。
- コンパスの方向は、(反時計回りに)E、ENE、NE、NNE、Nなどです。
- 全体として、16のそのような方向がコンパスに存在します。したがって、360度を16の異なる方向に分割する必要があります。残念ながら、360/16 = 22.5であり、偶数ではありません。
- 360/16は偶数ではないため、floatタイプを使用するか、CPUが制限されたローエンドの組み込みシステムの場合は、ここで最も可能性が高いように、すべての整数に10を掛けます。
上記の仮定が正しければ、次のようなことができます。
const char* DIRECTION [16] =
{
"E",
"ENE",
"NE",
"NNE",
"N",
"NNW",
"NW",
"WNW",
"W",
"WSW",
"SW",
"SSW",
"S",
"SSE",
"SE",
"ESE"
};
const char* get_direction (int angle)
{
angle = angle % 360; /* convert to angles < 360 degrees */
/* Formula: index = angle / (max angle / 16 directions) */
/* Since 360/16 is not an even number, multiply angle and max angle by 10, to eliminate rounding errors */
int index = angle*10 / (3600/16);
if(index == 15) /* special case since we start counting from "the middle of east's interval" */
{
if(angle*10 > 3600-(3600/16)/2)
{
index = 0; /* east */
}
}
return DIRECTION [index];
}
int main()
{
printf("%s\n", get_direction(0)); /* E */
printf("%s\n", get_direction(22)); /* E */
printf("%s\n", get_direction(23)); /* ENE */
printf("%s\n", get_direction(45)); /* NE */
printf("%s\n", get_direction(180)); /* W */
printf("%s\n", get_direction(348)); /* ESE */
printf("%s\n", get_direction(349)); /* E */
printf("%s\n", get_direction(360)); /* E */
getchar();
}
これの利点は、すべての間隔をチェックする場合と比較して、実行時間が決定論的であり、巨大なスイッチの場合よりも分岐予測が少なくなることです。
float番号を使用すると、コードがはるかに読みやすくなるため、そのオプションがある場合は使用する必要があることに注意してください。しかし、これはローエンドの組み込みシステム、つまり8ビットまたは16ビットのMCUアプリケーションであると想定しています。