ユーザ用ツール

サイト用ツール


multitouch:start

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 だけダブルタップする場合注意が必要です。 このフラグはあてにしない方が良いかもしれません。

  1. pointA DOWN (Primary)
  2. pointB DOWN
  3. pointA UP (Primary)
  4. すぐ同じ場所に 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 で プレス アンド ホールド (長押し) 操作が有効になっていることが原因です。 タッチしたタイミングが分からずディレイが発生するのでゲームなどに向きません。 下記の設定で直るようです。

  1. コントロールパネルから「ペンとタッチ」を開く
  2. 「タッチ」のタブを開く
  3. “プレスアンドホールド” を選択してその下の [設定] を押す。
  4. 「プレス アンド ホールド を右クリックとして認識する」のチェックを外す
  5. [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 それぞれで近い点を融合してしまう。
multitouch/start.txt · 最終更新: 2011/07/11 22:04 by oga