Adobe
製品
Acrobat
Creative Cloud
Creative Suite
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
その他の製品一覧
ソリューション
デジタルマーケティング
デジタルメディア
教育
金融機関
Web Experience Management
その他のソリューション
ラーニング サポート ダウンロード 会社情報
ご購入
アドビストア 安心のサポート& サービス
アカデミックストア 学生、教職員、個人向け
アドビライセンスストア 中小企業向け
ボリュームライセンスについて 企業、教育機関、官公庁向け
販売パートナー
キャンペーン情報
検索
 
情報 サインイン
ようこそ、 さん カート 注文状況 マイアカウント
マイアカウント
注文状況
アカウント情報の変更
コミュニケーションの設定を変更
サインアウト
サインインの目的 お客様のアカウントや体験版ダウンロード、製品の拡張機能、コミュニティエリアへのアクセスなどを管理するため
Adobe
製品 セクション ご購入   検索  
ソリューション 会社情報
サポート ラーニング
サインイン サインアウト 注文状況 マイアカウント
先行予約の提供開始予定日Date. 商品が発送されるまで、クレジットカードには課金されません。提供開始の予定日は変更される場合があります。 先行予約の提供開始予定日Date. ダウンロードの準備が整うまで、クレジットカードには課金されません。提供開始の予定日は変更される場合があります。
個数:
ご購入には学生・教職員個人版の購入資格の確認が必要です。
小計
カートの中身を見る
Adobe Developer Connection / Flashデベロッパーセンター /

Matrix3Dクラス - 変換行列2

著者 野中 文雄氏

野中 文雄氏
  • Fumio Nonaka
  • http://www.fumiononaka.com/

作成日

18 November 2008

ページ ツール

Facebookでシェア
Twitterでツイート
LinkedInでシェア
ブックマーク
印刷

タグ

必要条件

ユーザーレベル

すべて

必要な製品

  • Flash Professional CS4 (Download trial)

サンプルファイル

  • Matrix3D_samples.zip (71 KB)

はじめに

Flash Player 10からMatrix3Dクラスが実装され*1、3次元座標空間の変換行列が扱えるようになりました。そこで、Matrix3Dクラスの変換行列を使い*2 、マウスポインタの位置に合わせて3次元座標空間で平面を回転させるサンプルスクリプトについて解説します。

*1 併せて、FumioNonaka.com「Matrix3Dクラス」をご参照ください。

*2 2次元座標空間を扱うMatrixクラスの変換行列については、「Matrixクラス - 変換行列」で解説しました。変換行列の意義については、この記事の01「変換行列(Matrixクラス)とは」をお読みください。

01 Matrix3D.prependRotation()メソッド

3次元座標空間でMovieClipなどの(DisplayObjectクラスまたはそのサブクラスの)インスタンスを回転するには、Matrix3D.prependRotation()メソッド*3 が使えます。メソッドのシンタックスは、つぎのとおりです。

prependRotation(度数:Number, 軸:Vector3D):void

第1引数には、加える回転角を度数で指定します。第2引数は、回転の軸をxyzからひとつ選びます*4 。Vector3Dクラスの定数で指定するのがよいでしょう。それぞれ、Vector3D.X_AXIS、Vector3D.Y_AXIS、Vector3D.Z_AXISとなります*5 。

では、メインタイムラインにMovieClipインスタンスmy_mcを置きます。そして、Matrix3Dインスタンスは、MovieClipインスタンスのDisplayObject.transformプロパティから、Transform.matrix3Dプロパティとして取得します。ところが、メインタイムラインのフレームアクションにつぎのようにスクリプトを記述すると、ランタイムエラーになります(図001)。

my_mc.transform.matrix3D.prependRotation(30,Vector3D.Y_AXIS);

そして、[出力]パネルに表示されるエラーメッセージはつぎのとおりです。

TypeError: Error #1009: null のオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。

図001 フレームアクションがランタイムエラーになる

図001 フレームアクションがランタイムエラーになる
「オブジェクト参照」がnullだと告げる。

