はじめに
円関数(三角関数)の定義や性質、公式などを可視化して理解しようシリーズです。
この記事では、arccos関数のグラフを作成します。
【前の内容】
【他の内容】
【この記事の内容】
arccos関数の定義の可視化
arccos関数(逆cos関数・逆余弦関数・逆コサイン関数・inverse cosine function)の定義をグラフで確認します。arccos関数は、逆円関数(inverse circular functions)・逆三角関数(inverse trigonometric functions)の1つです。
cos関数の定義や作図については「【R】cos関数の可視化 - からっぽのしょこ」を参照してください。
利用するパッケージを読み込みます。
# 利用パッケージ library(tidyverse)
この記事では、基本的に パッケージ名::関数名()
の記法を使うので、パッケージの読み込みは不要です。ただし、作図コードについてはパッケージ名を省略するので、ggplot2
を読み込む必要があります。
また、ネイティブパイプ演算子 |>
を使います。magrittr
パッケージのパイプ演算子 %>%
に置き換えられますが、その場合は magrittr
を読み込む必要があります。
定義式の確認
まずは、arccos関数の定義式を確認します。
arccos関数は、cos関数の逆関数で定義されます。
ただし、定義域は であり、終域は です。関数の出力はラジアン(弧度法の角度)、 は円周率です。
曲線の形状
続いて、arccos関数のグラフを作成します。
曲線の作成
・作図コード(クリックで展開)
逆円関数の曲線の描画用のデータフレームを作成します。
# 逆関数の曲線の座標を作成 curve_inv_df <- tibble::tibble( x = seq(from = -1, to = 1, length.out = 201), # 定義域内の値 arccos_x = acos(x), arcsin_x = asin(x) ) curve_inv_df
# A tibble: 201 × 3 x arccos_x arcsin_x <dbl> <dbl> <dbl> 1 -1 3.14 -1.57 2 -0.99 3.00 -1.43 3 -0.98 2.94 -1.37 4 -0.97 2.90 -1.33 5 -0.96 2.86 -1.29 6 -0.95 2.82 -1.25 7 -0.94 2.79 -1.22 8 -0.93 2.77 -1.19 9 -0.92 2.74 -1.17 10 -0.91 2.71 -1.14 # ℹ 191 more rows
変数 と関数 の値をデータフレームに格納します。比較用に、 の値も格納しておきます。arccos関数は acos()
、arcsin関数は asin()
で計算できます。
円関数の曲線の描画用のデータフレームを作成します。
# 元の関数の曲線の座標を作成 curve_df <- tibble::tibble( t = seq(from = -pi, to = pi, length.out = 1001), # ラジアン cos_t = cos(t), inv_flag = (t >= 0 & t <= pi) # 逆関数の終域 ) curve_df
# A tibble: 1,001 × 3 t cos_t inv_flag <dbl> <dbl> <lgl> 1 -3.14 -1 FALSE 2 -3.14 -1.00 FALSE 3 -3.13 -1.00 FALSE 4 -3.12 -1.00 FALSE 5 -3.12 -1.00 FALSE 6 -3.11 -1.00 FALSE 7 -3.10 -0.999 FALSE 8 -3.10 -0.999 FALSE 9 -3.09 -0.999 FALSE 10 -3.09 -0.998 FALSE # ℹ 991 more rows
変数 と関数 の値を格納します。cos関数は cos()
で計算できます。
の値が のとり得る範囲内かのフラグを inv_flag
列とします。
arccos関数とcos関数のグラフを作成します。
・作図コード(クリックで展開)
# ラベル用の文字列を作成 def_label <- paste0( "list(", "arccos~x == cos^{-1}*x, ", "paste(-1 <= x, {} <= 1), ", "0 <= arccos~x <= pi", ")" ) # グラフサイズを設定 axis_y_size <- 3.5 # 関数曲線を作図 ggplot() + geom_segment(mapping = aes(x = c(-Inf, 0), y = c(0, -Inf), xend = c(Inf, 0), yend = c(0, Inf)), arrow = arrow(length = unit(10, units = "pt"), ends = "last")) + # x・y軸線 geom_line(data = curve_inv_df, mapping = aes(x = x, y = arccos_x, color = "arccos"), linewidth = 1) + # 逆関数 geom_line(data = curve_df, mapping = aes(x = t, y = cos_t, linetype = inv_flag, color = "cos"), linewidth = 1) + # 元の関数 geom_abline(slope = 1, intercept = 0, linetype = "dotdash") + # 恒等関数 scale_color_manual(breaks = c("arccos", "cos"), values = c("black", "#F8766D"), labels = c(expression(arccos~x), expression(cos~x)), name = "function") + # 凡例表示用 scale_linetype_manual(breaks = c(TRUE, FALSE), values = c("solid", "dotted"), guide ="none") + # 終域用 coord_fixed(ratio = 1, ylim = c(-axis_y_size, axis_y_size)) + # アスペクト比 labs(title = "inverse cosine function", subtitle = parse(text = def_label), x = expression(x), y = expression(f(x)))
arccos関数を実線、cos関数を朱色の実線と点線で、また恒等関数 を鎖線で示します。 がとり得る範囲( )の を実線で示しています。
恒等関数(傾きが1で切片が0の直線)に対して、arccos曲線とcos曲線が線対称な曲線です。
arccos関数の軸を入れ替えたグラフを作成します。
・作図コード(クリックで展開)
# 範囲πにおける目盛数を指定 tick_num <- 2 # ラジアン軸目盛用の値を作成 rad_break_vec <- seq(from = -pi, to = pi, by = pi/tick_num) rad_label_vec <- paste(round(rad_break_vec/pi, digits = 2), "* pi") # グラフサイズを設定 axis_y_size <- 2 # 逆関数と元の関数の関係を作図 ggplot() + geom_segment(mapping = aes(x = c(-Inf, 0), y = c(0, -Inf), xend = c(Inf, 0), yend = c(0, Inf)), arrow = arrow(length = unit(10, units = "pt"), ends = "last")) + # x・y軸線 geom_line(data = curve_inv_df, mapping = aes(x = arccos_x, y = x, color = "arccos"), linewidth = 1) + # 逆関数 geom_line(data = curve_df, mapping = aes(x = t, y = cos_t, color = "cos"), linewidth = 1, linetype = "dashed") + # 元の関数 scale_color_manual(breaks = c("arccos", "cos"), values = c("black", "#F8766D"), labels = c(expression(arccos~x), expression(cos~theta)), name = "function") + # 凡例表示用 scale_x_continuous(breaks = rad_break_vec, labels = parse(text = rad_label_vec)) + # ラジアン軸目盛 coord_fixed(ratio = 1, ylim = c(-axis_y_size, axis_y_size)) + # アスペクト比 labs(title = "inverse cosine function", subtitle = parse(text = def_label), x = expression(list(theta, tau == arccos~x)), y = expression(x == cos~theta == cos~tai))
arccos曲線の横軸と縦軸を入れ替える(恒等関数の直線に対して反転する)と、cos曲線に一致します。
cos関数とarccos関数は逆関数なので、、また のとき が成り立ちます。
arccos関数とarcsin関数のグラフを作成します。
・作図コード(クリックで展開)
# ラベル用の文字列を作成 def_label <- "arccos~x == frac(pi, 2) - arcsin~x" # グラフサイズを設定 axis_x_size <- 2 # 関数曲線を作図 ggplot() + geom_segment(mapping = aes(x = c(-Inf, 0), y = c(0, -Inf), xend = c(Inf, 0), yend = c(0, Inf)), arrow = arrow(length = unit(10, units = "pt"), ends = "last")) + # x・y軸線 geom_hline(yintercept = 0.5*pi, linetype = "dashed") + # 余角用の水平線 geom_line(data = curve_inv_df, mapping = aes(x = x, y = arccos_x, linetype = "arccos"), linewidth = 1) + # arccos関数 geom_line(data = curve_inv_df, mapping = aes(x = x, y = arcsin_x, linetype = "arcsin"), linewidth = 1) + # arcsin関数 scale_linetype_manual(breaks = c("arccos", "arcsin"), values = c("solid", "dotted"), labels = c(expression(arccos~x), expression(arcsin~x)), name = "function") + # 凡例表示用 scale_y_continuous(breaks = rad_break_vec, labels = parse(text = rad_label_vec)) + # ラジアン軸目盛 guides(linetype = guide_legend(override.aes = list(linewidth = 0.5))) + # 凡例の体裁 coord_fixed(ratio = 1, xlim = c(-axis_x_size, axis_x_size), ylim = c(-pi, pi)) + # アスペクト比 labs(title = "inverse cosine function", subtitle = parse(text = def_label), x = expression(x), y = expression(theta == f(x)))
余角の関係より、 が成り立ちます。
単位円と関数の関係
次は、単位円における偏角(単位円上の点)と円関数(cos・sin)と逆円関数(arccos)の関係を確認します。
各関数についてはそれぞれの記事を参照してください。
グラフの作成
変数を固定して、単位円におけるcos関数の線分とarccos関数の円弧のグラフを作成します。
・作図コード(クリックで展開)
円関数の変数を指定して、逆円関数を計算します。
# 点用のラジアンを指定 theta <- 10/6 * pi # 終域内のラジアンに変換 tau <- acos(cos(theta)) tau / pi
[1] 0.3333333
cos関数の変数 を指定して、 を変数としてarccos関数 を計算します。
円周上の点の描画用のデータフレームを作成します。
# 円周上の点の座標を作成 point_df <- tibble::tibble( angle = c("theta", "tau"), # 角度カテゴリ t = c(theta, tau), x = cos(t), y = sin(t), point_type = c("main", "sub") # 入出力用 ) point_df
# A tibble: 2 × 5 angle t x y point_type <chr> <dbl> <dbl> <dbl> <chr> 1 theta 5.24 0.5 -0.866 main 2 tau 1.05 0.5 0.866 sub
円関数の入力 と逆円関数の出力 それぞれについて、単位円上の点の座標 を計算します。
単位円の描画用のデータフレームを作成します。
# 単位円の座標を作成 circle_df <- tibble::tibble( t = seq(from = 0, to = 2*pi, length.out = 361), # 1周期分のラジアン r = 1, # 半径 x = r * cos(t), y = r * sin(t) ) # 範囲πにおける目盛数を指定 tick_num <- 6 # 角度目盛の座標を作成 rad_tick_df <- tibble::tibble( i = seq(from = 0, to = 2*tick_num-0.5, by = 0.5), # 目盛番号 t = i/tick_num * pi, # ラジアン r = 1, # 半径 x = r * cos(t), y = r * sin(t), major_flag = i%%1 == 0, # 主・補助フラグ grid = dplyr::if_else(major_flag, true = "major", false = "minor") # 目盛カテゴリ )
円周と角度軸目盛の座標を作成します。
偏角の描画用のデータフレームを作成します。
# 半径線の終点の座標を作成 radius_df <- dplyr::bind_rows( # 始線 tibble::tibble( x = 1, y = 0, line_type = "main" # 入出力用 ), # 動径 point_df |> dplyr::select(x, y, line_type = point_type) ) # 角マークの座標を作成 d_in <- 0.2 d_spi <- 0.005 d_out <- 0.3 angle_mark_df <- dplyr::bind_rows( # 元の関数の入力 tibble::tibble( angle = "theta", # 角度カテゴリ u = seq(from = 0, to = theta, length.out = 600), x = (d_in + d_spi*u) * cos(u), y = (d_in + d_spi*u) * sin(u) ), # 逆関数の出力 tibble::tibble( angle = "tau", # 角度カテゴリ u = seq(from = 0, to = tau, length.out = 600), x = d_out * cos(u), y = d_out * sin(u) ) ) # 角ラベルの座標を作成 d_in <- 0.1 d_out <- 0.4 angle_label_df <- tibble::tibble( u = 0.5 * c(theta, tau), x = c(d_in, d_out) * cos(u), y = c(d_in, d_out) * sin(u), angle_label = c("theta", "tau") )
それぞれについて、始線と動径、角マークと角ラベルの座標を作成します。
逆円関数を示す円弧の描画用のデータフレームを作成します。
# 関数円弧の座標を作成 radian_df <- tibble::tibble( u = seq(from = 0, to = tau, length.out = 600), r = 1, # 半径 x = r * cos(u), y = r * sin(u) ) radian_df
# A tibble: 600 × 4 u r x y <dbl> <dbl> <dbl> <dbl> 1 0 1 1 0 2 0.00175 1 1.00 0.00175 3 0.00350 1 1.00 0.00350 4 0.00524 1 1.00 0.00524 5 0.00699 1 1.00 0.00699 6 0.00874 1 1.00 0.00874 7 0.0105 1 1.00 0.0105 8 0.0122 1 1.00 0.0122 9 0.0140 1 1.00 0.0140 10 0.0157 1 1.00 0.0157 # ℹ 590 more rows
ラジアン を作成して、単位円の円周上の(半径が の)円弧の座標 を計算します。
円関数を示す線分の描画用のデータフレームを作成します。
# 関数の描画順を指定 fnc_level_vec <- c("arccos", "cos", "sin") # 関数線分の座標を作成 fnc_seg_df <- tibble::tibble( fnc = c( "cos", "cos", "sin", "sin" ) |> factor(levels = fnc_level_vec), # 関数カテゴリ x_from = c( 0, 0, 0, cos(theta) ), y_from = c( 0, sin(theta), 0, 0 ), x_to = c( cos(theta), cos(theta), 0, cos(theta) ), y_to = c( 0, sin(theta), sin(theta), sin(theta) ) ) fnc_seg_df
# A tibble: 4 × 5 fnc x_from y_from x_to y_to <fct> <dbl> <dbl> <dbl> <dbl> 1 cos 0 0 0.5 0 2 cos 0 -0.866 0.5 -0.866 3 sin 0 0 0 -0.866 4 sin 0.5 0 0.5 -0.866
各線分に対応する関数カテゴリを fnc
列として線の描き分けなどに使います。線分の描画順(重なり順や色付け順)を因子レベルで設定します。
各線分の始点の座標を x_from, y_from
列、終点の座標を x_to, y_to
列として、完成図を見ながら頑張って格納します。
関数ラベルの描画用のデータフレームを作成します。
# 関数ラベルの座標を作成 fnc_label_df <- tibble::tibble( fnc = c("arccos", "cos", "sin") |> factor(levels = fnc_level_vec), # 関数カテゴリ x = c( cos(0.5 * tau), 0.5 * cos(theta), 0 ), y = c( sin(0.5 * tau), 0, 0.5 * sin(theta) ), fnc_label = c("arccos(cos~theta)", "cos~theta", "sin~theta"), a = c( 0, 0, 90), h = c(-0.1, 0.5, 0.5), v = c(-0.5, 1, -0.5) ) fnc_label_df
# A tibble: 3 × 7 fnc x y fnc_label a h v <fct> <dbl> <dbl> <chr> <dbl> <dbl> <dbl> 1 arccos 0.866 0.5 arccos(cos~theta) 0 -0.1 -0.5 2 cos 0.25 0 cos~theta 0 0.5 1 3 sin 0 -0.433 sin~theta 90 0.5 -0.5
関数ごとに1つの線分の中点に関数名を表示することにします。
ラベルの表示角度を a
列、表示角度に応じた左右の表示位置を h
列、上下の表示位置を v
列として指定します。
単位円におけるarccos関数のグラフを作成します。
# ラベル用の文字列を作成 var_label <- paste0( "list(", "r == 1, ", "theta == ", round(theta/pi, digits = 2), " * pi, ", "tau == ", round(tau/pi, digits = 2), " * pi", ")" ) fnc_label_vec <- paste( c("arccos~z", "cos~theta", "sin~theta"), c(tau, cos(theta), sin(theta)) |> round(digits = 2), sep = " == " ) # グラフサイズを設定 axis_size <- 1.5 # 単位円における関数線分を作図 ggplot() + geom_segment(data = rad_tick_df, mapping = aes(x = 0, y = 0, xend = x, yend = y, linewidth = grid), color = "white", show.legend = FALSE) + # θ軸目盛線 geom_segment(mapping = aes(x = c(-Inf, 0), y = c(0, -Inf), xend = c(Inf, 0), yend = c(0, Inf)), arrow = arrow(length = unit(10, units = "pt"), ends = "last")) + # x・y軸線 geom_path(data = circle_df, mapping = aes(x = x, y = y), linewidth = 1) + # 円周 geom_segment(data = radius_df, mapping = aes(x = 0, y = 0, xend = x, yend = y, linewidth = line_type, linetype = line_type), show.legend = FALSE) + # 半径線 geom_path(data = angle_mark_df, mapping = aes(x = x, y = y, group = angle)) + # 角マーク geom_text(data = angle_label_df, mapping = aes(x = x, y = y, label = angle_label), parse = TRUE, size = 5) + # 角ラベル geom_text(mapping = aes(x = 0.5*cos(theta+0.1), y = 0.5*sin(theta+0.1)), label = "r", parse = TRUE, size = 5) + # 半径ラベル:(θ + αで表示位置を調整) geom_point(data = point_df, mapping = aes(x = x, y = y, shape = point_type), size = 4, show.legend = FALSE) + # 円周上の点 geom_segment(mapping = aes(x = cos(theta), y = sin(theta), xend = cos(tau), yend = sin(tau)), linetype = "dotted") + # 動径間の補助線 geom_path(data = radian_df, mapping = aes(x = x, y = y), color = "red", linewidth = 1) + # 関数円弧 geom_segment(data = fnc_seg_df, mapping = aes(x = x_from, y = y_from, xend = x_to, yend = y_to, color = fnc), linewidth = 1) + # 関数線分 geom_text(data = fnc_label_df, mapping = aes(x = x, y = y, label = fnc_label, color = fnc, angle = a, hjust = h, vjust = v), parse = TRUE, show.legend = FALSE) + # 関数ラベル scale_color_manual(breaks = fnc_level_vec, values = c("red", scales::hue_pal()(n = length(fnc_level_vec)-1)), labels = parse(text = fnc_label_vec), name = "function") + # 凡例表示用, 色の共通化用 scale_shape_manual(breaks = c("main", "sub"), values = c("circle", "circle open")) + # 入出力用 scale_linetype_manual(breaks = c("main", "sub"), values = c("solid", "dashed")) + # 入出力用 scale_linewidth_manual(breaks = c("main", "sub", "major", "minor"), values = c(1, 0.5, 0.5, 0.25)) + # 入出力用, 主・補助目盛線用 theme(legend.text.align = 0) + coord_fixed(ratio = 1, xlim = c(-axis_size, axis_size), ylim = c(-axis_size, axis_size)) + labs(title = "circular functions", subtitle = parse(text = var_label), x = expression(x == r ~ cos~theta), y = expression(y == r ~ sin~theta))
偏角(x軸の正の部分からの角度)をラジアン とします。中心角が の弧長は です。よって(ラジアンを用いると)、単位円における( のとき)偏角 と弧長 が一致します。半径が の円周上の点の座標は です。
cos関数の値を 、arccos関数の値を と置く(cos関数の入力を 、arccos関数の出力を とする)と、cos関数が になる偏角(弧長)が であり、 となります。
アニメーションの作成
変数を変化させて、単位円におけるarccos関数のアニメーションを作成します。
作図コードについては「GitHub - anemptyarchive/Mathematics/.../arccos_definition.R」を参照してください。
単位円における偏角とarccos関数の円弧の関係を可視化します。
cos関数の終域 をarccos関数の定義域 として、終域が になるのを確認できます。
単位円と曲線の関係
最後は、単位円と関数曲線のグラフを作成して、変数(ラジアン)と座標の関係を確認します。
作図コードについては「arccos_definition.R」を参照してください。
変数と座標の関係
変数に応じて移動する円周上の点と曲線上の点のアニメーションを作成します。
円周上の点とarccos関数曲線上の点の関係を可視化します。
に対応する偏角(弧長) と曲線の縦軸の値、 と曲線の横軸の値が一致するのを確認できます。
この記事では、逆cos関数を確認しました。次の記事では、逆tan関数を確認します。
おわりに
sin系の関数とcos系の関数は同じようなグラフになるので記事にすると気が引けるのですが、今回の内容だと偏角(円弧)の範囲が異なるのを感じてもらえれば2つ書いた甲斐があります。
ではあと4つ図が複雑になりつつ続きます。
記事投稿日の前日に公開されたエビ中のパフォーマンスver.のMVをどうぞ。
マイペースに ウェイ!
【次の内容】