Pythonで三角関数を計算(sin, cos, tan, arcsin, arccos, arctan)
Pythonの数学関数の標準モジュールmath
を使うと、三角関数(sin, cos, tan)および逆三角関数(arcsin, arccos, arctan)の計算ができる。
math
モジュールをインポートして使う。
import math
NumPyにおける三角関数については以下の記事を参照。
円周率(π): math.pi
円周率(パイ、π)はmath
モジュールの中で定数として用意されている。math.pi
で表す。
print(math.pi)
# 3.141592653589793
角度変換(ラジアン、度): math.degrees(), math.radians()
math
モジュールの三角関数および逆三角関数では、角度の単位としてラジアンを使う。
ラジアン(弧度法)と度(度数法)を変換するにはmath.degrees()
とmath.radians()
を使う。
ラジアンから度に変換するのがmath.degrees()
で、度からラジアンに変換するのがmath.radians()
。
print(math.degrees(math.pi))
# 180.0
print(math.radians(180))
# 3.141592653589793
正弦、逆正弦: math.sin(), math.asin()
正弦(サイン、sin)を求める関数はmath.sin()
、逆正弦(アークサイン、arcsin)を求める関数はmath.asin()
。
30度の正弦を求める例を示す。math.radians()
で度をラジアンに変換している。
sin30 = math.sin(math.radians(30))
print(sin30)
# 0.49999999999999994
30度の正弦は0.5だが、無理数である円周率を正確に計算できないので誤差が生じる。
適当な桁数で丸めるには組み込み関数round()
を使う。第二引数に小数点以下何桁に丸めるか指定する。四捨五入ではなく偶数への丸めなので注意。
print(round(sin30, 1))
# 0.5
比較したい場合は誤差を考慮するmath.isclose()
を使う方法もある。
print(math.isclose(sin30, 0.5))
# True
同様に0.5の逆正弦を求める例を示す。math.asin()
が返すのはラジアンなので、math.degrees()
で度に変換している。
asin05 = math.degrees(math.asin(0.5))
print(asin05)
# 29.999999999999996
print(round(asin05, 1))
# 30.0
余弦、逆余弦: math.cos(), math.acos()
余弦(コサイン、cos)を求める関数はmath.cos()
、逆余弦(アークコサイン、arccos)を求める関数はmath.acos()
。
60度の余弦と0.5の逆余弦を求める例を示す。
print(math.cos(math.radians(60)))
# 0.5000000000000001
print(math.degrees(math.acos(0.5)))
# 59.99999999999999
適当な桁で丸めたい場合は、上述のように組み込み関数round()
を使う。
正接、逆正接: math.tan(), math.atan(), math.atan2()
正接(タンジェント、tan)を求める関数はmath.tan()
、逆正接(アークタンジェント、arctan)を求める関数はmath.atan()
またはmath.atan2()
。math.atan2()
については後述。
45度の正接と1の逆正接を求める例を示す。
print(math.tan(math.radians(45)))
# 0.9999999999999999
print(math.degrees(math.atan(1)))
# 45.0
適当な桁で丸めたい場合は、上述のように組み込み関数round()
を使う。
math.atan()とmath.atan2()の違い
math.atan()
とmath.atan2()
はどちらも逆正接を返す関数だが、引数の数と返り値の範囲が異なる。
math.atan(x)の返り値は-90度から90度
math.atan(x)
は引数が一つで、arctan(x)をラジアンで返す。返り値は-pi / 2
からpi / 2
(-90度から90度)の間になる。
print(math.degrees(math.atan(0)))
# 0.0
print(math.degrees(math.atan(1)))
# 45.0
print(math.degrees(math.atan(-1)))
# -45.0
print(math.degrees(math.atan(math.inf)))
# 90.0
print(math.degrees(math.atan(-math.inf)))
# -90.0
上の例のmath.inf
は無限大を表す。
math.atan2(y, x)の返り値は-180度から180度
math.atan2(y, x)
は引数が二つで、arctan(y / x)をラジアンで返す。
この角度は、原点から座標(x, y)
へのベクトルがx軸の正の方向となす角度(偏角)であり、返り値は-pi
からpi
(-180度から180度)の間になる。
第2象限・第3象限での角度も正しく計算できるので、偏角を求めたい場合はmath.atan()
よりもmath.atan2()
のほうが適当。
引数の順番がx, y
ではなくy, x
なので注意。
print(math.degrees(math.atan2(0, 1)))
# 0.0
print(math.degrees(math.atan2(1, 1)))
# 45.0
print(math.degrees(math.atan2(1, 0)))
# 90.0
print(math.degrees(math.atan2(1, -1)))
# 135.0
print(math.degrees(math.atan2(0, -1)))
# 180.0
print(math.degrees(math.atan2(-1, -1)))
# -135.0
print(math.degrees(math.atan2(-1, 0)))
# -90.0
print(math.degrees(math.atan2(-1, 1)))
# -45.0
負のゼロ
math.atan2(y, x)
において、上の例のように、x軸の負の方向(y
が0でx
が負の値)はpi
(180度)となるが、y
が負のゼロのときは-pi
(-180度)となる。符号を厳密に処理したい場合は要注意。
print(math.degrees(math.atan2(-0.0, -1)))
# -180.0
負のゼロは以下のような演算の結果として発生する。
print(-1 / math.inf)
# -0.0
print(-1.0 * 0.0)
# -0.0
整数int
では負のゼロとして扱われない。
print(-0.0)
# -0.0
print(-0)
# 0
x
, y
がどちらもゼロ(原点)の場合も、その符号によって結果が異なる。
print(math.degrees(math.atan2(0.0, 0.0)))
# 0.0
print(math.degrees(math.atan2(-0.0, 0.0)))
# -0.0
print(math.degrees(math.atan2(-0.0, -0.0)))
# -180.0
print(math.degrees(math.atan2(0.0, -0.0)))
# 180.0
math.atan2()
だけでなくmath.sin()
やmath.asin()
, math.tan()
, math.atan()
など、負のゼロによって結果の符号が変わる例は他にもある。符号を厳密に処理したい場合は要注意。
print(math.sin(0.0))
# 0.0
print(math.sin(-0.0))
# -0.0
print(math.asin(0.0))
# 0.0
print(math.asin(-0.0))
# -0.0
print(math.tan(0.0))
# 0.0
print(math.tan(-0.0))
# -0.0
print(math.atan(0.0))
# 0.0
print(math.atan(-0.0))
# -0.0
print(math.atan2(0.0, 1.0))
# 0.0
print(math.atan2(-0.0, 1.0))
# -0.0