これは、インスタンスの。DisplayObject.transformプロパティが、デフォルトではTransform.matrix3Dプロパティをもたず、nullを返すからです。このMatrix3Dインスタンスは、DisplayObject(またはそのサブクラス)のインスタンスに3次元座標の操作をしたとき、自動的に生成される仕組みになっています。そのためには、たとえばDisplayObject.zプロパティにデフォルト値0を設定するだけで足ります。

したがって、上記フレームアクションに、この操作を加えてつぎのように修正すれば、3次元座標空間においてインスタンスはy軸で水平方向に30度回転します(図002)。なお、Matrix3Dクラスを使った変換には、パースペクティブが適用されるので、インスタンスは回転角に応じて台形に変形されます。

my_mc.z = 0; my_mc.transform.matrix3D.prependRotation(30, Vector3D.Y_AXIS);

図002 3次元座標空間において水平方向に回転したインスタンス

図002 3次元座標空間において水平方向に回転したインスタンス
Matrix3D.prependRotation()メソッドに回転角30度とy軸を指定して、3次元座標空間でインスタンスを回転した。

それでは、マウスポインタの水平座標位置に合わせて、インスタンスをy軸で水平に回転させてみます。回転のアニメーションは、DisplayObject.enterFrameイベント 定数Event.ENTER_FRAME にリスナー関数として登録します*6。関数名は、xRotate としましょう。フレームアクションは、つぎのスクリプト001のようになります。

スクリプト001 3次元座標空間におけるインスタンスをy軸で回転させる

// タイムライン: メイン // 第1フレームアクション var nX:Number = my_mc.x; var nDeceleration:Number = 0.3;   // 回転スピードの調整係数 my_mc.z = 0;   // 3次元座標のプロパティを操作 addEventListener(Event.ENTER_FRAME, xRotate); function xRotate(eventObject:Event):void {               var nRotationY:Number = (mouseX - nX)*nDeceleration;               // 3次元座標空間においてy軸でインスタンスを回転               my_mc.transform.matrix3D.prependRotation(nRotationY, Vector3D.Y_AXIS); }

回転角の大きさは、インスタンスの基準点から見たマウスポインタの水平座標値に、調整係数を掛合わせて決めています。したがって、インスタンスから水平方向にマウスポインタを離すほど、インスタンスが水平に回転するスピードは増します(図003)。

図003■インスタンスがマウスポインタの位置に応じて水平に回転

図003■インスタンスがマウスポインタの位置に応じて水平に回転
回転スピードは、インスタンスの基準点から見たマウスポインタの水平座標値に比例させた。

*3  Matrix3D.prependRotation()メソッドには、オプションの(省略可能な)第3引数としてVectorインスタンスで中心点を指定できます。デフォルトは、インスタンスの基準点になります。

*4  インスタンスの回転する方向は、x軸なら垂直で、y軸では水平になることに注意しましょう。

*5  [ヘルプ]の[Matrix3D]クラスの解説中には、「_」(アンダースコア)のないVector3D.XAXIS、Vector3D.YAXIS、Vector3D.ZAXISと誤って記載されていることがあります。

*6  EventDispatcher.addEventListener()メソッドを使ったイベントリスナーの登録の仕方について、詳しくはGihyo.jp連載「ActionScript 3.0で始めるオブジェクト指向スクリプティング」の第5回「イベントリスナーを使う」をお読みください。

02 変換行列を適用する順序

前掲スクリプト001に、y軸の水平回転だけでなく、x軸による垂直の回転も加えてみましょう。以下のフレームアクションのように、y座標についてもx座標と同じ処理を加えればよさそうに思われます。

var nX:Number = my_mc.x;               var nY:Number = my_mc.y;               var nDeceleration:Number = 0.3;               my_mc.z = 0;               addEventListener(Event.ENTER_FRAME, xRotate);               function xRotate(eventObject:Event):void {                             var nRotationY:Number = (mouseX - nX)*nDeceleration;                             var nRotationX:Number = (mouseY - nY)*nDeceleration;                             my_mc.transform.matrix3D.prependRotation(nRotationY, Vector3D.Y_AXIS);                             my_mc.transform.matrix3D.prependRotation(nRotationX, Vector3D.X_AXIS);               }

