このページでは、C言語での「三角関数の使い方」について解説していきます!
Contents
sin
関数・cos
関数・tan
関数
C言語では、数学等で利用した sin・cos・tan の計算を行う関数が標準ライブラリ関数として用意されています。
#incldue <math.h>
double sin(double x);
double cos(double x);
double tan(double x);
sin
関数・cos
関数・tan
関数を利用するためには、math.h
をインクルードしておく必要があるので注意してください。
環境によっては sin
関数・cos
関数・tan
関数を利用するために libm
のリンクが必要な場合があります
もしコンパイルをしてみて "Undefiend Reference...."
や "未解決の外部シンボル...."
みたいなエラーが出るようであれば、コンパイル時のオプションに -lm
を指定してみてください
libm
のリンクが行われてエラーを解決できると思います
例えば下記は、0
度から 359
度までの角度に対する sin
関数・cos
関数・tan
関数の結果を 20
度刻みで表示するプログラムのソースコードになります。
#include <stdio.h>
#include <math.h>
int main(void) {
for (int degree = 0; degree < 360; degree+=20) {
double rad = degree * M_PI / 180;
printf("%3d : %4.2f %4.2f %4.2f\n", degree, sin(rad), cos(rad), tan(rad));
}
return 0;
}
実行結果は下記のようになります。
0 : 0.00 1.00 0.00 20 : 0.34 0.94 0.36 40 : 0.64 0.77 0.84 60 : 0.87 0.50 1.73 80 : 0.98 0.17 5.67 100 : 0.98 -0.17 -5.67 120 : 0.87 -0.50 -1.73 140 : 0.64 -0.77 -0.84 160 : 0.34 -0.94 -0.36 180 : 0.00 -1.00 -0.00 200 : -0.34 -0.94 0.36 220 : -0.64 -0.77 0.84 240 : -0.87 -0.50 1.73 260 : -0.98 -0.17 5.67 280 : -0.98 0.17 -5.67 300 : -0.87 0.50 -1.73 320 : -0.64 0.77 -0.84 340 : -0.34 0.94 -0.36
ソースコードに登場する M_PI
は円周率 π を表す定数マクロになります。このページのソースコードではこの M_PI
を利用しますが、下記ページで解説しているとおり、math.h
をインクルードしても M_PI
が利用できない場合があるので注意してください。その場合は別途 M_PI
や PI
を自身で定義する必要があります。
引数は単位が「ラジアン」の角度
sin
関数・cos
関数・tan
関数ともに引数に指定するのは「角度」であり、その角度の単位は「ラジアン」である必要があります。単位が「度」の角度を引数に指定すると意図した結果が得られないので注意してください。
そのため、プログラム内で角度を「度」で扱っている場合、sin
関数・cos
関数・tan
関数を実行する前には事前に角度を「度」から「ラジアン」に変換する必要があります。
この角度の単位の変換方法に関しては下記ページで解説していますので、詳しく知りたい方はこちらをご参照しただければと思います。
度(度数法)⇔ラジアン(弧度法)の変換スポンサーリンク
sin
関数・cos
関数・tan
関数の返却値
続いて sin
関数・cos
関数・tan
関数の返却値について確認していきましょう!
下の図のような、底辺の長さが a
、高さが b
、斜辺の長さが c
、斜辺と底辺とがなす角の角度が θ
度の直角三角形で考えていきたいと思います。
また、θ
の単位をラジアンに変換した角度を x
としたいと思います。この x
は下記の式により求めることが出来ます。
x = θ * M_PI / 180
上記で求めた x
を引数に指定して sin(x)
・cos(x)
・tan(x)
を実行した場合、返却値はそれぞれ下記のようになります。
sin(x)
:b / c
cos(x)
:a / c
tan(x)
:b / a
要は、sin
関数・cos
関数・tan
関数は「直角三角形における2辺の長さの比」を返却します。
sin
関数・cos
関数・tan
関数の使用例
これらの三角関数は、単に数式を解く上でも便利な関数ですが、図形や座標等を扱うプログラムで特に活躍します。
三角関数で三角形の面積を求める
例えば、下の図の三角形の面積について考えてみましょう!長さ d
と長さ e
と角度 x
が分かっている場合、どのようにして三角形の面積は求められるでしょうか?(まずは、角度 x
の単位は「ラジアン」で考えていきたいと思います)
このような三角形の面積は三角関数を利用することで簡単に求めることが出来ます。
まず、三角形に下の図のように補助線を入れれば、この補助線の長さが三角形の高さとなります。この高さを f
としたいと思います。
三角形の面積は 底辺の長さ * 高さ / 2
で求めることが出来ますので、上の図の三角形の面積は d * f / 2
により求めることができることになります。また、現状では d
の長さは分かっているので、f
を求められれば三角形の面積を求めることが出来ます。
さらに、青で色をつけた部分は直角三角形になりますね!したがって、sin(x)
を実行すれば、f / e
を返却値として得ることができることになります。これはつまり、sin(x) = f / e
の等式が成立することになります。
この等式の sin(x) = f / e
の両辺に e
を掛ければ f = e * sin(x)
が成立することになり、また e
の長さは分かっていますので、結局 f
の長さは e * sin(x)
で求めることが出来ることになります。したがって、下の図の三角形の面積は d * e * sin(x) / 2
により求めることができることになります。
この三角形の面積を求めるプログラムは下記のように書くことが出来ます。
#include <stdio.h>
#include <math.h>
int main(void) {
double d, e;
double x;
double s;
/* 2辺の長さを設定 */
d = 30;
e = 25;
/* 角度を設定 */
x = M_PI / 6;
/* 面積を計算して表示 */
s = d * e * sin(x) / 2;
printf("%f\n", s);
return 0;
}
ここまで x
を「ラジアン」の単位の角度を扱ってきましたが、もし、x
の単位が「度」の場合は下記のように角度の単位を変換してから求める必要があるので注意してください。
#include <stdio.h>
#include <math.h>
int main(void) {
double d, e;
int x;
double rad_x;
double s;
/* 2辺の長さを設定 */
d = 30;
e = 25;
/* 角度を設定 */
x = 30;
/* 角度をラジアンに変換 */
rad_x = x * M_PI / 180;
/* 面積を計算して表示 */
s = d * e * sin(rad_x) / 2;
printf("%f\n", s);
return 0;
}
ポイントは、長さが不明の辺の長さを「三角関数の利用により求めているところ」です。
このように、三角関数を利用することで、直角三角形の「一辺の長さ」と「斜辺と底辺とがなす角の角度」から「他の辺の長さ」を求めることが可能です。これはここまで紹介した三角形の面積を求める場合だけでなく、図形や座標を扱う場合に大活躍するので覚えておくと良いと思います!
スポンサーリンク
三角関数で回転を行う
また、三角関数を利用して画像や図形の回転を行う事も可能です。画像の回転に関しては下記ページで詳しく解説していますので興味のある方は是非読んでみてください。
C言語で画像を回転ここでは、簡単に下のような F を表す文字を回転するプログラム例を紹介しておきます。
****** ****** ** ** ****** ****** ** ** ** **
例えば135度で回転すると F の文字が下記のように変化します(ちょっと一方に寄ってしまって見た目がイマイチになる回転角度もありますが…)。
* ** ** ** *** ***** *** ** ** *** *** *** *
この F を表す文字の回転は、下記のプログラムで実現することが出来ます。
#include <stdio.h>
#include <math.h>
#define Y 12
#define X 12
static int F[Y][X] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int rotated_F[Y][X];
void output(void) {
for (int y = 0; y < Y; y++) {
for (int x = 0; x < X; x++) {
if (rotated_F[y][x] == 0) {
/* 0の場合は空白を出力 */
printf(" ");
} else {
/* 1の場合は*を出力 */
printf("*");
}
}
printf("\n");
}
}
void rotate(int degree) {
double mat[2][2];
double db_x, db_y;
int b_x, b_y;
/* 回転行列の逆行列を作成 */
mat[0][0] = cos(M_PI / 180 * degree);
mat[0][1] = sin(M_PI / 180 * degree);
mat[1][0] = -sin(M_PI / 180 * degree);
mat[1][1] = cos(M_PI / 180 * degree);
/* 回転後の全座標(x,y)に回転前の座標をコピーする */
for (int y = 0; y < Y; y++) {
for (int x = 0; x < X; x++) {
/* 行列matと回転後座標(x,y)との積から回転前座標(db_x,db_y)を算出 */
db_x = mat[0][0] * (x - X / 2) + mat[0][1] * (y - Y / 2);
db_y = mat[1][0] * (x - X / 2) + mat[1][1] * (y - Y / 2);
/* (db_x,db_y)に一番近い座標を算出 */
b_x = round(db_x) + X / 2;
b_y = round(db_y) + Y / 2;
if (b_x < 0 || b_x >= X || b_y < 0 || b_y >= Y) {
/* 回転前座標が配列外であれば0とする */
rotated_F[y][x] = 0;
} else {
/* 回転後座標に回転前座標をコピー */
rotated_F[y][x] = F[b_y][b_x];
}
}
}
}
int main(void) {
int degree;
printf("angle(degree):");
scanf("%d", °ree);
if (degree < 0 || degree >= 360) {
printf("0 - 359を入力してください\n");
return 0;
}
rotate(degree);
output();
return 0;
}
この回転は、ほぼ前述で紹介した画像の回転と同じ仕組みで行っています(そのためソースコードの解説は省略させていただきます…)。もしかしたらソースコードを難しく感じるかもしれませんが、まずは三角関数を利用することでこういった回転も実現することができることを覚えておくと良いと思います!
その他三角関数でできること
三角関数を使ってゲームのキャラクターの動作等も実現することが出来ます。C言語始めたてでゲームを開発する機会はなかなかないかもしれませんが、三角関数はゲームプログラミング等でも活躍することは知っておくと良いと思います。
簡単なゲームのキャラクターの動作を三角関数でどのように実現しているかについては下記ページでも解説していますので、興味があれば読んでみてください(ソースコードはイメージしか載せていませんので注意してください)。
プログラミングにおける三角関数の重要性まとめ
このページでは、C言語での「三角関数(sin
関数・cos
関数・tan
関数)の使い方」について解説しました!
使用時の注意点は下記の3つだと思います。
- 引数に指定する角度の単位は「ラジアン」
math.h
をインクルードする- 必要に応してコンパイル(リンク)時に
-lm
を指定する
三角関数は単に数式を解くだけでなく、図形や画像を扱ったりゲームのキャラクター等の動作を実現したりするときにも活躍してくれる関数になります!
三角関数を使いこなせると、よりプログラミングを楽しめるようになりますので、ぜひ三角関数の使い方はマスターしておきましょう!
また、逆三角関数の atan
と atan2
については下記ページで解説しています。これらの関数は直角三角形の角度を算出するもので、こちらも非常に便利な関数なので是非読んでみてください!