逆正接を使う必要が生じた
先日リリースしたピクチャレ大会の目玉機能としてスマホで記録コンポーネントをスワイプすると
左右それぞれある閾値を超えたらリンク先へ自動ジャンプするという仕組みを作りました。
ただ、いざリリースして本番環境をiPhoneで動作確認すると大きな問題があることが発覚。
iPhoneだとページスクロールのためのスワイプ動作もこの仕組みが検知してしまうため、
ページスクロールしたいのにスワイプメニューが動くのでスクロールできないという現象が起きてしまいます。
これでは使い物にならないので改善案を出すべくいろいろ考えていました。
結論から言うと三角比の一つ「逆正接(アークタンジェント、atan)」を使えば解決できるのですが、
なんでそれで解決できるのか自分の言葉で説明できないのはモヤるのでブログに経緯を書き残します。
まず、この問題はページスクロールとスワイプメニューの動作が混在してしまうことです。
一般に、スマホのページスクロールは縦方向に行われるのに対して、
スワイプメニューは横方向に行われることを想定しています。
つまり、縦のときは動作させないようにすればいい。
具体的には、スワイプ操作の始点と終点を結ぶ角度が45度以上なら動作しないようにすればいいわけです。
ここで問題になるのが「始点と終点を結ぶ角度」をどうやって算出するのかという問題です。
始点と終点は分かっているので、これはそれぞれ直角三角形ABCのAとCに割り当てることができます(ACが斜辺)。
このとき、辺ABの長さがX軸の移動量、辺BCがY軸の移動量と考えることができ、
これらは始点と終点の差分を計算することによって求めることができます。
角度θに対する辺ABと辺BCの比率をタンジェントといい、次のように計算できます。
tan(θ) = AB / BC
ところが今回はそもそも関数に入れる角度θを求めたいので、この関数と逆のことをしなければなりません。
この「逆のこと」に相当する数学用語が逆関数です。
関数f(x) = y
の逆関数は慣例的にf(y)^-1 = x
と表記しますが、別にマイナス1乗するわけではありません。
逆関数の表記はさまざまで、タンジェントではそれに相当するのが「アークタンジェント(arctan)」となります。
逆関数の解は単純な公式によって導けるものではないらしく、多少ググったくらいでは求め方が出てきませんでした。
そもそも本来引数として与えられる値が分からないのでどうしようもないというわけです。
そこでプログラミングの世界ではMath.atan2(x, y)
というめちゃくちゃ便利な関数があり、
これにXの移動量、Yの移動量を入れると内部で複雑な計算をして角度を算出してくれる仕組みになっています。atan2()
はWikipediaにも単独記事があり、歴史のある有名な関数みたいです。
結局アークタンジェントの求め方は理解することができませんでしたが、
数学も深掘りしようとすると果てしないということを改めて認識するとともに、
高校数学の範囲はweb制作でもお目にかかることがあるのだと改めて危機感を抱きました。