なんちゃってMathematicaを作る - その20 [なんちゃってMathematica]
昨日の続き。3種類の座標表現があって、それを混在して使っていい、ということにしたときに、座標を変換していく作業と相対座標の解決をどう両立するか、というのが問題だった。今日とりあえずの解決策を思いつくことができた。もっといい方法があるかもしれないけど、とりあえず今日はその話。
の3つを使うことにした。途中でnormalized座標を挟む理由は前書いた。
そしてこの3つとも相対指定を許したので、たとえばplot座標で指定されたある位置からview座標で指定されたオフセットの位置、なんかを表現することができる。
ところが3つの座標ごとに別のオブジェクトにすると、相対指定のポインタを更新する必要がある。つまりplot座標に対して相対指定したview座標は、plot座標からnormalized座標に変換されて、normalized座標のオブジェクトが作られたとき、相対元をさしたview座標のポインタはplot座標のほうのままになってしまう。これは何らかのタイミングで更新してやる必要がある。
しかし、かならず更新が必要か、というとそれは組み合わせによる。
この組み合わせはその場で相対座標から絶対座標に解決してしまうことができる。
この組み合わせは、座標変換がおこなわれてplot→normalized→viewと作られる過程のどこかで、即時解決の組み合わせと同じになる。座標変換の過程で元座標を指しているポインタは変更する必要はない。
この3通りの対応ができればいい。わざわざ整理するまでもなくちょっと考えればわかることだけど下層から上層への相対指定はポインタの更新が必要になる、ということ。
とはいうものの、簡単ではない。
plot座標は使いまわしすることができるようにしたい。そのとき変換後の座標はplot座標の組み合わせによって変わる。使いまわしたときにこのポインタをどう扱うか、というのは非常にめんどうな問題になる。
そこで、そのポインタを外に持つ、ということを考えてみる。つまり、
ところでこの辞書は座標変換のクラスに持たせるしか今のところ方法はない。本来ならコンテナクラスのインスタンスに持たせるべきだが、座標オブジェクト側が自分が属しているコンテナを知る方法を用意するのは簡単ではない(たとえば、スレッドごとに専用のスタックを持たせてそのトップにコンテナへのポインタを置く、とかする必要がある)。
座標変換のクラスはすべての座標点をスキャンするし、その時の副作用として辞書をアップデートすればいい。シンプルさ、美しさはいまいちだけど簡単。
ということで、座標変換にまつわる問題は解決できたことにしよう。実装するときにもういちど突っ込むことになるのでこのへんで置いておくのがいいだろう。
ふう。
4.6 相対座標解決のタイミング
3種類の座標の混在を許して、しかも相対指定をできるようにしたせいで、問題が発生した。もう一度整理する。4.6.1 座標の種類
座標にはplot | ユーザが指定する座標 |
normalized | plot領域全体を[0,1]区間に規格化する |
view | 描画座標 |
そしてこの3つとも相対指定を許したので、たとえばplot座標で指定されたある位置からview座標で指定されたオフセットの位置、なんかを表現することができる。
ところが3つの座標ごとに別のオブジェクトにすると、相対指定のポインタを更新する必要がある。つまりplot座標に対して相対指定したview座標は、plot座標からnormalized座標に変換されて、normalized座標のオブジェクトが作られたとき、相対元をさしたview座標のポインタはplot座標のほうのままになってしまう。これは何らかのタイミングで更新してやる必要がある。
しかし、かならず更新が必要か、というとそれは組み合わせによる。
4.6.2 即時解決
まず、受け取った時点で解決できる組み合わせは元座標側 | ← | 相対座標側 |
plot | ← | plot |
normalized | ← | normalized |
view | ← | view |
4.6.3 更新不要
また、次の組み合わせ元座標側 | ← | 相対座標側 |
normalized | ← | plot |
view | ← | plot |
normalized | ← | view |
4.6.4 更新が必要
最後の組み合わせは更新が必要になる。それは元座標側 | ← | 相対座標側 |
plot | ← | normalized |
plot | ← | view |
view | ← | normalized |
とはいうものの、簡単ではない。
4.7 更新の方法
いちばん簡単なのは、やっぱり座標変換後のポインタを持っておくこと。つまり、plot座標はそれを変換したnormalized座標へのポインタを、normalized座標はview座標へのポインタをインスタンス変数として持つ。でも、ほとんどのインスタンスではそのポインタは使われずに終わってしまう。それともうひとつ問題がある。plot座標は使いまわしすることができるようにしたい。そのとき変換後の座標はplot座標の組み合わせによって変わる。使いまわしたときにこのポインタをどう扱うか、というのは非常にめんどうな問題になる。
そこで、そのポインタを外に持つ、ということを考えてみる。つまり、
- コンテナにひとつNSMutableDictionaryを持つ
- 座標変換したplot座標をキーにして、その変換後のnormalized座標のポインタを辞書ペアとして保持する
- 更新が必要な相対座標は、変換先を辞書に問い合わせる
- 座標ひとつひとつがポインタを持つ必要がない
- 変換はコンテナごとに行われて、それごとに辞書は独立するので、plot座標の使いまわしができるようになる
- コンテナに含まれていない座標を参照している相対座標のチェックをすることができる
- 辞書探索のオーバーヘッドが発生する
ところでこの辞書は座標変換のクラスに持たせるしか今のところ方法はない。本来ならコンテナクラスのインスタンスに持たせるべきだが、座標オブジェクト側が自分が属しているコンテナを知る方法を用意するのは簡単ではない(たとえば、スレッドごとに専用のスタックを持たせてそのトップにコンテナへのポインタを置く、とかする必要がある)。
座標変換のクラスはすべての座標点をスキャンするし、その時の副作用として辞書をアップデートすればいい。シンプルさ、美しさはいまいちだけど簡単。
ということで、座標変換にまつわる問題は解決できたことにしよう。実装するときにもういちど突っ込むことになるのでこのへんで置いておくのがいいだろう。
ふう。
2012-03-13 22:14
nice!(0)
コメント(0)
トラックバック(0)
コメント 0