角度と座標を使った計算には、三角関数が必要になります。この文書では、三角関数について簡単な解説を加え、サンプルスクリプトをご紹介します。

 

 

  1. 三角関数の意義



    高校で習う数学によると、三角関数はつぎのように定義されます。直角三角形の底辺と斜辺のなす角度を θ とする (図1) と、sinθ および cosθ は以下の式の値になります。



    sinθ = 高さ/斜辺

    cosθ = 底辺/斜辺







    三角関数に苦手意識をもつ方は多いようです。その大きな理由のひとつは、この比率にどんな意味があるのかわからないということではないでしょうか。まず、その点からご説明しておきましょう。



    X軸 - Y軸からなる平面の直交座標に、原点を中心とした半径 1 の円を描きます。このとき原点から X軸に対して角度 θ の直線が円周と交わる点の座標は、(cosθ, sinθ) となります (図2)。これは、この交点から X軸に対して垂線を下ろし、角度 θ の線分と垂線および X軸とでつくられる直角三角形を考えてみればわかります。斜辺となる半径が 1 ですから、高さがそのまま sinθ、底辺が cosθ となるからです。しかし、ここではもう三角形のことは忘れて結構です。原点から X軸に対して角度 θ、距離 1 の座標が、(cosθ, sinθ) であるということさえ覚えておけばよいのです。







    2 次元の平面上の位置を特定する場合、直交座標を使うことが一般的です。Flash のステージ上の位置も、直交座標 (x, y) で表わされます。しかし、平面上の位置を決める方法は、直交座標に限られるわけではありません。たとえば、レーダーを考えてみましょう。ここでは「北北西に 1km の距離」といった表現がされます。これは、位置を角度 (東西南北の方向) と距離 (km) とで定めているのです。そして、三角関数はこの角度と距離によって定義された位置を、直交座標に変換するための関数なのです。角度 θ、距離 1 の座標は (cosθ, sinθ) でした。すると、角度 θ で距離 D の位置座標は (D*cosθ, D*sinθ) となります。実際の値は、関数電卓や Flash 5 のアクション (Math オブジェクト) で簡単に求めることができます。Flash の 'Math.sin' や 'Math.cos' メソッドについては、『ActionScript リファレンスガイド』をご参照ください。
  2. tanと逆関数



    三角関数にはもうひとつ tan があります。これはつぎのように定義されます。



    tanθ = 高さ/底辺 = sinθ/cosθ



    X軸 - Y軸の直交座標で表現すると、X軸の距離 1 の点 (1, 0) から立てた垂線と角度 θ の線分との交点の高さになります (図3)。元々は、太陽の角度と物体の影から、物体の実際の高さを計算するという用途で考えられたようです。影の長さが D なら、物体の高さは D*tanθ になるわけです。







    ところで関数には、一般に逆関数というものが考えられます。そして三角関数にも逆関数があります。これは三角関数の値から、逆に角度を返す関数です。数学では 3 つの三角関数それぞれについて、逆関数が定義されています。ただ、座標から三角関数の値を計算する場合、 tan が一番簡単です (sin や cos を求めるには、ピタゴラスの定理を使って原点から座標までの距離を計算しなければなりません)。この tan の逆関数が atan です (アークタンジェントと呼びます)。座標が (x, y) のとき、角度を θ するとつぎの式が成り立ちます。



    tanθ = y / x



    そこで逆関数 atan を使えば、角度 θ はつぎの式で求められます。



    θ = atan(tanθ) = atan(y / x)



    ところが、逆関数 atan には重要な制約があります。角度が 45 度のとき tan は 1 です。しかし角度が 135 度のときも、やはり tan は 1 になるのです。つまり、三角関数 tan の値からは、X 座標が正の場合と負の場合とを区別できません。一般に、関数はかならずひとつの値を返さなければなりません。そこで、逆関数 atan の値は、X 座標が正の場合の -90 度から 90 度の値にするという制約が与えられたのです。したがって、atan を使って座標から角度を求めたいときには、座標値 x と y それぞれの正負も合わせて考えなければなりません。



    Flash には、座標 x と y を評価したうえで角度を返す 'Math.atan2' メソッドがあります。X 座標と Y 座標の値を引数として与えると、ラジアン単位で -π (-180度) から π (180度) の数値を返します。このメソッドを使えば、座標値 x と y の正負の場合分けは必要がありません。'Math.atan2' メソッドについて、詳しくは『ActionScript リファレンスガイド』をご参照ください。
  3. ラジアン

    三角関数をとっつきにくいものにしているもうひとつの理由として、角度の単位があります。三角関数では角度の単位に「ラジアン」を使うことが多いのです。Math オブジェクトでも三角関数には、ラジアンが用いられています。360 度は 2π ラジアンです。すると 1 ラジアンは、約 57.3 度ということになります。なぜこんな半端な単位を使うのでしょうか。



    三角関数は円運動の分析にも使われます。運動を解析する際には、運動の距離を知る必要があります。ところが度数で示される角度は、距離と直接の関係がありません。そこで、また半径 1 の円を基準に考えます。半径 1 の扇形の角度を、その円弧の長さで表わした単位がラジアンなのです。したがって、360 度は円周の長さである 2π になります。1 秒間に半径 1m の円周上を 1 ラジアンの角度移動すれば、その平均速度は 1m/秒ということになるわけです。



    もっとも使う理由がわかったところで、1 ラジアンがどれくらいの角度になるのか想像できる方は少ないでしょう。そこで、度数で表わされる角度とラジアンとの変換の式をご紹介しておきます。π の値は、'Math.PI' 定数で得ることができます(詳しくは『ActionScript リファレンスガイド』を参照)。



    -- [度数をラジアンに変換]

    ラジアン = 度数*Math.PI/180



    -- [ラジアンを度数に変換]

    度数 = ラジアン*180/Math.PI
  4. ムービークリップをマウスポインタの方向に向かせるオブジェクトアクション



    では、'Math.atn2' メソッドを利用した、簡単なアクションのサンプルをご紹介しましょう。以下のオブジェクトアクションをムービークリップのインスタンスに設定すると、ムービークリップがマウスポインタの方向に回転します。X 軸正 (右) の方向が基準となりますので、ムービークリップのマウスポインタに向けたい部分を水平方向右向きに配置します。使用されているプロパティ・メソッドその他のアクションについて、詳しくは『ActionScript リファレンスガイド』の該当項目をご参照ください。



    onClipEvent (enterFrame) {

    var nMouseX = _root._xmouse-this._x;

    var nMouseY = _root._ymouse-this._y;

    var nDegrees = Math.atan2(nMouseY, nMouseX)*180/Math.PI;

    this._rotation = nDegrees;

    }



    アクションについて、簡単にご説明します。まず、第1・第2ステートメントで、ムービークリップからメインタイムライン上のマウスポインタ座標までの水平・垂直距離をローカル変数に代入します。第3ステートメントで、'Math.atan2' メソッドを使って x、y 座標値から角度 (ラジアン) を求め、それを度数に変換したうえで、変数に代入しています。最後の第4ステートメントは、ムービースクリプトの '_rotation' プロパティを、第3ステートメントで得られた角度に設定しています。



    ここで、疑問を持たれた方もあるかもしれません。これまでの説明では、数学的な X-Y の直交座標を前提にしてきました。つまり、垂直方向の Y 軸は上にいくほど数値が大きくなります。ところが、Flash で扱う座標系は左上を原点とし、垂直方向の Y 軸は下に向かって数値が増えます。この点を考慮して、角度を修正する必要はないのでしょうか。結論からいえば、その必要はありません。直交座標は、座標軸が垂直に交わってさえいればよいのです。グラフ用紙を上下逆さにしようが、裏返そうが (こうすると Flash の座標系と同じになります)、座標と角度との関係に変わりはないからです。



    もう 1 点補足します。'Math.atan2' メソッドは、引数の x、y 座標値がともに 0 のとき、Mac OS 上では 'NaN' を返すことがあります ('NaN' について、詳しくは『ActionScript リファレンスガイド』をご参照ください。またこの問題については、別途文書 Math.atan2 メソッドの戻り値が NaN になることがある (fl0188) も併せてご覧ください)。ムービークリップの '_rotation' プロパティを 'NaN' に設定するアクションは動作しません。もっとも、アクションは無視されるだけで、エラーにはなりません。その場合、ただムービークリップの角度が直前の状態から変更されないというだけです。もし、x、y 座標値がともに 0 のときは、角度を 0 に設定したいという場合は、'if' アクションで座標値 (x, y) を評価し、処理を分岐するステートメントを追加します。以下のサンプルをご参照ください。



    onClipEvent (enterFrame) {



    var nMouseX = _root._xmouse-this._x;

    var nMouseY = _root._ymouse-this._y;

    if (nMouseX == 0 && nMouseY == 0) {

    var nDegrees = 0;

    } else {

    var nDegrees = Math.atan2(nMouseY, nMouseX)*180/Math.PI;

    }

    this._rotation = nDegrees;

    }

アドビコミュニティフォーラムをご利用下さい

この文章はお役に立てましたでしょうか?さらに情報をお探しになる場合には、アドビスタッフがお届けし ている解決事例やメンバー同士での活発な意見交換をチェックできるコミュニティフォーラム をご利用下さい。

本作品は Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License によってライセンス許可を受けています。  Twitter™ および Facebook の投稿には、Creative Commons の規約内容は適用されません。

法律上の注意   |   プライバシーポリシー