目次
Multitouch 関連情報
Multitouch 対応ハード
↓実際に開発に使用している、または所有しており自分で触ってみたもの。
PC | 同時認識 | sensor | touch補足 | 対応 API | display | CPU | GPU |
---|---|---|---|---|---|---|---|
HP TouchSmart IQ821jp | 2 点 | optical | NextWindow | Win7 Touch API | 25.5inch 1920×1200 | Core2 Duo P8600 2.4GHz | GeForce 9600M GS |
SHARP Meibus PC-NJ70A | ∞? | optical LCD | 開発× | SHARP 独自のみ | 4.0inch 854×480 (sub display) | Atom N270 | GMA950 |
iPhone 2G/3G/iPod touch | 5 点 | capacitive | iOS (iPhoneOS) | 3.5inch 480×320 | ARM11 412/533MHz | PowerVR MBX | |
iPhone 3GS/iPod touch | 5 点 | capacitive | iOS (iPhoneOS) | 3.5inch 480×320 | Cortex-A8 600MHz | PowerVR SGX 535 | |
iPad 3G/Wi-Fi | 11 点 | capacitive | iOS (iPhoneOS) | 9.7inch 1024×768 | Cortex-A8 1GHz | PowerVR SGX 535 | |
iPad2 3G/Wi-Fi | 11 点 | capacitive | iOS (iPhoneOS) | 9.7inch 1024×768 | Cortex-A9 1GHz x2 | PowerVR SGX 543MP | |
HTC Desire (X06HT) | 2 点 | capacitive | Android 2.x | 3.7inch 800×480 | Scorpion 1GHz | Adreno 200 (AMD Z430?) | |
iiyama ProLite T2250MTS | 2 点 | optical | Win7 Touch API | 21.5inch 1920×1080 | モニタのみ | ||
MouseComputer LuvPad AD100 | 2 点 | capacitive | Android 2.2 | 10.1inch 1024×600 | Cortex-A9 1GHz x2 | Tegra 250 | |
LG Optimus Pad L-06C | 10 点 | capacitive | Android 3.0 | 8.9inch 1280×768 | Cortex-A9 1GHz x2 | Tegra 250 |
- Mebius PC-NJ70A はタッチパッドに内蔵されたサブ画面のみマルチタッチ可能です。SDK が無いのでマルチタッチを活用したアプリケーションを作ることはできません。サンプリングも極めて低速でお勧めしません。
↓店頭で実際に触って確認したもの。ペイントがわかりやすい。
PC | 同時認識 | sensor | touch補足 | 対応 API | display | CPU | GPU |
---|---|---|---|---|---|---|---|
Fujitsu LOOX U G90 | 5 点 | resistive | Win7 Touch API | 5.6inch 1280×800 | Atom Z520 1.33GHz | GMA500 (PowerVR SGX 535) | |
ASUS EeePC T91MT | 2 点 | resistive | Win7 Touch API | 8.9inch 1024×600 | Atom Z520 1.33GHz | GMA500 (PowerVR SGX 535) | |
ASUS EeePC T101MT | 2 点 | resistive | Win7 Touch API | 10.1inch 1024×600 | Atom N450 1.66GHz | GMA3150 | |
Lenovo IdeaPad S10-3t | 2 点 | capacitive | Win7 Touch API | 10.1inch 1024×600 | Atom N450 1.66GHz | GMA3150 | |
ASUS EeeTop ET2010AGT | 2 点 | optical | Win7 Touch API | 20.0inch 1600×900 | AthronII X2 250u 1.6GHz | ATI Mobility Radeon HD 5470 | |
Gateway ZX6800-43 | 2 点 | optical | Win7 Touch API | 23.0inch 1920×1080 | Core2 Duo E7500 2.93GHz | GMA X4500HD | |
Fujitsu FMV F/G60 | 2 点 | optical | Win7 Touch API | 20.0inch 1600×900 | Core i3-330M 2.13GHz | GMA HD | |
HP TouchSmart PC600 1190jp | 2 点 | optical | Win7 Touch API | 23.0inch 1920×1080 | Core i7-720QM 1.6GHz | GeForce GT230 | |
SONY VAIO L VPCL139FJ/T | 2 点 | optical | NextWindow | Win7 Touch API | 24.0inch 1920×1080 | Core2 Duo E7600 3.06GHz | GeForce 310M |
IODATA LCD-AD221FB-T | 2 点 | optical | Win7 Touch API | 21.5inch 1920×1080 | モニタのみ | ||
Let's note C1 | 2 点 | electromagnetic digitizer + capacitive | 複合 Wacom | Win7 Touch API | 12.1inch 1280×800 | Core i5-502M 2.4GHz | GMA HD |
SHARP IS01/SH-10B/JN-DK01 | 2 点? | capacitive | 開発× | Android 1.6で独自 | 5.0inch 960×480 | Scorpion 1GHz | Adreno 200 (AMD Z430?) |
Toshiba Libretto W100 | 2点 x 2面 | capacitive | 2面とも | Win7 Touch API | 7.0inch 1024×600 x2 | Pentium U5400 1.2GHz | GMA HD |
↓情報提供していただいた物。
PC | 同時認識 | sensor | touch補足 | 対応 API | display | CPU | GPU |
---|---|---|---|---|---|---|---|
ONKYO TW317A5 | 2点 | capacitive | Win7 Touch API | 11.6inch 1366×768 | Aton N450 1.66GHz | GMA3150 | |
GREEN HOUSE GH-JTJ223GSHB | 2点 | optical | Win7 Touch API | 21.5inch 1920×1080 | モニタのみ |
↓その他マルチタッチ可能と判明しているものや発売予定のものなど。
PC | 同時認識数 | sensor | touch補足 | 対応 API | display | CPU | GPU |
---|---|---|---|---|---|---|---|
Lenovo ThinkPad X201 Tablet | ? | electromagnetic digitizer + capacitive? | 複合 Wacom | Win7 Touch API | 12.1inch 1280×800 | Core i7-640LM | GMA HD |
Viliv S10 | 3 点 | resistive | Win7 Touch API | 10.1inch 1366×768 | Atom Z550 2.0GHz | GMA500 (PowerVR SGX 535) | |
iPhone 4 / iPod touch 4G | 5? | capacitive | iOS | 3.5inch 960×640 | Cortex-A8 | PowerVR SGX 535 | |
Samsung Galaxy S GT-I9000 | ∞? | capacitive | Android 2.x | 4.0inch 800×480 | Cortex-A8 1GHz | PowerVR SGX 540 | |
Dell SX2210T | 2 点 | optical | NextWindow | Win7 Touch API | 21.5inch 1920×1080 | モニタのみ | |
HP 2310t | 2 点 | optical | Win7 Touch API | 23.0inch 1920×1080 | モニタのみ | ||
HP 2209t | 2 点 | optical | Win7 Touch API | 21.5inch 1920×1080 | モニタのみ | ||
HP mini 5102 10H/160/Pro | Win7 Touch API | 10.1inch 1366×768 | Atom N450 1.66GHz | GMA3150 | |||
MSI E22T31-ITWH | 2 点 | optical | Win7 Touch API | 21.tinch 1920×1080 | Celeron T3100 1.9GHz | NVIDIA ION | |
MSI Wind Top AE2420 3D | touch+3D | Win7 Touch API |
- 据え置き(一体型)でモニタサイズが大きく 20inch 以上のものは、ほとんど全部が赤外線の光学式で 2点タッチのもの。
- 安価なノート PC 向けは 抵抗膜式(resistive) が多いが、Lenovo IdeaPad S10-3t は静電容量式(capacitive)。
- マルチタッチとはいえ一般向けは 2点までのものが多く、3点以上取れるものはかなり少ない。
- EeePC 901-X のようにタッチパッドのみマルチタッチ対応のものも多い。(capacitive) これらのマルチタッチはドライバと専用ユーティリティのみで Windows 7 touch API には非対応。
API
- 基本的に 2点タッチ以上はマルチタッチ扱いです。
- multi touch の情報を受け取った場合処理の仕方は全体をひとつの sequence とみなすか、タッチ点毎に独立して判定するかの二通りあります。
- 一人が複数点タッチを同時に行なったとみなすか複数人が各々好き勝手にタッチしたかの違いで、扱い方はアプリの実装依存となります。
- 複数人が同時にマルチタッチした場合の判別は簡単にはできません。操作対象の場所や対象オブジェクトで区別することになるでしょう。
- どの OS も同時に最大何点識別できるかどうかを返すプロパティを発見出来ていません。
- Windows 7 は、タッチパネルがあるかどうか、シングルタッチのみなのか、マルチタッチデバイスを接続しているか、の区別はできます。
- ハードウエアの限界以上の点を同時にタッチした時の挙動は不定となっているようです。
- 例えば同時 2点タッチできるデバイスに 3箇所触ったとき。
Windows 7
概要
複数のセンサーからの入力を受け取れる。
WM_TOUCH と WM_GESTURE の 2種類あり
- WM_TOUCH : 低レベル API、直接複数ポイントの座標を参照できる。ID 分離は行われている。1 point 目の touch はマウスと同じ扱いになる。
- WM_GESTURE : フリックやズームなどのよく使う動作を簡単にイベントとして受け取ることができる。WM_TOUCH の上位機能。
WM_GESTURE
WM_GESTURE の方が一見簡単に使えそうですが、判定はモーション完了後に行われるためワンテンポ遅れてあまり直感的ではありません。 最初にタッチしたオブジェクトで判定を切り替えたい場合も多く、意外にできないことも多くあります。 タッチを使った直接操作というより、ジェスチャーを使ったショートカットに近い。 実際に使うなら WM_TOUCH の方が良いと思います。
WM_TOUCH
WM_TOUCH は WM_GESTURE より低レベルとはいえ、タッチ点がシステムで分離されているので扱いは容易です。 ID 分けされた各タッチ点毎に TOUCHEVENTF_MOVE/DOWN/UP で区別可能です。 識別 ID TOUCHINPUT::dwID は必ずしも 0 から始まるわけではないので要注意。
座標は整数値ですがサブピクセル情報を含んでおり TOUCH_COORD_TO_PIXEL() マクロで変換します。( 1/100 倍)
最初のタッチ点は特別に TOUCHEVENTF_PRIMARY としてマークされています。Primary はマウス扱いになります。 Primary 点を離した後は、いったんすべての接地点が無くなるまで Primary 扱いにはなりません。 例えば下記の 4 は Primary にならないので、他の点をタッチしたまま Primary だけダブルタップする場合注意が必要です。 このフラグはあてにしない方が良いかもしれません。
- pointA DOWN (Primary)
- pointB DOWN
- pointA UP (Primary)
- すぐ同じ場所に pointA DOWN
連続する MOVE message は多くの TOUCHEVENTF_NOCOALESCE で送られてきますが、このフラグが無いメッセージのみサンプルすることで、 ある程度取りまとめて判定することが可能です。 RegisterTouchWindow() 時に TWF_FINETOUCH を指定するとすべて NOCOALESCE になります。
cxContact/cyContact は設置面積 (pixel 数) を表します。dwMask に TOUCHINPUTMASKF_CONTACTAREA がある場合のみ有効です。 光学式でも値が取れることを確認。
デフォルトは WM_GESTURE なので、あらかじめ RegisterTouchWindow( hWnd, 0 ) を実行しておく必要があります。
Mouse 操作とマルチタッチの併用時の問題
TOUCHEVENTF_PRIMARY のタッチは WM_LBUTTONDOWN/WM_LBUTTONUP/WM_MOUSEMOVE 等のマウスイベントも発生させます。 アプリケーションをマウスとマルチタッチの両操作対応にすると、マルチタッチ中なのに同時にマウス側の処理も多重に行われる可能性があります。 MSDN Troubleshooting Applications によると下記の方法で判別できるそうです。
#define MOUSEEVENTF_FROMTOUCH 0xFF515700 if( (GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH ){ // Click was generated by wisptis / Windows Touch }else{ // Click was generated by the mouse. }
WM_TOUCH で Primary の TOUCHEVENTF_DOWN が来ない問題
Windows 7 のデフォルト設定では、最初のタッチ時に即座に TOUCHEVENTF_DOWN が発生しません。 下記の何らかの動作を行って初めて DOWN と UP (または MOVE) が同時に発生します。
- 指を離したとき
- 位置をずらしたとき
- そのまま押し続けて円の描画が終わってから
Windows 7 で プレス アンド ホールド (長押し) 操作が有効になっていることが原因です。 タッチしたタイミングが分からずディレイが発生するのでゲームなどに向きません。 下記の設定で直るようです。
- コントロールパネルから「ペンとタッチ」を開く
- 「タッチ」のタブを開く
- “プレスアンドホールド” を選択してその下の [設定] を押す。
- 「プレス アンド ホールド を右クリックとして認識する」のチェックを外す
- [OK] → [OK]
これで最初のタッチですぐに TOUCHEVENTF_DOWN が発生するようになります。 ただし通常のウィンドウ操作でも長押し(プレス アンド ホールド)で右ボタンメニューが出なくなるので注が必要です。
参考ページ
Android 2.0 以降 (API Level 5 以上)
概要
Android OS 2.0 (API Level 5) で導入されています。
タッチ点の ID 分離をシステムが行ってくれるため扱いは容易です。 ただし pointer Index 値は 0 からの連番となり絶対 ID ではないので要注意。 2 点タッチ中に Primary が ACTION_UP すると Secondary が index 0 に繰り上げられます。
index の代わりに固有 ID (pointerId) を使った識別ができます。この場合 index と違い繰上問題が起こりません。詳細は後述。
タッチ操作の精度を上げるには大量のサンプリング点が必要ですが、 イベントの発生頻度を抑える工夫が行われているようです。 Windows7 でいえばおそらく TOUCHEVENTF_NOCOALESCE がついていない (COALESCE された) メッセージに相当し、その間のポイントは History として参照できます。
ACTION_DOWN, ACTION_UP でも同時にタッチされている点がすべて報告されるので、実際に変化のあったタッチ点を得るには下記の演算で求まる index 値が必要です。
(event.getAction() & event.ACTION_POINTER_ID_MASK) >> event.ACTION_POINTER_ID_SHIFT
API Level 8 (Android OS 2.2 Froyo) からは上の計算の代わりに event.getActionIndex() が使えるようになります。
座標値は Windows7 と違い浮動小数 float が用いられています。
情報アクセスに用いる 3つの番号
pointerIndex
マルチタッチ時に、タッチされている点への情報アクセスに使う index。0 ~ event.getPointerCount()-1。 event.getPointerCount() は同時にタッチされている点の数。
なお ACTION_UP 時は UP された座標の通知のために 2点送られて来るが、厳密にはこのタイミングでは触っているのは 1点になっている。
pos
History Table の index 番号。 0 ~ event.getHistorySize()-1 。 ACTION_MOVE 時に軌跡を補間する。 マルチタッチの場合は、各点毎に HistorySize 分の値が入っている。
ACTION_MOVE 以外では使わない。このとき event.getHistorySize() は常に 0 となる。
pointerId
タッチ点を識別する固有 ID 値。 pointerIndex と違って繰上が行われず、固有値として用いることができる。 pointerIndex と相互変換して使う。
pointerIndex → pointerId 変換 | pointerId= event.getPointerId( pointerIndex ) |
pointerId → pointerIndex 変換 | pointerIndex= event.findPointerIndex( pointerId ) |
実デバイスの値
HTC Desire のパネルは 10msec サンプリング。 およそ 100Hz。 Move Event は約 30msec 毎に取りまとめられている。 移動値が少ないと頻度が下がるので、時間ではなく移動量かもしれません。
参考ページ
iOS (iPhoneOS)
概要
タッチポイント分、複数の UITouch がそのまま通知されます。 マルチタッチ時の通知は変化があったポイント座標のみで必要最小限です。 Android のように同時にタッチされている点が全部通知されることがありません。
個々のタッチ点の固有の追跡は行われていないようで、タッチ点を分離しての ID の割り振り処理はアプリケーションに委ねられています。 その分シンプルで非常にわかりやすい構造となっています。
iOS 3.2 からは上位 API として UIGesureRecognizer が追加されたそうです。 ( [iPhone] iPhone OS 3.2(iPad用OS)の特徴)
android 同様浮動小数値が用いられています。 タッチ点の ID 分離はない代わりに、タップ回数の判定はシステムで行ってくれます。 このあたり他の OS と違って特徴的です。
他の OS との比較
- Windows 7
- システムでタッチ点の ID 分離が行われている。
- 分離した各点がそれぞれ独立して UP/DOWN/MOVE の状態が送られてくる。ただし互換性のために Mouse 相当となる Primary 点のみシーケンス判定あり。
- 一度のイベントで、タッチされているすべての点の情報が更新される。同時に 2点触っているなら必ず 2点分の情報がくる。
- Move Event の融合を行うかどうかは選択できる。
- マウス操作や Tablet PC など古い single touch 時代のアプリと互換性を保つ必要があるため、タッチ操作がマウスとしても通知されるなど少々複雑。
- Android
- 一度のイベント通知に必要な情報がほとんど全部含まれている。例えば現在タッチされている 2点間の距離などは、保持データが無くても一度のイベント情報だけで求めることができる。
- システムでタッチ点を分離して ID 割付が行われている。
- Move Event は融合されており、その間の詳細な座標の遷移は History 情報に含まれる。より細かい精度での Event 通知が可能かどうかは不明。
- 後発ながらもともと single touch だった API を拡張しているため少々わかりにくい部分もある。multi touch できない端末も多く、対応していても3点以上判別可能とは限らない。互換性を考えて使い分ける必要がある。
- マルチタップは自分で判断する必要あり。イベント発生時のタイムスタンプが含まれているのでそれを元にする。
- iOS (iPhoneOS)
- 必要最小限の情報(差分)だけが送られてくる。例えば同時に 2点触っていても、移動したのが片方だけなら情報は 1点分だけ送られてくる。よってタッチ判定点が増えても無駄が無い。
- その代わり以前送られてきた点の情報を自分で保持しておく必要がある。
- 送られてきた座標が前回のどのタッチ点に相当するのか、ID の割り当てを自分で行う必要がある。
- 最初から multi touch であり、ハードウエアも統一されているので制限なく使える。同時タッチ点が最低でも 5点あるので安心。
- 唯一マルチタップ判定がある。
参考ページ
比較表
Event | Windows 7 | Android | iOS (iPhoneOS) |
---|---|---|---|
DOWN | TOUCHEVENTF_DOWN | ACTION_DOWN | touchesBegan |
UP | TOUCHEVENTF_UP | ACTION_UP | touchesEnded |
MOVE | TOUCHEVENTF_MOVE | ACTION_MOVE | touchesMoved |
CANCEL | ACTION_CANCEL | touchesCancelled |
OS | 固有 ID 割り振り | UP/DOWN イベント | マルチタップカウント | TimeStamp | 面積 | 頻度 | イベントに含まれる情報 | 補足 |
---|---|---|---|---|---|---|---|---|
Windows 7 WM_TOUCH API | あり dwID | 分離したタッチ点毎に UP/DOWN 状態が含まれる | なし | あり | あり | 選択可能 | 全部の点それぞれの詳細 | Single ならマウスとして扱える |
Android OS 2.x | あり pointerId | 個別に発生するが他の点座標も含まれる | なし | あり | あり | 低+History | 全部の点 | |
iOS (iPhoneOS) | なし(座標値から判定) | 発生した点の座標のみ単独 | あり | なし | ? | 高 | 変化した点だけ |
各 OS ごとのイベント通知の違い
Windows 7
PRIMARY WM_TOUCH: id3 (x,y) DOWN WM_TOUCH: id3 (x,y) MOVE WM_TOUCH: id3 (x,y) MOVE id4 (x,y) DOWN WM_TOUCH: id3 (x,y) MOVE id4 (x,y) MOVE WM_TOUCH: id3 (x,y) MOVE id4 (x,y) MOVE id5 (x,y) DOWN WM_TOUCH: id3 (x,y) UP id4 (x,y) MOVE id5 (x,y) MOVE WM_TOUCH: id4 (x,y) MOVE id5 (x,y) MOVE WM_TOUCH: id4 (x,y) MOVE id5 (x,y) UP WM_TOUCH: id4 (x,y) UP
- なぜか dwID が 3から始まる。
- 複数の UP/DOWN を同時に受け取れる構造だが、イベントは同時に発生しない。必ず個別に発生する。(ドライバの仕様かもしれない)
Android 2.x 以降
pointerIndex/pointerId (x,y) ACTION_DOWN: 0/id0 (x,y) ACTION_MOVE: 0/id0 (x,y) ACTION_MOVE: 0/id0 (x,y) ACTION_DOWN: 0/id0 (x,y) 1/id1 (x,y) actionPointerId=1 ACTION_MOVE: 0/id0 (x,y) 1/id1 (x,y) ACTION_DOWN: 0/id0 (x,y) 1/id1 (x,y) 2/id2 (x,y) actionPointerId=2 ACTION_MOVE: 0/id0 (x,y) 1/id1 (x,y) 2/id2 (x,y) ACTION_UP: 0/id0 (x,y) 1/id1 (x,y) 2/id2 (x,y) actionPointerId=0 ACTION_MOVE: 0/id1 (x,y) 1/id2 (x,y) ACTION_MOVE: 0/id1 (x,y) 1/id2 (x,y) ACTION_UP: 0/id1 (x,y) 1/id2 (x,y) actionPointerId=1 ACTION_UP: 0/id1 (x,y) actionPointerId=0
- DOWN/UP 発生時、実際に変化したタッチ場所を得るには actionPointerId 番目の情報を参照する。
- イベントの構造上、複数の点の UP/DOWN を同時に受け取ることが出来ない。
iOS (iPhoneOS)
touchesBegan: (x,y) touchesMoved: (x,y) touchesMoved: (x,y) touchesBegan: (x,y) touchesMoved: (x,y) touchesMoved: (x,y) (x,y) touchesBegan: (x,y) touchesMoved: (x,y) (x,y) (x,y) touchesMoved: (x,y) (x,y) (x,y) touchesEnded: (x,y) touchesMoved: (x,y) (x,y) touchesMoved: (x,y) touchesEnded: (x,y) (x,y)
- 複数の点を同時にタッチ&離したときは、1つの Began/Ended イベントで複数点の情報が送られてくる。
Multi touch 方式
方式 | スタイラス | 指 | 爪 | 精度 | 圧力 |
---|---|---|---|---|---|
抵抗膜式 (resistive) | ◎ | △ | ◎ | ◎ | 必要 |
静電容量式 (capacitive) | × | ◎ | × | × | 不要、触れただけで反応 |
光学式 (optical) | ◎ | ◎ | ◎ | △ | 不要、触れただけで反応 |
- 抵抗膜式 (resistive)
- 軽く触れただけでは反応せずさらに押し込む必要がある。物理的なスイッチに近い。指が触れただけで反応しないため、尖ったペンや爪での操作に向いている。精度は高いが画面の上にセンサーのレイヤがあるため見栄えに影響があり。表面の強度も劣る。
- 静電容量式 (capacitive)
- 指で触れるだけで反応するが、座標の精度が低くペンに反応しない。ノートPC のタッチパッドなど、指での操作に向いており広く使われている。接地面積である程度の押し付け状態を取ることができる。
- 光学式 (optical)
- 大きなモニタに対応可能。横方向への光学遮断で判定する。そのため光さえ遮れば、ペン、手、その他何でも軽く触れるだけで反応する。衣服やゴミ、虫等も認識する。垂直方向の圧力(筆圧)を取ることが出来ないが、その代わりおおまかな接地面積を取れる。
- 電磁誘導 active デジタイザ (electromagnetic digitizer)
- 専用のペンを用いる方法で精度が高い。専用のペン以外は認識しないので手をついても大丈夫。指操作できるがペン認識しない静電誘導方式とはちょうど欠点を補間しあう関係となるため、マルチタッチ UI 向けは両者を組み合わせて使うことが多い。
- マルチタッチでタッチ点の移動を厳密に追跡することは意外に難しい。高速なサンプリングが必要。
- 指タッチは点ではなく面積なので、マルチタッチの位置が近いと融合してしまうことがある。光学式は近い点を1つとみなしてしまう。分離精度があまり高くない。静電容量式も制度が悪いものは、X-Y それぞれで近い点を融合してしまう。
- http://www.nextwindow.com/optical/index-jp.html NextWindow optical imaging