上記のステートメント追加により、確かにインスタンスが垂直方向に回転するようになります。しかし、その回転の軸に違和感があります。マウスポインタを垂直に動かしたとき、ステージ上のインスタンスの状態から垂直に回転しません。いわばインスタンスが正面を向いた状態で垂直に回り、配置されたタイムラインのx軸でなく、インスタンス自身のx軸で回転しているように見えます(図004)。

図004 マウスポインタを垂直に動かすとインスタンスのx軸で回転

図004 マウスポインタを垂直に動かすとインスタンスのx軸で回転
マウスポインタを垂直に動かしたとき、配置されたタイムラインのx軸でなく、インスタンス自身のx軸で回転する。

これは変換を適用する順序に原因があります。変換をまったく加えていないデフォルト状態のインスタンスは、位置が親タイムラインの基準点にあり、拡大・縮小は行わない比率1の実寸、回転角も0の状態です(図005)。

図005 変換を行う前のデフォルト状態

図005 変換を行う前のデフォルト状態
位置は親タイムラインの基準点、拡大・縮小は比率1、回転角0。

そのインスタンスをオーサリング時のステージ上でも、あるいはランタイム時にスクリプトによってでも、移動したり、拡大・縮小したり、回転したりすると、変換が加えられたことになり、DisplayObject.transformプロパティのTransform.matrix3Dプロパティにその変換行列が設定されます*7。

Matrix3Dで移動 「平行移動」とも呼ばれます や拡大・縮小、回転を行うメソッドには、下表001のように変換を前に prepend 適用するものと、後に append 適用するものとがあります。そして、前に適用するメソッドは、インスタンスに設定されている現在のTransform.matrix3Dプロパティつまり変換行列を一旦デフォルトに戻し、メソッドの変換を先に加えてから、もとの変換行列 Transform.matrix3Dプロパティ を後から適用するのです。

表001■Matrix3Dクラスの移動/拡大・縮小/回転のメソッド

変換 変換を前に適用するメソッド 変換を後に適用するメソッド 変換結果
平行移動 Matrix3D.prependTranslation() Matrix3D.appendTranslation() 図006
拡大・縮小 Matrix3D.prependScale() Matrix3D.appendScale() 図007
回転 Matrix3D.prependRotation() Matrix3D.appendRotation() 図008

先ほど試したフレームアクションでは、Matrix3D.prependRotation()メソッドによりx軸で回転しました。そのため、インスタンスは一旦デフォルトに戻り、回転を何も加えていない正面向きになります。それをx軸で回す訳ですから、つねに正面向きからの回転にしかならないのです。変換行列は、適用の順序が変わると、その結果が変わることにご注意ください*8 。これは、フィルタを適用する順番が変わると、その効果が変わってくるのに似ています。

したがって、インスタンスの現在の状態を回転しようというときには、後から変換するMatrix3D.appendRotation()メソッドを使うべきだということになります。ただし、この場合ひとつ気をつけることがあります。変換行列は、原点を基準として座標を変換します。この原点は、親タイムラインの基準点になります。つまり、インスタンスの変換は、配置された親タイムラインの基準点を中心に加えられるのです。ちょうど[自由変形ツール]で、中心点を親タイムラインの基準点に設定した状態と考えればよいでしょう(図006)。

図006 [自由変形ツール]で中心点を親タイムラインの基準点に設定

008
中心点に設定した親タイムラインの基準点を中心に、変形が加えられる。

03 変換行列を後から適用する

それでは、改めてx軸で回す処理をスクリプト001に加えます。具体的に変換行列をどのように適用すればよいでしょう。

インスタンスを親タイムラインの基準点に置かないかぎり、回転はインスタンスの基準点でなく、その親タイムラインの基準点を原点として適用されてしまいます。かといって、インスタンスを完全にデフォルトに戻してしまうと、意図した回転ができませんでした。だとすれば、必要な値だけを個別にデフォルトに戻すのです。

回転について問題になっているのは、インスタンスの位置です。したがって、インスタンスを親タイムラインの基準点に平行移動すれば、インスタンスを自身の基準点で回すことができます。そして、回転し終えたら、位置をまた平行移動してもとに戻せばよいのです。

平行移動を後から適用するメソッドは、Matrix3D.appendTranslation()です(前掲表001)。シンタックスはつぎのとおりです。

appendTranslation(x座標:Number, y座標:Number, z座標:Number):void

