Accelerometer クラスについて
■Accelerometer クラスについて
Accelerometer クラスは、加速度センサーを利用するための機能がまとまっています。
■加速度センサーに対応しているか調べる
加速度センサーをサポートしているか調べるには、Accelerometer.isSupported プロパティを使用します。
true であれば、利用可能です。
加速度センサーが利用可能か調べる
import flash.sensors.Accelerometer;
import flash.text.TextField;
// テキストフィールドを作成
var text_field:TextField = new TextField();
text_field.x = 10;
text_field.y = 10;
text_field.width = stage.stageWidth - 20;
text_field.height = 20;
text_field.border = true;
stage.addChild(text_field);
text_field.text = "加速度センサーのサポート:" + Accelerometer.isSupported;
■ユーザーが加速度センサーをミュートしているか調べる
ユーザーが、加速度センサーの利用を停止しているか調べるには、muted プロパティを使用します。
true であれば、利用できません。
加速度センサーがミュート設定か調べる
import flash.sensors.Accelerometer;
import flash.text.TextField;
// テキストフィールドを作成
var text_field:TextField = new TextField();
text_field.x = 10;
text_field.y = 10;
text_field.width = stage.stageWidth - 20;
text_field.height = 20;
text_field.border = true;
stage.addChild(text_field);
// アクセラレータオブジェクトを作成
var accelerometer:Accelerometer = new Accelerometer();
text_field.text = "加速度センサーのミュート設定:" + accelerometer.muted;
■加速度センサーで加速度を検出する
加速度センサーを利用することにより、以下の加速度を検出することができます。
■重力加速度を検出する
地球上にデバイスが存在すると、常に重力の影響を受け続ける事になります。
実際に加速度センサーの値を取得してみると、静止している状態でも常に「真下方向に、長さが 1 のベクトル」を検出することができます。
デバイスの真下の方向を知ることができるので、デバイスがどれだけ傾いているかを計算できます。
東西南北上下の、どの方向を向いているかは計算できません。
■遠心力を検出する
デバイスを手に持って振り回す回転運動を行うと、外側に向かって遠心力が発生します。
遠心力は、加速度センサーで検出することができます。
回転運動を行っている間は、一定の遠心力が常に働き続けます。
■加速移動時の慣性力を検出する
デバイスを加速させる運動を行うと、進行と反対の方向に、慣性力(止まり続けようとする力)が発生します。
車が急発進したときに、後ろに吹っ飛んで座席に押し付けられる感じです。
デバイスの加速は、加速度センサーで検出することができます。
等速で移動中の場合は、慣性は発生しないので加速度センサーで検出できません。
■減速移動時の慣性力を検出する
デバイスを減速させる運動を行うと、移動した方向に、慣性力(移動し続けようとする力)が発生します。
車が急停止したときに前に吹っ飛んでシートベルトに引っかかる感じです。
デバイスの減速は、加速度センサーで検出することができます。
等速で移動中の場合は、慣性は発生しないので加速度センサーで検出できません。
■取得できる加速度の座標系について
加速度は、3Dベクトルとして取得することができます。
Flash の画面の向きを基準とした座標系となります。
Flash の画面の左右方向が x 軸となります。
Flash の画面の上下方向が y 軸となります。
Flash の画面の前後方向が z 軸となります。
■加速度の方向について
加速度センサーは、重力加速度(9.8 m/s2)を約 1.0 として取得できます。
地球上にあるデバイスは重力の影響を受け続けます。
デバイスを動かさなかったとしても、「長さが 1.0 のベクトル」を常に検出することができます。
加速度の座標系の正の方向は、以下の通りです。
Flash の座標系の正の方向とは違うので注意します。
x 軸方向について
端末の右端を下方向に向けると負の値が取得できます。
端末の左端を下方向に向けると正の値が取得できます。
端末の右端を外側に向けて回転運動を行うと、負の値が取得できます。
端末の左端を外側に向けて回転運動を行うと、正の値が取得できます。
端末を右方向に加速させると、正の値が取得できます。
端末の右方向に減速させると、負の値が取得できます。
端末を左方向に加速させると、負の値が取得できます。
端末の左方向に減速させると、正の値が取得できます。
y 軸方向について
端末の上端を下方向に向けると負の値が取得できます。
端末の下端を下方向に向けると正の値が取得できます。
端末の上端を外側に向けて回転運動を行うと、負の値が取得できます。
端末の下端を外側に向けて回転運動を行うと、正の値が取得できます。
端末を上方向に加速させると、正の値が取得できます。
端末の上方向に減速させると、負の値が取得できます。
端末を下方向に加速させると、負の値が取得できます。
端末の下方向に減速させると、正の値が取得できます。
z 軸方向について
端末の表側(液晶がある方)を下方向に向けると負の値が取得できます。
端末の裏側(液晶がない方)を下方向に向けると正の値が取得できます。
端末の表側を外側に向けて回転運動を行うと、負の値が取得できます。
端末の裏側を外側に向けて回転運動を行うと、正の値が取得できます。
端末を手前方向に加速させると、正の値が取得できます。
端末の手前方向に減速させると、負の値が取得できます。
端末を奥方向に加速させると、負の値が取得できます。
端末の奥方向に減速させると、正の値が取得できます。
加速度を取得する
サンプルをダウンロード
■加速度センサーの取得時間隔を変更する
加速度センサーの取得時間隔を変更するには、setRequestedUpdateInterval() メソッドを使用します。
引数に、取得したい時間隔をミリ秒で指定します。
加速度センサーの取得時間隔を 10 ミリ秒に変更する
import flash.sensors.Accelerometer;
// 加速度センサー利用可能
if(Accelerometer.isSupported){
// アクセラレータオブジェクトを作成
var accelerometer:Accelerometer = new Accelerometer();
// 取得時間隔を変更
accelerometer.setRequestedUpdateInterval(10);
}
■加速度を取得する
■イベントから加速度を取得する
加速度を取得するには、AccelerometerEvent.UPDATE イベントを使用します。
一定の時間隔で、登録した関数が呼び出されます。
■AccelerometerEvent クラスのプロパティについて
AccelerometerEvent クラスには、以下のプロパティがあります。
プロパティ名 | 型 | 解説 |
accelerationX | Number | x 軸方向の加速度 |
accelerationY | Number | y 軸方向の加速度 |
accelerationZ | Number | z 軸方向の加速度 |
timestamp | Number | 初期化されてからイベント発生時までの時間(秒) |
■加速度を取得する
取得例です。
加速度を取得する
import flash.sensors.Accelerometer;
import flash.text.TextField;
import flash.events.AccelerometerEvent;
// テキストフィールドを作成
var text_field:TextField = new TextField();
text_field.x = 10;
text_field.y = 10;
text_field.width = stage.stageWidth - 20;
text_field.height = 100;
text_field.border = true;
stage.addChild(text_field);
// 加速度センサー利用可能
if(Accelerometer.isSupported){
// アクセラレータオブジェクトを作成
var accelerometer:Accelerometer = new Accelerometer();
// 取得時間隔を変更
accelerometer.setRequestedUpdateInterval(10);
// 更新がある度に実行されるイベント
accelerometer.addEventListener(AccelerometerEvent.UPDATE, function (e:AccelerometerEvent):void{
// 加速度をテキストフィールドに出力
var str:String = "";
str += "x:" + e.accelerationX + "\n";
str += "y:" + e.accelerationY + "\n";
str += "z:" + e.accelerationZ + "\n";
text_field.text = str;
});
}
■デバイスを振り回したかを調べる
■加速度の変化を計算する
加速度センサーで得られる値は、重力加速度や遠心力や慣性が、すべて合成された結果となります。
デバイスをどのように振り回したかを調べたい場合は、重力加速度成分が不要となります。
そこで、前回の加速度の値を残しておいて、次回の加速度との差分を計算して、加速度の変化を調べます。
加速度の変化から、「突き」「払い」「左右に振る」「ひねる」といった動作を推測できるようになります。
■取得例
取得例です。
加速度の変化を取得する
import flash.sensors.Accelerometer;
import flash.geom.Vector3D;
import flash.text.TextField;
import flash.events.AccelerometerEvent;
// テキストフィールドを作成
var text_field:TextField = new TextField();
text_field.x = 10;
text_field.y = 10;
text_field.width = stage.stageWidth - 20;
text_field.height = 100;
text_field.border = true;
stage.addChild(text_field);
// 前回の加速度ベクトル
var acc_vector_old:Vector3D = new Vector3D();
// 加速度センサー利用可能
if(Accelerometer.isSupported){
// アクセラレータオブジェクトを作成
var accelerometer:Accelerometer = new Accelerometer();
// 取得時間隔を変更
accelerometer.setRequestedUpdateInterval(10);
// 更新がある度に実行されるイベント
accelerometer.addEventListener(AccelerometerEvent.UPDATE, function (e:AccelerometerEvent):void{
// 今回の加速度ベクトルと前回の加速度ベクトルとの差分を計算
var x:Number = e.accelerationX - acc_vector_old.x;
var y:Number = e.accelerationY - acc_vector_old.y;
var z:Number = e.accelerationZ - acc_vector_old.z;
// 今回の加速度ベクトルを残す
acc_vector_old.x = e.accelerationX;
acc_vector_old.y = e.accelerationY;
acc_vector_old.z = e.accelerationZ;
// 加速度の変化をテキストフィールドに出力
var str:String = "";
str += "x:" + x + "\n";
str += "y:" + y + "\n";
str += "z:" + z + "\n";
text_field.text = str;
});
}
デバイスのデバイスの傾きを取得する
■デフォルトの姿勢を確認する
Flash コンテンツの仕様から、デバイスのデフォルトの姿勢を確認します。
大抵の場合、「水平に置いている」か「垂直に立てている」状態になるのではないでしょうか。
■デバイスを水平に置いている場合
■傾けていないデフォルトの姿勢を確認する
液晶のない裏面が、真下を向いている状態です。
このとき重力加速度は、x:0.0 y:0.0 z:1.0 となります。
■2次元情報として計算する
水平に置いている状態から、デバイスを 90 度以上傾けると、液晶面が裏側を向きます。
物理的に液晶面が見えなくなるので、ユーザーがデバイスを 90 度以上傾ける事はないと想定します。
これを利用して、3次元情報ではなく2次元情報として計算してみます。
単純に z 軸情報を無視して、x 軸と y 軸の2次元ベクトルとします。
Flash の座標系に落とし込むには、x 軸を反転させる必要があります。
この2次元ベクトルの方向成分を、傾いている方向とします。
また、2次元ベクトルの長さ成分を、傾きの強さとします。
水平に置いた状態からの傾きを Flash の2次元座標系で取得する
import flash.sensors.Accelerometer;
import flash.geom.Point;
import flash.text.TextField;
import flash.events.AccelerometerEvent;
// テキストフィールドを作成
var text_field:TextField = new TextField();
text_field.x = 10;
text_field.y = 10;
text_field.width = stage.stageWidth - 20;
text_field.height = 100;
text_field.border = true;
stage.addChild(text_field);
// 加速度センサー利用可能
if(Accelerometer.isSupported){
// アクセラレータオブジェクトを作成
var accelerometer:Accelerometer = new Accelerometer();
// 取得時間隔を変更
accelerometer.setRequestedUpdateInterval(10);
// 更新がある度に実行されるイベント
accelerometer.addEventListener(AccelerometerEvent.UPDATE, function (e:AccelerometerEvent):void{
// x 軸と y 軸を取得する
var vec:Point = new Point();
vec.x = -e.accelerationX;
vec.y = e.accelerationY;
// ベクトルから傾いている方向(角度)を取得する
var r:Number = Math.atan2(vec.y,vec.x) * 180 / Math.PI;
// ベクトルから傾きの強さを取得する
var s:Number = vec.length;
// 方向と強さをテキストフィールドに出力
var str:String = "";
str += "r:" + r + "\n";
str += "s:" + s + "\n";
text_field.text = str;
});
}
■3次元情報として計算する
デバイスの傾きの角度を調べるには、2つの3次元ベクトルの角度差を計算します。
デフォルトの状態の加速度ベクトル (0,0,1)と、現在の姿勢の加速度ベクトルとの角度差を計算します。
デバイスをデフォルトの状態から傾けた角度を調べる
import flash.sensors.Accelerometer;
import flash.geom.Vector3D;
import flash.text.TextField;
import flash.events.AccelerometerEvent;
// テキストフィールドを作成
var text_field:TextField = new TextField();
text_field.x = 10;
text_field.y = 10;
text_field.width = stage.stageWidth - 20;
text_field.height = 100;
text_field.border = true;
stage.addChild(text_field);
// 加速度センサー利用可能
if(Accelerometer.isSupported){
// アクセラレータオブジェクトを作成
var accelerometer:Accelerometer = new Accelerometer();
// 取得時間隔を変更
accelerometer.setRequestedUpdateInterval(10);
// 更新がある度に実行されるイベント
accelerometer.addEventListener(AccelerometerEvent.UPDATE, function (e:AccelerometerEvent):void{
// 水平に置いた状態の加速度
var acc0:Vector3D = new Vector3D(0,0,1);
// 現在の加速度
var acc1:Vector3D = new Vector3D(e.accelerationX,e.accelerationY,e.accelerationZ);
// ベクトルを正規化
acc0.normalize();
acc1.normalize();
// 2つの3Dベクトルの角度差を計算する
var dot:Number = ((acc0.x * acc1.x) + (acc0.y * acc1.y) + (acc0.z * acc1.z));
var rot:Number = Math.acos(dot) * 180.0 / Math.PI;
// 角度をテキストフィールドに出力
text_field.text = "r:" + rot;
});
}
得られる値は、0 ~ 180までの角度となります。
次に、回転軸を調べます。
デバイスの回転軸を調べる
import flash.sensors.Accelerometer;
import flash.geom.Vector3D;
import flash.text.TextField;
import flash.events.AccelerometerEvent;
// テキストフィールドを作成
var text_field:TextField = new TextField();
text_field.x = 10;
text_field.y = 10;
text_field.width = stage.stageWidth - 20;
text_field.height = 100;
text_field.border = true;
stage.addChild(text_field);
// 加速度センサー利用可能
if(Accelerometer.isSupported){
// アクセラレータオブジェクトを作成
var accelerometer:Accelerometer = new Accelerometer();
// 取得時間隔を変更
accelerometer.setRequestedUpdateInterval(10);
// 更新がある度に実行されるイベント
accelerometer.addEventListener(AccelerometerEvent.UPDATE, function (e:AccelerometerEvent):void{
// 水平に置いた状態の加速度
var acc0:Vector3D = new Vector3D(0,0,1);
// 現在の加速度
var acc1:Vector3D = new Vector3D(e.accelerationX,e.accelerationY,e.accelerationZ);
// ベクトルを正規化
acc0.normalize();
acc1.normalize();
// 2つの3Dベクトルの角度差を計算する
var rot:Number = Vector3D.angleBetween(acc0,acc1) * 180 / Math.PI;
// 2つの3Dベクトルの外積を計算する
var cro:Vector3D = acc0.crossProduct(acc1);
// 角度と回転軸をテキストフィールドに出力
var str:String = "";
str += "r:" + rot + "\n";
str += "x:" + cro.x + "\n";
str += "y:" + cro.y + "\n";
str += "z:" + cro.z + "\n";
text_field.text = str;
});
}
デバイスの傾きを行列として計算する
import flash.sensors.Accelerometer;
import flash.geom.Vector3D;
import flash.geom.Matrix3D;
import flash.text.TextField;
import flash.events.AccelerometerEvent;
// 加速度センサー利用可能
if(Accelerometer.isSupported){
// アクセラレータオブジェクトを作成
var accelerometer:Accelerometer = new Accelerometer();
// 取得時間隔を変更
accelerometer.setRequestedUpdateInterval(10);
// 更新がある度に実行されるイベント
accelerometer.addEventListener(AccelerometerEvent.UPDATE, function (e:AccelerometerEvent):void{
// 水平に置いた状態の加速度
var acc0:Vector3D = new Vector3D(0,0,1);
// 現在の加速度
var acc1:Vector3D = new Vector3D(e.accelerationX,e.accelerationY,e.accelerationZ);
// ベクトルを正規化
acc0.normalize();
acc1.normalize();
// 2つの3Dベクトルの角度差を計算する
var rot:Number = Vector3D.angleBetween(acc0,acc1) * 180 / Math.PI;
// 2つの3Dベクトルの外積を計算する
var cro:Vector3D = acc0.crossProduct(acc1);
// 回転軸と角度から行列を作成する
var mtx:Matrix3D = new Matrix3D();
mtx.prependRotation(rot, cro);
});
}
■デバイスを垂直に立てている場合
■傾けていないデフォルトの姿勢を確認する
液晶の下部が真下を向いている状態です。
このときの重力加速度は、x:0.0 y:1.0 z:0.0 となります。
■2次元情報として計算する
液晶を常に手前に表示しながら、Flash の画面を 360 回転させるという使い方を想定します。
これを利用して、3次元情報ではなく2次元情報として計算してみます。
単純に z 軸情報を無視して、x 軸と y 軸の2次元ベクトルとします。
Flash の座標系に落とし込むには、x 軸を反転させる必要があります。
この2次元ベクトルの方向成分を、Flash 画面の回転角度とします。
2次元ベクトルから得られた角度の符号を反転します。
デフォルトの状態で、(x:0,y:1) が得られる為、さらに 90 度減算します。
垂直に立てた状態からどれだけ回転したかを調べる
import flash.sensors.Accelerometer;
import flash.geom.Point;
import flash.text.TextField;
import flash.events.AccelerometerEvent;
// テキストフィールドを作成
var text_field:TextField = new TextField();
text_field.x = 10;
text_field.y = 10;
text_field.width = stage.stageWidth - 20;
text_field.height = 100;
text_field.border = true;
stage.addChild(text_field);
// 加速度センサー利用可能
if(Accelerometer.isSupported){
// アクセラレータオブジェクトを作成
var accelerometer:Accelerometer = new Accelerometer();
// 取得時間隔を変更
accelerometer.setRequestedUpdateInterval(10);
// 更新がある度に実行されるイベント
accelerometer.addEventListener(AccelerometerEvent.UPDATE, function (e:AccelerometerEvent):void{
// x 軸と y 軸を取得する
var vec:Point = new Point();
vec.x = -e.accelerationX;
vec.y = e.accelerationY;
// ベクトルから傾いている方向(角度)を取得する
var r:Number = Math.atan2(vec.y,vec.x) * 180 / Math.PI - 90;
// 角度をテキストフィールドに出力
text_field.text = "r:" + r;
});
}
■3次元情報として計算する
デバイスの傾きの角度を調べるには、2つの3次元ベクトルの角度差を計算します。
デフォルトの状態の加速度ベクトル (0,0,1)と、現在の姿勢の加速度ベクトルとの角度差を計算します。
デバイスをデフォルトの状態から傾けた角度を調べる
import flash.sensors.Accelerometer;
import flash.geom.Vector3D;
import flash.text.TextField;
import flash.events.AccelerometerEvent;
// テキストフィールドを作成
var text_field:TextField = new TextField();
text_field.x = 10;
text_field.y = 10;
text_field.width = stage.stageWidth - 20;
text_field.height = 100;
text_field.border = true;
stage.addChild(text_field);
// 加速度センサー利用可能
if(Accelerometer.isSupported){
// アクセラレータオブジェクトを作成
var accelerometer:Accelerometer = new Accelerometer();
// 取得時間隔を変更
accelerometer.setRequestedUpdateInterval(10);
// 更新がある度に実行されるイベント
accelerometer.addEventListener(AccelerometerEvent.UPDATE, function (e:AccelerometerEvent):void{
// 垂直に立てた状態の加速度
var acc0:Vector3D = new Vector3D(0,1,0);
// 現在の加速度
var acc1:Vector3D = new Vector3D(e.accelerationX,e.accelerationY,e.accelerationZ);
// ベクトルを正規化
acc0.normalize();
acc1.normalize();
// 2つの3Dベクトルの角度差を計算する
var dot:Number = ((acc0.x * acc1.x) + (acc0.y * acc1.y) + (acc0.z * acc1.z));
var rot:Number = Math.acos(dot) * 180.0 / Math.PI;
// 角度をテキストフィールドに出力
text_field.text = "r:" + rot;
});
}
得られる値は、0 ~ 180までの角度となります。
次に、回転軸を調べます。
デバイスの回転軸を調べる
import flash.sensors.Accelerometer;
import flash.geom.Vector3D;
import flash.text.TextField;
import flash.events.AccelerometerEvent;
// テキストフィールドを作成
var text_field:TextField = new TextField();
text_field.x = 10;
text_field.y = 10;
text_field.width = stage.stageWidth - 20;
text_field.height = 100;
text_field.border = true;
stage.addChild(text_field);
// 加速度センサー利用可能
if(Accelerometer.isSupported){
// アクセラレータオブジェクトを作成
var accelerometer:Accelerometer = new Accelerometer();
// 取得時間隔を変更
accelerometer.setRequestedUpdateInterval(10);
// 更新がある度に実行されるイベント
accelerometer.addEventListener(AccelerometerEvent.UPDATE, function (e:AccelerometerEvent):void{
// 垂直に立てた状態の加速度
var acc0:Vector3D = new Vector3D(0,1,0);
// 現在の加速度
var acc1:Vector3D = new Vector3D(e.accelerationX,e.accelerationY,e.accelerationZ);
// ベクトルを正規化
acc0.normalize();
acc1.normalize();
// 2つの3Dベクトルの角度差を計算する
var rot:Number = Vector3D.angleBetween(acc0,acc1) * 180 / Math.PI;
// 2つの3Dベクトルの外積を計算する
var cro:Vector3D = acc0.crossProduct(acc1);
// 角度と回転軸をテキストフィールドに出力
var str:String = "";
str += "r:" + rot + "\n";
str += "x:" + cro.x + "\n";
str += "y:" + cro.y + "\n";
str += "z:" + cro.z + "\n";
text_field.text = str;
});
}
デバイスの傾きを行列として計算する
import flash.sensors.Accelerometer;
import flash.geom.Vector3D;
import flash.geom.Matrix3D;
import flash.text.TextField;
import flash.events.AccelerometerEvent;
// 加速度センサー利用可能
if(Accelerometer.isSupported){
// アクセラレータオブジェクトを作成
var accelerometer:Accelerometer = new Accelerometer();
// 取得時間隔を変更
accelerometer.setRequestedUpdateInterval(10);
// 更新がある度に実行されるイベント
accelerometer.addEventListener(AccelerometerEvent.UPDATE, function (e:AccelerometerEvent):void{
// 垂直に立てた状態の加速度
var acc0:Vector3D = new Vector3D(0,1,0);
// 現在の加速度
var acc1:Vector3D = new Vector3D(e.accelerationX,e.accelerationY,e.accelerationZ);
// ベクトルを正規化
acc0.normalize();
acc1.normalize();
// 2つの3Dベクトルの角度差を計算する
var rot:Number = Vector3D.angleBetween(acc0,acc1) * 180 / Math.PI;
// 2つの3Dベクトルの外積を計算する
var cro:Vector3D = acc0.crossProduct(acc1);
// 回転軸と角度から行列を作成する
var mtx:Matrix3D = new Matrix3D();
mtx.prependRotation(rot, cro);
});
}