Manipulateチュートリアル

Manipulateはこのコマンドだけで,たった数行の入力を使って驚くほどの範囲に渡るインタラクティブなアプリケーションを作成することができる.ManipulateTablePlot等の基本的なコマンドが気楽に使える人が使用することを意図したものである.複雑な新しい概念やユーザインターフェースのプログラミングを知っておく必要はない.
Manipulateコマンドを評価して得られる出力は,1つあるいは複数のパラメータの値を変更するために使用する1つあるいは複数のコントロール(スライダー等)を含むインタラクティブなオブジェクトである.この出力は,単なる静的な結果ではなく,インタラクトすることのできる実行中のプログラムであるという点において,小さいアプレットまたはウィジェットによく似ている.
このチュートリアルは,関数の使い方,さまざまな種類のカッコ,簡単なプロットの作成方法を含むWolfram言語の基礎的な使用方法を知っている人のためのものである.例題の中には高度な関数を使ったものもあるが,その例題の趣旨を得るためにその関数がどのように動作するのかを正確に理解する必要はない.
このチュートリアルは長いが,それでもすべてを説明しきれてはいない.この豊かなコマンドのより高度な機能については「Manipulateの高度な機能」でさらに詳しく説明する.
Tableのように簡単なManipulate
最も基本的な部分で,Manipulateのシンタックスは下位関数のTableのシンタックスと同一である.以下のTableコマンドは,1から20までの数のリストを生成する.
TableManipulateに置き換えるだけで,n の値をスライダーで変更することのできるインタラクティブなアプリケーションになる.
このドキュメントをWolframシステムで開いている場合には,スライダーをクリック・ドラッグすると,表示された値がリアルタイムで変更される(スライダーを解放したときだけでなく,スライダーをドラッグしている間にも変更される)ことが分かる.静的形式で開いていると,スライダーが任意の位置まで動かされるのが見える(デフォルトでは,スライダーは左側から開始するが,以下の例題では多くの場合,スライダーは最初の位置から動かされている).
TableManipulateはどちらも以下の形式{variable,min,max}を使い,「反復子」を指定して変数の名前およびその変数が変更される範囲を与える.
もちろんManipulateの肝心な点(この点ではTableも同様)は,第1引数に単純な変数名だけでなく,どのような式を入れてもよいということである.この非常に簡単な出力でスライダーを動かすことで,すでにManipulateのパワーを垣間見ることができる.
このドキュメントを静的形式でお読みの場合は,スライダーを動かしたらグラフがリアルタイムで変化するということを信じていただきたい.
スライダーには,その隣に別のアイコンがあり,それをクリックすると小さいコントロールパネルが開く.これは上の例のパネルを開いたところである.
パネルにより変数の数値を見ることができる上,アニメーションコントロールを使って変数を変化させ続けることもできる.
サブパネルを開かずに変数の値が見たい場合は,変数の指定にオプションAppearance->"Labeled"を加えるとよい.プラス記号の右側に表示される数値はスライダーが動くと同時にリアルタイムで更新される.
これは,Manipulateが出力および柔軟性,また変数のリストで指定できるものの範囲において,比較的簡単なTableを超えるという最初の証拠でもある.
ManipulateTable同様,2つ以上の変数の範囲指定ができる.
Manipulateでは,いくつの変数でも,たとえ類似のTableコマンドなら不適切に大きな数の項目を列挙しようとするぐらい多くの変数であっても使うことができる.
数値を見るためにはサブパネルの一部あるいは全部を開けばよいし,多数の異なる変数を同時に動かすこともできる.
Manipulateは,広大なパラメータ空間をインタラクティブに探究する方法と考えることができる.その空間を自由に動き回り,現れた面白い方向を探究することができる.後半のセクションで説明するように,Manipulateにはそのような探究をより簡単に,より有益にすることのできるよう設計された機能が多数ある.
記号的出力と刻み幅
上記の例題はグラフィックスであり,インタラクティブなグラフィックスはまさにManipulateの最も一般的なアプリケーションである.しかし,Manipulateは,Wolfram言語のグラフィックス関数だけでなく,どの関数をインタラクティブにすることもできる.
グラフィックスではなく記号的な出力を含む例題でまず問題となるのは,連続的に変換する実数ではなく整数を扱いたいことが多いということである.Tableのデフォルトの刻み幅は1なので,当然整数が得られるが,Manipulateのデフォルトは連続変化を許可する(これは刻み幅ゼロと見ることができる).次の2つの例を比較すると,ManipulateTableによって返される値の間の値を許可していることが分かる.
例えば,代数的操作を含む関数は,非整数のパラメータ値が与えられると何も面白い変化を見せないことが多い.以下のExpand関数は何も拡張しない.
ここでManipulateコマンドに簡単に明示的な刻み幅1を加えるいうことは簡単にできることであり,Tableによって返されるのと全く同じ値の集合がManipulateで生成される.
明示的な刻み幅を加えることで,Expandの例題もずっと面白くなる.
一度に表示される値が1つだけということで,Tableコマンドで実践できることをはるかに超える例題を生成することができる.Manipulate出力の重要な特性には,パネルの大きさが固定されておらず,出力パネルをどのくらい大きくできるかの制限もないということがある.
(このドキュメントを印刷すると,用紙を節約するためにスライダーがかなり低く設定される.しかしスライダーを右側まで動かすと,出力は垂直のスペースに相当するだけのページ数を含むようスムーズに大きくなる.)
Tableの場合と同じように,最小値およびステップに有理数を使うと,変数には近似実数ではなく完全有理数が得られる.以下の例題では,フォーマット関数Rowを使い,分数を加える簡単な例を作成する.
通常の数ではなく記号的式の終点や刻み幅を使うこともできる.
コントロールの種類
Manipulateは,変数に対して異なる種類のコントロールを生成する変数指定の多様な方法をサポートする.これにはスライダーの他,チェックボックス,ポップアップメニュー等がある.
この原理は,各変数について可能な値の特殊な集合を求めると,Manipulateが自動的に適切な種類のコントロールを選択してこれらの値が便利に利用できるようにするというものである.これまで見たきたように,Tableのような一般的な数値的反復子では,スライダーが最も便利なインターフェースである.
一方,範囲ではなく可能な値(数値あるいは記号)の離散リストが指定したい場合もある.その場合は形式{variable,{val1,val2,}}の反復子で行う.
(範囲指定と比較すると,リストのレベルが追加されていることに注目.)少ない数の別々の値を求める場合は,1行のボタンが得られる.
多数の離散値の場合,Manipulateはポップアップメニューを使うよう切り替える.
指定の値TrueFalseの場合は,チェックボックスになる.
この選択はもちろん,幾分任意のものではあるが,便利であるよう意図されている.変数指定にControlTypeオプションを入れることで,コントロールの自動選択をオーバーライドすることができる(可能なコントロールのタイプはすべてManipulateのドキュメントに挙げてある).
例えば,自動選択でポップアップメニューが選ばれるような場合でも,オプションControlType->SetterBarを使うと1列のボタンに変更することができる.
スライダーは数値の範囲だけではなく,離散的な記号値を読み取ることができる.これによりそれらをアニメーション化することができる.オプションControlType->ManipulatorManipulateによって使われるデフォルトのコントロールを要求する.デフォルトコントロールとは,スライダーにオプショナルの数値付きのコントロールパネルあるいはアニメーションコントロール(上記参照)の付いたものである.ControlType->Sliderはスライダーだけを要求する.
同じ変数の値を調整するために,2つの異なるコントロールを使用することも可能である.次の例では,ポップアップメニューとスライダーの両方がfilling変数の値に接続されている.スライダーがポップアップメニューに現れない値を選択するために使われる場合,ポップアップは空白になるが機能はする.値をポップアップメニューから選ぶときは,スライダーは該当する位置に移動する.このように,同じ値を調整するために両方のコントロールを互換的に使うことができ,一方が使われているときは他方がそれに従うのである.
これがManipulateで使用できるコントロールの種類すべてではない.詳細はManipulateを参照されたい.最も重要なコントロールのひとつであるLocatorでは,Manipulateのグラフィックス出力の内部にコントロール点を置くことができる.これについては「ロケータ」で,Slider2Dについては「2Dスライダー」で説明する.
初期値とラベル
以下はリサージュ図形を作る面白い例題である.
初めは何も見えない.変数 a 1a 2(振幅)を初期値のゼロから移動させないと,見えるようにならないのである.初期値をデフォルトの左端とは別にしておいた方が便利かもしれない.これには形式{{var,init},min,max}の変数指定を使うとよい.
下では上と同じ例を使って,両方の初期振幅を1に設定し,デフォルトの周波数値をよい感じの初期図形を与えるよう設定してある.
ひとつの図形が別の図形に変化するのを見るのは楽しい.これに関連して,Wolfram言語のスライダーの珍しい機能を知るのもよい.Optionキー(Macintosh)あるいはAltキー(Windows)を押すと,スライダーの動きがマウスの動きに対して20分の1の速さになる.つまり,マウスを左右にドラッグすると,つまみは通常の20分の1の速さでしか動かなくなるのである.スライダーの領域から出ても,マウスがクリックされている限り,値はその方向へとゆっくり移動する.
Option/Altキーに加え,ShiftキーかCtrlキー,あるいはその両方を押すと,動きがさらにその20分の1の速さになる(それぞれについて20分の1の速さ).3つのキーすべてを押すと,つまみを最速時の100万分の1の速さで動かすことも可能である.この機能は,非常に小さい範囲のパラメータ空間に美しいパターンが隠されているこのような例に役に立つ.
(この例では,スライダーが動かされているときでもParametricPlotで滑らかな曲線が描画できるようにするため,オプションPerformanceGoal->"Quality"が使ってある.このオプションの必要性についての詳細は,「Manipulateの高度な機能」で説明する.)
Manipulateではデフォルトで,コントロールにラベル付けをするのに変数の名前を使う.これより長く記述的なラベルを使いたい場合は,形式{{var,init,label},min,max}の変数指定を使うとよい.
以下は,上と同じ例題に好みのラベルをつけたものである.
コントロールエリアの調整
Manipulateは,コントロールエリアの再配列,注釈,整備を可能にする多数の機能をサポートしており,特定の例題のニーズに合うようにしている.しかし,上級ユーザにはManipulateがWolfram言語でインタラクティブなインターフェースを作成できる唯一の方法ではないことを覚えておいて欲しい.また,Manipulateでは思い通りのことができない場合,DynamicDynamicModule等の関数を直接使い,Manipulateの特別な慣例に結びついていない自由形式のオープンエンドユーザインターフェースを作成することができる.これらの機能については,「Dynamicチュートリアル」「Dynamicの高度な機能」で説明する.
少数のコントロールがある場合,一般にそれをManipulateパネルの内容エリアの上部に置くのが最も便利である.しかし,通常スクリーンは縦よりも横の方が長いので,コントロールの数が多いときにはControlPlacementオプションを使い左側に置いた方がよいかもしれない.
ControlPlacementManipulateのレベル全体で使うと,すべてのコントロールのデフォルトの位置を設定する.しかし,このオプションは個々の変数指定の中で使うこともできるため,出力の複数の側にコントロールを配置することができる.
以下の例題では,コントロールは通常3個組みの2つのグループか2個組みの3つのグループになる.変数指定の文字列にキーワードDelimiterを挿入して,分割線を置く場所を指定できる.ここではラベルのない2つの分割線を使い,コントロールを3つのグループに分ける.
あるいは文字列(または文字列とデリミタ)を使い,コントロールのグループにラベルを付けることもできる.
コントロールにはスタイル付きのテキスト,任意の式,またメインの出力ウィンドウとは独立して更新される動的オブジェクトさえも含む非常に多様なものを組み込むことができる.以下ではStyleを使ってグループヘッディングをより目立たせる簡単な例を示す.
より複雑な配列および動的ラベルの例は「Manipulateの高度な機能」を参照のこと.
2Dスライダー
Wolfram言語の優れた機能に,2つの値を同時に制御するために両方向のマウスの動きを可能にする2Dスライダーのサポートがある(通常の1Dスライダーはマウスで提供できる2度の自由度のうちのひとつをある意味で無駄にしている).
2Dスライダーを得るためには,{var,{xmin,ymin},{xmax,ymax}}のように minmax の両方に対して数値のペアを使う.
変数の値は{x,y}のペアでもある.以下は,どのようにコントロールが動作するかを見るための変数の値を考察するためだけの例である.
以下の例は,2Dスライダーの値がどのように座標の点に対応するかをよりグラフィカルに示したものである.
もっと面白いことをすると,前のセクションのリサージュ図形を6つの1Dスライダーの代りに3つの2Dスライダーで再生成することができる.ここでも同じ6つのパラメータを制御しているわけであるが,一度に2つを動かすことができるのである.
簡潔で楽しい例題ができた.「初期値とラベル」で説明したスライダーの動きを遅くするOptionShiftCtrlキーを使った微調整は,1Dのスライダーだけでなく2Dスライダーにも使える.
プロットを超えるグラフィックス
ここまで,主に高レベルのプロット関数を使ってきたが,Manipulate内部でWolfram言語の低レベルグラフィックス言語を使うのも面白い.前のセクションからの以下の例は低レベルグラフィックス言語を使った簡単な例である.
この例題は,Manipulate内部でGraphicsを使うときは常に明示的にPlotRangeオプションを指定した方がよいということも示唆している.PlotRange->1は原点からのすべての方向において1であることを意味し,PlotRange->{{-1,1},{-1,1}}に等しい.PlotRangeオプションを省略すると,Wolfram言語の自動プロット範囲決定機能により全く動かない点を表示する.これはプロット範囲は常にそれを中心とするからである.
簡単な(または複雑な)Wolfram言語のプログラミングで出力に任意のグラフィカル要素を加えることができる.例えば,ここでは点の代りに中心への線にしてみる.2つ目の線形スライダーで線の数を指定する.
次も線の表の作成に基づく面白い線の図形の例である.
Wolfram言語は高度なプログラミング言語なので,Manipulateを使ってパラメータ化されたプログラムやアルゴリズムをインタラクティブに探究することができる.Wolfram言語のグラフィックス言語は「グラフィックスオブジェクトの構造」で説明してあり,このような例題はWolframデモンストレーションプロジェクトに多数記載してある.
Locator
インタラクティブなグラフィックス例題を生成する場合,Manipulateの最も重要な機能のひとつは,出力エリアに現れるグラフィックスの内部にLocatorと呼ばれるコントロール点を置くことができるということである.
線が中心点に集まる上の例を考えてみよう.2Dスライダーを使って中心の点を制御するのもよいが,中心点をクリックアンドドラッグすることができた方がよいかもしれない.これは pt 変数に対するコントロール指定にLocatorを加えることで実現できる.この場合,min および max の範囲はグラフィックスから自動的に選ばれるので,指定する必要はない.しかし,初期値は指定する必要がある.
これでグラフィックスの任意の点をクリックすると,マウスボタンを押している間,線の集まる点はマウスに従う.中心を正確にクリックする必要はない.グラフィックスのどこをクリックしても中心点はそこにジャンプする.
Locatorを別々にリストすることで複数のコントロールを含むことができる.また,内容エリアの外側にコントロールのないManipulateであっても全く問題がなく,以下のように純粋にグラフィカルな例題が作成できる.
複数のLocatorがある場合でもグラフィックスのどこをクリックしても,最も近くにあるLocatorがクリックしたところにジャンプし,マウスを追跡し始める.
それぞれが1つの{x,y}点に対応する複数の別々の変数を使う代りに,値が点のリストである変数を1つだけ使うこともできる.
この場合も特定のLocator上以外のグラフィックの部分をクリックすると,最も近くにあるものがマウスの位置にジャンプしそれを追跡し始める.
内部的な制約のため,単独のLocator変数と複数のLocator変数のリストである変数を組み合せることはできない.1つのManipulateの中には1つの複数のLocator変数しか含むことができない.しかし,その代りその1つのマルチLocatorの変数にオプションLocatorAutoCreate->Trueを加え,インタラクティブにLocator点を生成したり破壊したりする(変数に保存された点のリストの長さを変更する)ことができる.
下の例では,Cmdキー(Macintosh)あるいはAltキー(Windows)を押したまま既存のLocatorにはない部分をクリックすると,その場所に新規のLocatorを生成することができる.既存のLocator上でCmd/Altをクリックすると,それは破壊される.Locatorを加えたり削除したりするときは,pts 変数に保管される点のリストの長さを変更することになるので,表示された多角形の頂点の数を変更することになる.
もちろんLocatorコントロールと通常のManipulate変数を組み合せることもできる.例えば,下は多角形の外観を制御するスライダーと色指定である.
上の例は簡単すぎると思われるかもしれないが,これはあくまでもシステムの一般性を示すことを意図したものである.これは内部で何でもできるようなフレームワークを提供する.下の例は,ほんの数行のコードで,インタラクティブな多項式曲線のフィット環境という,非常に驚くようなことができることを示したものである.
ロケータのつまみは,最小2乗により「order」スライダーにより決定される次数を持つ多項式にフィットされているデータ点を表す.内部的には5つの点が提供されるが,グラフィックスの空白部分をCmd/Alt クリックすると新規の点を加えることができ,既存の点をCmd/Altクリックするとその点を削除することができる.
このような高度な例がこれだけのコードで構築できるということは,驚くべきことである.コンパクトなWolfram言語コードで誰かを本当に驚かせたいならば,以下の例がよい.これでは一般性はやや欠けるが2行だけで実行できる.少し練習すると,この形式を最初から30秒以内で入力できるようになる.
3Dグラフィックス
Manipulateは,パフォーマンス問題があるとはいえ,2Dのときと同じくらい簡単に3Dを探究するために使うことができる.次の簡単な例を考えてみる.
n の値が大きいと関数は急速に振動する.滑らかな画像を生成するために,Plot3Dのデフォルトの適応型サンプリングアルゴリズムが長い計算時間と描画時間をかけてかなり多量の多角形を生成する.
幸いPlot3Dおよびその他の組込みのプロット関数は,Manipulateの内部で使われると,コントロールがドラッグされている間に描画の質を犠牲にしてもスピード向上させるため,自動的に内部アルゴリズムと設定を調整する.マウスのボタンが解放されると,プロットの高画質のものが非同期に生成される(プロットが生成されている間でもフロントエンドの操作は継続できる).非同期の評価については「Dynamicの高度な機能」「同期の動的評価と非同期の動的評価」に説明してある.
その結果は,スライダーをドラッグしている間は早いがやや粗いプロットがリアルタイムで描画され,コントロールを解放すると,スムーズな描画がやや遅れて表示される.これが起るのは,Plot3Dおよび他のほとんどのプロット関数が描画の質とスピードを制御するさまざまなオプションのデフォルト設定で,関数ControlActiveを参照しているためである.Manipulate内でControlActiveを使うことについては,「Manipulateの高度な機能」遅い評価の対処を参照のこと.
2Dのときと同様に,高レベルのプロットコマンドと同じくらい簡単に低レベルのグラフィックス言語を使うことができる.以下の例では,互いに交わり境界ボックスとも交わる球をWolfram言語がどのように操作するかを見ることができる.
以下では,ネストされた3D構造の中を見るためにどのように透明度(透過性)が使えるかを示している.
3Dグラフィックスに透過性を加えると,描画が顕著に遅くなる.
Manipulate出力の中の3Dグラフィックスは,通常通りのクリックとドラッグで回転させることができる.ほとんどの場合,Manipulateのコントロールのいずれかを次に動かすと,Manipulateのグラフィックス式が明示的なViewPointオプションを含んでいるか,別のフォーマットコンストラクトでグラフィックス出力をラップしているかしない限り,そのグラフィックスは手動で動かされた位置まで回転し続ける.
あらゆるタイプの出力のサポート
ManipulateはWolfram言語で得ることのできる全範囲の出力タイプが扱えるよう設計されている.しかし,それはグラフィカルあるいは代数的出力にとどまらない.Wolfram言語でサポートされるすべての出力タイプがManipulateの中で使えるのである.以下にあまり思いつかないようなManipulateの使用例をいくつか挙げる.
GridColumnPanel等のフォーマットコンストラクトはきれいにフォーマットされた出力を生成するために使うことができる(フォーマットコンストラクトについては「Wolfram言語のGrid,Row,Column」を参照のこと).
スライダーやタブのようなユーザインターフェース要素を生成する関数をManipulateでラップすることもできる(ユーザインターフェース要素については「コントロールオブジェクト」「ビューアと注釈」を参照).以下の例では3つ目のスライダーの外観を制御する2つのスライダーを使う.
次のもっと複雑な例では,TabViewの構造がManipulateで制御されている.ここではDynamic[pane]を使うことで,Manipulateで生成されたスライダーを使うか,出力エリアでTabViewをクリックするかして現在のTabViewの枠が選べるようになっている.出力は完全にアクティブである.
この例はManipulateが完全な汎用関数であり,グラフィックスや代数的例題の固定された領域だけの探究に限られたものではないことを例示することだけを意図したものである.文字通り,WolframシステムノートブックのセルにはManipulateを使ってインタラクティブに探究できないものは何もないのである(もちろん使用中のコンピュータの速度による).
Manipulate内部で使用される関数定義の保存
関数を定義して,それをManipulateの第1引数で使うとする.
この例は,ファイルに保存し,Wolframシステムの新しいセッションで開こうとしない限り動作する.関数fはその定義を含むセルを手動で評価しない限り定義されないのである(このドキュメントをWolframシステムで読んでいると,Manipulateの出力エリアにfが現れるが,それはまさにこの理由による).
Manipulateは,自動的にManipulate出力へ,Manipulate入力で参照されるすべての関数(および再帰的にそれらの関数に参照される関数)の定義を構築するオプションSaveDefinitions->Trueをサポートする.これらの定義は,Manipulate出力が開かれた新規のWolframシステムセッションでManipulateの内容が最初に評価される前に,再構築される.
したがって,このドキュメントをWolframシステムで読んでいる場合,初めて開いたときにも2番目の例題の数字は正確に表示されているはずである.
SaveDefinitionsを使うと関数定義やデータが保存できるが,大量のデータを参照する場合は,保存されたManipulate出力を含むファイルに存在するため,非常に大きなファイルになる可能性がある.
そのような場合,別の方法として,Initializationオプションを使い,データパッケージをManipulate出力に組み込む代りにファイルや別のソースからロードすることもできる.Initializationオプションには,Manipulateの内容が新しいWolfram言語のセッションで初めて評価される前に評価するWolfram言語コードのプロックを与えることができる. Initializationオプションの右辺はセッションに付き1度だけ評価される.
例えば,SaveDefinitionsの代りにInitializationオプションを使って上と同じ結果を得ることができる.
SaveDefinitionsは,Initializationオプションに例題を実行するのに必要な定義すべてを自動的に設定する簡単な方法だと見ることができる.SaveDefinitionsは実際のところInitializationオプションの使用を妨げないので,両方使うことも可能である.
ゲームパッドとジョイスティック
マウスを使ってManipulate出力とインタラクトする場合,一度に1つのコントロールを動かすことしかできない.しかし,各指の下にボタンやジョイスティックを置くことでこの限界を克服する多数のUSBコントローラが使える.これで同時に動かすことのできるコントロールの数がかなり増える.
ManipulateでUSBコントローラを利用するためには,それを差し込んで制御したいManipulate出力を含むセルブラケットをマウスで選ぶ(ハイライトする)だけである.Wolframシステムは自動的にコントローラを検出し,Manipulateは自動的に使用できるジョイスティックやボタンと,できるだけ多数のパラメータとをリンクさせる.
Wolframシステムは,どのようなUSBコントローラデバイス(ゲームパッド,ジョイスティック,飛行機のシミュレーションスロットルコントロール,USBコントローラインターフェース標準を使用するデータ取得デバイス等)でも使用できるし,使用できるはずであるが,Manipulate出力を制御するのに他よりも確実にうまく動作するものがある.一般に,ビデオゲームで広く使用されるようなデュアルジョイスティックゲームパッドは,4つのアナログ軸および多数のボタンといった優れたコントロールを提供する.
このセクションの残りの部分では,Logitech Dual Actionブランドのゲームパッドを使っているものと想定する.この手頃なコントローラは広く入手可能であり,他の多数のゲームパッド(ずっと高価なもの)よりも構造的・電気的に優れている.シングルジョイスティックまたは他のブランドのゲームパッドを使う場合は,どのコントローラの部分がどのManipulateパラメータにマップされるかという点で違いがあるかもしれない.
ゲームパッドを差し込んで,次の出力を含むセルブラケットを選択する.初めはゲームパッドのジョイスティックがニュートラルの位置,つまり偏向制御されない位置にあるので何も起らない.しかしジョイスティックを動かすと,1つまたはそれ以上のパラメータが動き出す.パラメータが変更される比率はジョイスティックの屈折度に比例する.
デフォルトではManipulateは左のゲームパッドの x 軸と最初のパラメータを,左のジョイスティックの y 軸と第2のパラメータを,右のジョイスティックの x 軸と3番目のパラメータを,右のゲームパッドの y 軸と4番目のパラメータを接続する.これは,それぞれのジョイスティックを指定された方向に動かしてどのパラメータが変更されるかを見ると確認できる.Logitech Dual Action以外を使っている場合は,マッピングが異なることがある(メーカーにより少しずつ異なっており,Wolframシステムには一般に使用可能なコントローラの多くを正規化する表があるが,常に新式が出てくる).
デフォルトでは,マッピングは速度ベースである.これはパラメータの変更速度がジョイスティックの位置で制御されるということである.つまり,ジョイスティックの位置は変数の値とは直接繋がっていないのである.
これではなく,変数値をジョイスティックの絶対的な位置で決定したい場合がある.そのためには2つの方法がある.ここで使っているLogitechモデルを含む多くのゲームパッドでは,ジョイスティックはボタンでもある.ジョイスティックを抑えるとボタンのようにクリックするため,ジョイスティックでManipulateを制御しているときは,これにより対応するパラメータがジョイスティックの位置に直接リンクされるようになる.この直接モードを使ってどの位置にでもすぐにジャンプさせ,ジョイスティックを解放してそこでパラメータ値を停止させることができる.
ゲームパッドにジョイスティックのボタンがない場合,あるいは連結を常に直接にしたい場合は,オプションControllerMethod->"Absolute"を使う.
直接連結には不利な点がある.最も顕著なのは,接続されたゲームパッドでセルブラケットをハイライトするとすぐに,パラメータ値すべてがその中間の位置にジャンプする.これはもちろんジョイスティックがニュートラルの位置にあるならば当然のことである.マウスで値を設定することはできるが,ゲームパッドを触るとすぐにその値はオーバーライドされてしまう.
速度制御の変形として,オプションControllerMethod->"Cyclic"が使える.この設定では,連結は速度ベースであるが,値のパラメータ範囲の片側に到達すると,中止する代りに反対側へと巡回する.
直接連結と速度ベース連結のどちらがよいかはその例題による.上の例では一般に速度連結の方がよいが,下は直接連結の方がよい.
これらの例題のどれも動作しないならば,例題を含むセルブラケットをハイライトし忘れている場合が多い.これはよくあることである.便宜上,また出力が生成されるたびにそれを選択する必要性を避けるため,コントローラを参照する出力が生成された直後にいずれかのゲームパッドコントローラを動かすと,Wolfram言語は自動的にその出力セルを自動的に選択するようになっている.しかしこれは,出力が生成された直後に限る.その後はどのManipulate出力とコントローラを連結するかはユーザ次第となる.
指定されたManipulateが選択されているか否かにかかわらずコントローラに常に反応するようにしたい場合は,オプションControllerLinking->Allを加えることができるが,これを使う場合には注意が必要である.スクリーン上にそのような出力が多数ある場合,そのどれもが同時に動こうとする.これではあまり役に立たない.このオプションは,このドキュメントのようにスクロールすることを意図して例題を作成するときではなく,固定された形式の出力ウィンドウを作成するときに使うのが一番よい.
上のような例は,ゲームパッドを使っていなければあまり意味をなさないが,パラメータに関連付けられたスライダー,あるいはManipulateの残りのフレームワークを表示しても意味がないこともある.関数ControllerManipulateは機能とシンタックスにおいては基本的にManipulateと同じであるが,フレームやスライダーを一切表示しないという点が異なる.
コントロールがゲームパッドによりどのような影響を受けるかを理解するためにコントロールを見ることができると役に立つので,以下の例題でもManipulateを使い続けることにする.しかしこれらの例題の多くはControllerManipulateでも同様に動作する.
Manipulateに,値が{x,y}という数のペアであるSlider2Dスタイルの変数が含まれる場合,その変数は自動的に利用可能なジョイスティックの両方の方向にリンクされる.次の例は,ゲームパッドの左側のジョイスティックに両方向で応答する.
コントローラのブッシュボタンは,デフォルトでManipulateで指定されるブール型(True/False)パラメータにリンクされる.どちらのボタンがどちらかは,指定のコントローラでは推定しがたい(このヘルプについては以下を参照)が,Logitechモデルでは,右側の4つのボタンに1から4のラベルが付いており,Manipulateはその順序で使用する.以下の例ではボタン「1」をクリックすることでb1の設定が切り替えられ,点の色が変更される.
この切り替え動作(ボタンが押されるごとに,パラメータの値を1度変更する)は「速度」ベースの連結と同じである.ControllerMethod->"Absolute"オプション(上記参照)を使うと,パラメータは直接リンクされ,ボタンが直接押されているとき以外は値は常にFalseとなる.
Manipulateがコントローラ軸とパラメータを接続する厳密な規則は複雑であるが,基本的にはコントローラ上のジョイスティック,ボタン,ノブ,その他のウィジェットを最大限に利用するために,利用できるアナログおよびブール型コントロールをManipulateのパラメータに割り当てるというものである.どれに何がリンクされているかを調べる一番速く簡単な方法は,さまざまなノブを動かして何が起るかを見ることである.
デフォルトの連結が希望のものでないならば,どのコントローラ軸をどのパラメータに接続するかを明示的に指定するとデフォルトをオーバーライドすることができる.コントローラ軸は,論理体系に従って名前が付いているが,ほとんどの場合,"X""Y""XY""X1""X2""B1""B2"等の基本的なものを覚えておくだけで十分である.
"X",またはその異名の"X1"は主の x 軸,あるいはゲームパッドの左側のジョイスティックをさす.パラメータをこの軸にリンクするよう指定するためには,次の形式を使う.
"X2"は同様に第2の x 軸あるいは右側のジョイスティックを指す.
軸は多次元パラメータに組み合せることができる.例えば"XY"は左,または主のジョイスティックの両方向を指し,1つの{x,y}値にすることができる.このように組み合された軸は,以下の例のようにパラメータのSlider2Dスタイルに接続しなければならない.
3軸の変数も"XYZ"としてサポートされる.3軸のジョイスティックコントローラを使うときは,ジョイスティックの自由度3度に対応する.デュアルジョイスティックゲームパッドを使うときは,各ジョイスティックには2度の自由度しかない.この場合,"XYZ"軸は左側のジョイスティックの x および y 方向に加え,右側のジョイスティックの x 方向にリンクされる.これが意味をなすかどうかは,例題により異なる.自由度3のジョイスティックを利用するために特別に書かれた例題は,他の種類のコントローラでは動作しない可能性がある.
コントローラの中には6アナログ自由度を提供するものもあり,"XYZ""XYZ2"で参照される.例えば,3DConnexion Space Navigatorコントロールでは,以下の例題で空間自由度3,角度自由度3が探究できる.このコントロールでないと,うまくいかない.
Manipulateの3D変数はコントローラを使っているかどうかにかかわらず使用できるが,ジョイスティックやゲームパッドとの関連以外では大して利用価値はない.
通常のゲームパッドには"XY""XY2"という2つの x-y コントローラがある.しかし,4つのボタンのグループを上下左右という4つの方向であるとして生成されるいくつかの擬似アナログ軸も利用できるということはあまり知られていない.例えば,Logitech Dual Actionゲームパッドの左側にある方向パッドの「hat」は"XY3"と参照することができる.
追加した2つの軸("XY4")はゲームパッドの右側の4つのボタンと,前面("XY5")の4つのボタンで定義される.これは言うまでもなくLogitechブランドのコントローラ特有のものであるが,他のブランドでも通常似たようなボタンのグループがある.
これらの擬似アナログ軸は本物のアナログ軸のように動作する.異なるのは,前者は速度に連結したモードのときは常に同じスピードで進行し,絶対モードのときは完全に左,中央,完全に右いずれかに固定されるという点である.
特定の軸に連結しようとすると,指定されたコントローラ上のどれがどれかを見つけるのが大変なことがある.関数ControllerInformation[]を使うと,これがインタラクティブに判定できる.ゲームパッドあるいはジョイスティックをつないで,下の入力を評価してみる(現在の情報を得るために,コントローラを接続したWolfram言語のセッションで評価しなければならない).
使用中のコンピュータの種類により,組込みのコントロールが使えることがある.例えば,Macintoshのラップトップには通常常にコンピュータの向きを読み出す位置センサーが含まれている.この情報は利用可能であるためManipulateで使用することができるが,デフォルトでは使えない(そうでないと,コンピュータを傾けるたびにそのようなラップトップで実行されるManipulateが動き回り,幾分うっとうしくなる).
観察したいコントローラを見付け,その名前の隣にある詳細表示三角形をクリックして,Wolfram Languageサブセクションを開くと,利用可能な軸の名前がすべてリストされる.
Show Dynamic Valuesがチェックされていると,パネルに表示される値はコントローラを動かしたりボタンを押したりするとすぐに更新される.これにより簡単にどのボタンがどの軸に対応しているかが分かる(Manipulateで軸の名前を使うときは,その周りに引用符を忘れないようにする).
オプションControllerMethodは全体レベルのManipulateで使い,連結を速度ベースから絶対へと変更することができる.軸のいくつかを絶対連結に,他を速度ベースにしたい場合は,以下の例のように絶対連結にしたい軸の名前に"Absolute"を加える.この例では x 方向が速度ベース連結,y 方向が絶対連結である.
この表記における"Absolute"の反対は"XRelative"等にあるような"Relative"である.
自動実行
Manipulateは多くの点で,単純な線形アニメーションを大きく超えている.Manipulateは固定されたシーケンスから起動するのではなく,自由に行ったりきたりすることを可能にする.しかし,自分でスライダーを動かしたくなかったらどうであろうか.1つの方法として,各スライダーの隣にあるアイコンを使い,アニメーションコントロールのパネルを開くというものがある.1つの変数がアニメーション化されているManipulateAnimateとほとんど同じである.
しかし複数の変数があり,そのすべてを変更したときの効果が見たい場合は,別々のアニメーションコントロールを使うのは不便である.Manipulate自動実行機能を使うと,すべての変数をその値の範囲内で実行する1つのアニメーションコントロールが得られる.
Manipulate出力の右上隅のメニューをクリックして表示されるメニューの一番下の自動実行を選ぶ.Manipulateの上部にアニメーションコントロールとボタンを含む自動実行パネルが現れる.デフォルトでは,アニメーションはそれぞれの変数をその値の範囲内で実行し,残りはデフォルト値のままにしておく.どのアニメーションコントロールでもそうであるが,スピードと方向を変更したり,スライダーをクリックして手動でアニメーションを動かしたりすることができる.自動実行アニメーションスライダーは他のコントロールすべてを定義された順序で動かすマスターコントロールのようなものである.
自動実行のデフォルト動作はマウスでできることをシミュレートする.つまり,一度に1つのコントロールを動かすのである.Manipulate入力にオプションAutorunSequencing->Allを加えると,以下の例で分かるように結果の出力の自動実行コマンドはすべてのコントロールを同時に動かす.この機能はうまく動作する例とそうでない例がある.
AutorunSequencing自動実行アニメーションからあるコントロールを除外するため,あるいはアニメーション化されるコントロールの順序を変更するために使うこともできる.例えば,ここでは3番目のコントロールを最初に動かし,1番目,4番目を動かし,2番目のコントロールはデフォルト値に留めたままにする.
AutorunSequencingを使うと,特定のコントロールのアニメーションのために確保する時間が指定できる.この設定は最初のコントロールに対して2秒間,3つ目のコントロールに対して2秒間,4番目のコントロールに対して10秒間確保する.2つ目のコントロールは飛ばされる.
AutorunSequencingの詳細を気にする理由のひとつは,自動的にアニメーションビデオ(QuickTimeやFlash形式で)を生成するためにExportコマンドが使えるというためである.Exportはデフォルトで自動実行1回分Manipulateを実行してアニメーションを生成する.
AutorunSequencingではアニメーションシーケンスに対して十分な制御ができない場合は,次のセクションで説明するブックマーク機能を使い,パラメータ値の組合せである「way point」のリストを定義し,これらの定義された点をスムーズに補間するアニメーションを作成することができる.これだとアニメーションの厳密なパスに対して完全に制御ができる.
パラメータ値の組合せをブックマークする
Manipulate関数は,多くのコントロールを持つ場合は特に,捜しても見付かりそうにないものを見付けるために使うことができる.見付かりそうにないものとは,特に面白い結果を出す複数のパラメータ値の特定の組合せのことである.そのような値の集合が見付かると,後の参照のためにそれを保存しておいた方がよい.ManipulateManipulate出力の右上隅のメニューでこれを実行するための機能を提供している.
単独の値を静的入力として使うことのできる形式にするためには,メニューからスナップショットをペーストコマンドを使う.結果はManipulate出力の下の新規セルに挿入される.
次は,この例でスナップショットをペーストを使った結果である.
3つの現在値がDynamicModuleの変数定義ブロックにコピーされ,最初の引数がボディにコピーされる.DynamicModuleが使われるのは,ボディーで明示的にDynamicが使われている場合にこの方が正しく動作するからである.結果で何がしたいかによるが,DynamicModuleの代りに式を変更せずにModuleWithBlockを使ってもよい.あるいは割当てのブロックを,構築中の他のコード等にコピーペーストしてもよい.ModuleDynamicModuleの違いは「Dynamicの高度な機能」に詳しく説明してある.
将来見付けやすいように覚えておきたいだけならば,その場所を即座に抽出する代りにメニューからブックマークに追加を選ぶとよい.これでパネルが表示され,ブックマークの名前を付けボタンをクリックすることでこのManipulateに既知であるブックマークのリストに加えるか,ボタンをクリックして追加をキャンセルする.
ブックマークを加えた後,指定した名前がメニューに現れる.そのメニューから名前を選ぶことで,すべてのパラメータはそのブックマークが加えられたときに持っていた値に戻る.また,すべてのManipulateはそのコントロールの初期設定を覚えているので,このメニューの初期設定を選ぶことでその値に戻ることができる.
一旦ブックマークを置き始めると,メニューにはブックマークをペーストブックマークのアニメーション化という,関連のある2つの項目がある.
ブックマークとは,指定されたパラメータ空間における位置のリストであり,ブックマークのペーストを選ぶことでそのリストの生のデータを抽出することができる.結果のリストはどの要素もbookmarkName:>parameterValuesという形式である.このリストはManipulate入力にBookmarksオプションの設定として再挿入するのに文法的に適している.例えば,これにより新しいManipulate出力のアクティブなブックマークとして復元する前に,手動の編集でブックマークを編集したり,それに対してプログラムを実行したりすることができる.
ブックマークのアニメーション化メニューコマンドは上のセクションで記述してある自動実行コマンドのように動作するが,各パラメータをその値の範囲内でアニメーション化する代りに,ブックマークにより指定された点を介して補間するアニメーションを生成する.
ブックマークをアニメーション化するときに発生する補間は,Interpolationコマンドで内部的に実行される.Manipulateはアニメーションがどのように1点から次の点へと進むかを調整するために,InterpolationOrderオプションさえも取る.Automaticのデフォルト値は,十分なブックマークがある場合には二次補間を,それ以外の場合は線形補間を実行する.
明示的なブックマークを含むManipulate出力は,Exportを使ってビデオアニメーション形式へとエキスポートされる.結果のビデオはブックマークのアニメーション化により生成されたシーケンスを通して1サイクルである.ブックマークがない場合は,結果は自動実行の1サイクルである.