Matrix3D.appendTranslation メソッドの3つの数値の引数には、移動する座標値つまり現在の座標に加算するxyz座標値を指定します。なお、後から回転を加えるメソッドはMatrix3D.appendRotation で、シンタックスはMatrix3D.prependRotation メソッドと基本的に同じです。これらのメソッドを使って前掲スクリプト001は、つぎのように修正されます スクリプト002 。

スクリプト002 3次元座標空間におけるインスタンスをx軸とy軸で回転させる

// タイムライン: メイン // 第1フレームアクション var nX:Number = mySprite.x; var nY:Number = mySprite.y; var nDeceleration:Number = 0.3; mySprite.z = 0; addEventListener(Event.ENTER_FRAME, xRotate); function xRotate(eventObject:Event):void {               var nRotationY:Number = (mouseX - nX)*nDeceleration;               var nRotationX:Number = (mouseY - nY)*nDeceleration;               // 3次元座標空間でインスタンスを回転               mySprite.transform.matrix3D.appendTranslation(-nX, -nY, 0);   // 親タイムラインの基準点に移動               mySprite.transform.matrix3D.appendRotation(nRotationY, Vector3D.Y_AXIS);               mySprite.transform.matrix3D.appendRotation(nRotationX, Vector3D.X_AXIS);               mySprite.transform.matrix3D.appendTranslation(nX, nY, 0);   // 位置を戻す }

まず、予め取得しておいたインスタンスのxy座標値をともにマイナスにして引数とし、変換行列(Transform.matrix3Dプロパティ)にMatrix3D.appendTranslation()メソッドを適用します。すると、インスタンスの位置は親タイムラインの基準点に移動します。しかし、位置以外の回転などの変換は、もとのインスタンスと同じ状態が保たれます。

そこで、Matrix3D.appendRotation()メソッドにより、y軸とx軸の回転を後から加えます。そのうえで、改めてインスタンスのもとの位置のxy座標を引数として、Matrix3D.appendTranslation()メソッドを後から適用することにより、インスタンスの位置を戻します。これで、ステージ上のインスタンスの状態をもとに、マウスポインタの位置に応じてインスタンスがx軸およびy軸で回転します(図007)。

図007 ステージ上のインスタンスの状態から水平・垂直に回転

図007 ステージ上のインスタンスの状態から水平・垂直に回転
ステージ上のインスタンスの状態から、マウスポインタの位置に合わせて、インスタンスが水平・垂直に回転する。

*7 前述のとおり、インスタンスはデフォルトではTransform.matrix3Dプロパティをもたず、プロパティ値はnullになりますので、インスタンスに3次元座標空間の操作が加えられたものとします。

*8 変換行列の適用は、数学的には行列の乗算になります。変換行列の数学的な捉え方については、FumioNonaka.com「変換行列を数学的に捉える」をお読みください。

製品

  • Acrobat
  • Creative Cloud
  • Creative Suite
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Elements
  • モバイルアプリ
  • Photoshop
  • Touch Apps

ソリューション

  • デジタルマーケティング
  • コンテンツオーサリング
  • Web Experience Management

業種別ソリューション

  • 教育
  • 金融機関

サポート

  • ヘルプ&サポート
  • 注文と返品
  • ダウンロードに関するヘルプ
  • ユーザー登録に関するヘルプ

ラーニング

  • ADC: Adobe Developer Center
  • Adobe TV
  • Design Magazine
  • Photoshop Magazine
  • Focus In

ご購入方法

  • アドビストア
  • アカデミックストア
  • アドビライセンスストア
  • ボリュームライセンスについて
  • 販売パートナー
  • キャンペーン情報

ダウンロード

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

会社情報

  • プレスルーム
  • パートナープログラム
  • 企業の社会的責任(英語)
  • 採用情報
  • 投資家の皆様へ(英語)
  • イベント&セミナー
  • Legal(英語)
  • セキュリティ
  • お問い合わせ
国・地域および言語の選択 日本(変更)
国・地域および言語の選択 閉じる

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • ישראל - עברית
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • الشرق الأوسط وشمال أفريقيا - اللغة العربية
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

利用条件 | プライバシーポリシーとCookie (更新)

Reviewed by TRUSTe: site privacy statement