So-net無料ブログ作成

なんちゃってMathematicaを作る - その19 [なんちゃってMathematica]

前回から2週間以上も経ってしまって忘れてしまいそうになるんだけど、がんばって続きをやる。

2次元プロットを与えられた矩形いっぱいに、しかし端っこが切れたりすることなく表示するため、3つの座標の表現を使って順に変換されることでそれを実現するような方法をとることを決めて、その問題点を整理していた。前回は実装に近い問題をおさらいした。その結果3つの座標表現は汎用の表現のサブクラスとして実装しよう、ということにした。今日はそのことによって発生する別の問題について。

4.5.2  別の問題

一番簡単なサブクラス化という手段をとると、別の問題が持ち上がる。相対座標の処理をどうするか、という問題である。

たとえばあるplot座標Apに対して相対的な位置を保持したplot座標Rpがあるとする。RpApへのポインタを持っているはずである。

この両方をnomalize座標に変換して、それぞれAnRnを作ったとしよう。Rnも相対座標のままだとすれはポインタを持っているはずだが、それはAnを指すようにはならない。この場合はnormalized座標に変換する前に相対値を解決してしまえばいい。指している先が別の相対座標であったとしてもいつかは解決できるはずである。

では、相対的なplot座標Rpが、plot座標ではなくview座標Avを指していたらどうするか。座標の混在を許したのでこういうケースはありえる。この場合plot座標がview座標に変換されるまで絶対座標には変換できない。したがって相対座標のまま残ることになる。

しかしこの場合は、view座標がplotToNormalizedWithTransformation:メソッドを受け取ったときには新しいnormalized座標を作らず自分自身を返すようにすればいい。どっちみちview座標からnormalized座標へ変換することはできないしする必要がない。この場合はこれで問題は解決である。

では最後に残った例を考えてみる。たとえば曲線オブジェクトの中にview座標がまざっていたとしよう。混在を許しているのでこれもありえる。そしてそのview座標は別のplot座標の相対値だったとしよう。これも相対view座標は解決できない。そしてplot座標がnormalized座標に変換されたとき、相対view座標のポインタは古いplot座標を指したまま更新できないということになる。これは大きな問題である。わかりにくいので図に書くと図-4のようになる。
0312fig4.png
なんだかあまり分かりやすくなってないけど、左側のplot座標がNormalized座標に変換されたとき、右側の相対View座標は解決できないので相対座標のままだけど、相対元を指しているポインタ(赤い矢印)は変換後には黒点線のポインタにつけ変わっている必要がある。

4.5.3  相対付け替え処理の解決法

これを解決するにはどうするか。いくつか方法が考えられる。
  1. すべてのplot座標が変換後のnormalized座標へのポインタを持つ
  2. 相対座標からポイントされていることを絶対座標側が知っている
  3. plotContainerが「相対座標データベース」を持つ
  4. 座標変換時に相対座標が含まれていないかスキャンする
  5. その他
1番目は、plot座標がnormalized座標に変換されたあと、相対座標解決を指示されたとき、plot座標は自分自身の座標値をもとにするのではなく、変換後のnormalized座標のほうを使って解決させるようにする、ということである。本来plot座標は自分がどのnormalized座標に変換されたかを関知する必要はない。そして相対指定元となるようなplot座標は、普通の用途ではそれほど数は多くないはずである。したがってほとんどのplot座標にとってnormalized座標のポインタは無駄である。

2番目は逆に相対指定を受けている側がポインタを持つ、というやりかたである。相対指定する側は一つとは限らないのでNSArrayとして保持することになる。そして変換したことを相対指定する側に教えてやるのである。これも結局すべてのplot座標がNSArrayを持つことになって(ほとんどはnilだろうけど)非常に無駄である。

3番目は、すべてのplot座標がポインタを持つのではなく、変換の関係を外部に持つ、ということである。この場合、相対座標と相対元のペアを保持することになる。そして変換されたことを検知してペアを更新する。この場合は関係するものだけを保持すればいいのでメモリ上は無駄が減るが、更新のタイミングが難しい。変換された座標が生成されたときしか両方を知る瞬間はない。結局全座標をスキャンする4番目と同じことになる。

結局座標をそれぞれサブクラス化したのが問題のもとになっている。かといってunionにもどるのはいまいち。だいたいunionではあまりObjective-Cの恩恵を受けられない。座標のコンテナとなるオブジェクトを作る、というのも手だけどやっぱり屋上屋ですっきりしない。

いちばん簡単なのはやっぱりサブクラス化して変換後の座標へのポインタをそれぞれ持つ、というのだろう。しかしそれでも問題は残る。座標を変換するタイミングと、相対指定を解決するタイミングが微妙だということ。

相対指定の解決は、plot座標からnormalized座標への変換が終わってからでないとポインタを付け替えることができない。そして変換がすべての座標点に対して終わってから、相対指定座標を探すためにまたすべての座標点をスキャンしなければならない。これは2度手間である。変換中に相対解決をすればいいけど、そのとき相対指定元の変換が終わっているとは限らない。

そうすると、どうするか。続きはまた明日考える。
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0