2012-02-02

Flash学習(17) 三角関数 sin cos

『ActionScript 3.0 アニメーション』を読む。

ActionScript 3.0 アニメーションActionScript 3.0 アニメーション

作者:KeithPeters
出版社/メーカー:ボーンデジタル
発売日:2007-10-30
メディア:単行本

Chapter3 三角関数

角度

度 degree
360度=円、180度=半円、90度=直角
ラジアン radian
2π (6.28)ラジアン=円、1π(3.14)ラジアン=半円、2分の1π(1.57)ラジアン=直角

変換公式

radian = deg * Math.PI / 180;
degree = rad * 180 / Math.PI;

たとえば

  • 180度は 180 * Math.PI / 180 = Math.PI = 3.14ラジアン = 1πラジアン
  • 1度は 1 * Math.PI / 180 = 3.14 / 180 = 0.017ラジアン = 180分のπラジアン
  • 1ラジアンは 1 * 180 / Math.PI = 180 / 3.14 = 57.32度

なぜFlashはラジアンとデグリーの2つを使うのか?→デザイナー向けにはデグリー、プログラマー向けにはラジアンを使うことになったのでは

座標系

数学の座標系
原点 まんなか┼
    ↑ y+
    ↓ y-
← x-  x+ →
角度の計算 ↑が+
Flashの座標系
原点 左上┌
    ↑ y-
    ↓ y+
← x-  x+ →
角度の計算も↓が+

ちなみに IllustratorはCS5でFlashと同じ座標系(Y座標+のとき下↓に行く)になった。それまでは数学的座標系(Y座標+のとき上↑)だった。

角度の計算は、30度+すると、数学の場合Y座標上↑に向かう。Flash座標系では下↓に向かう。下の図はFlash座標系なので \ の線は -30度じゃなくて+30度。(── の線が0度)

三角関数


30度のsin(サイン)は? Math.sin(30*Math.PI/180)) = 0.499.. (0.5近似)
30度のcos(コサイン)は? Math.cos(30*Math.PI/180)) = 0.86..
30度のtan(タンジェント)は? Math.tan(30*Math.PI/180)) = 0.577..

Math.sin(a) の引数aにはデグリーではなく、ラジアンを与える必要あり。なので、Math.sin(30)ではなくMath.sin(30*Math.PI/180)と書いている。

コサイン値 0.86のときの角度は? アークコサインを使う。Math.acos(0.86)*180/Math.PI = 30.68.. →約30度、これはcos30度と一致する
タンジェント値 0.577 のときの角度は? アークタンジェント Math.atan(0.577)*180/Math.PI = 29.98 (約30度)
Math.atan()の返り値はラジアンなので、ここでは「*180/Math.PI」してdegreeに修正している。
しかしアークコサイン、アークタンジェントはほぼ使わない。よく使うのは以下のatan2

座標値を元に角度を求めることもできる。
30度のとき 三角形の1点は (y, x)=(1, 1.73) の座標に位置する。上の図でいうと「30°」と書いてあるところが原点(0,0)。「1」 と「2」の長さの直線の交点が(y,x)。yはFlash座標系なので-1ではなく+1。xは1.73。
点(1, 1.73)の角度は? Math.atan2(1, 1.73)*180/Math.PI = 約30° (下の画像では trace()で計算結果を表示してる)

この「角度」30°っていうのは、y=0の ── に見える直線を+30°回転したとき、(1, 1.73)の点にぶつかるということだな。

次のサンプルはMain.asを使わない。DocumentClassには「RotateToMouse」を指定する‥‥どうやって? FlashDevelopでソースコードの RotateToMouse.as を右クリックして、[Set DocumentClass] を選べばよい。

 

  private function arrowHandler(e:Event):void 
{
var dx:Number = mouseX - arrow.x;
var dy:Number = mouseY - arrow.y;
//var radian:Number = Math.atan(dy / dx); // X座標がマイナスのとき矢印が180°逆を向く
var radian:Number = Math.atan2(dy, dx);
arrow.rotation = radian * 180 / Math.PI;
}

矢印の赤い点が原点。マウスカーソルが (dy, dx)。そこからatan2で算出した角度をdegreeに変換してから rotationプロパティに渡す。

sin値は、移動だけではなく、拡大率(scale)や不透明度(alpha)にあたえるのも効果ある。

  private function ballHander(e:Event):void 
{
ball.x = (ball.x + speedX) % stage.stageWidth;
ball.y = centerY + Math.sin(angle) * range; // -50 < y < +50
ball.scaleX = ball.scaleY = centerScale + Math.sin(angle)/2.0; // 0.5 < scaleX/Y < 1.5
ball.alpha = Math.sin(angle) / 2.0 + 1.0; // 0.5 < alpha < 1.5
angle += speedY;
}

サインカーブを図示する。

楕円軌道: オブジェクトのx座標をcos, y座標をsinにすればよい。正円の場合は radius(半径)を X,Yともに同じ数値にすればいい。

  private function ballHandler(e:Event):void 
{
ball.x = centerX + Math.cos(angle) * radiusX;
ball.y = centerY + Math.sin(angle) * radiusY;
angle += speed;
}

ピタゴラスの定理: 2点の距離を測る。下のFlash swfはマウスカーソルとの距離(ピクセル)を測る。

  private function mouseHandler(e:MouseEvent):void 
{
graphics.clear();
graphics.lineStyle(1, 0, 0.3);
graphics.moveTo(origin.x, origin.y);
graphics.lineTo(mouseX, mouseY);
var dx:Number = origin.x - mouseX;
var dy:Number = origin.y - mouseY;
var dist:Number = Math.sqrt(dx * dx + dy * dy);
tfd.x = mouseX - 5; tfd.y = mouseY + 30;
tfd.text = "距離: " + Math.floor(dist).toString() + " px";
}

0 件のコメント:

コメントを投稿

人気記事