SSブログ

Mac用プロットライブラリ-12 [考え中 - プロットライブラリ]

前回の、プロット座標から相対指定されたView座標が、描画領域からはみ出す場合の処理について。前回の議論はあまりにもナイーブだったことがわかった。もう一度整理し直すことにする。まず、はみ出し問題を扱う前にそれがどこで現れるか、を示すためまずレイヤ構造のおさらい。

ユーザから受けたプロットすべきデータを表示するのを、4つのレイヤに分担させることにした。
  1. Automatic Layer
  2. Primitive Layer
  3. Normalized Layer
  4. View Layer

1.Automatic Layer

Automatic Layerは
  1. ユーザが指定した、あるいは暗黙のオプションを展開してPrimitiveの集合に変換する
  2. Primitve Layerのインスタンスを作る
のが仕事。特にAutomaticオプションを具体的な指定に展開するのが仕事量が多い。かなりの手間だけどこれをどこまで作り込めるかでライブラリとしての使い勝手が違ってくる。
Automaticオプションは例えば
KeyAutomatic指定したときの意味
PlotRange範囲指定 {{xl,xh},{yl,yh}}データ全体が表示領域一杯になる
AspectRatio縦横比座標軸の刻みが等方になる
AxesOrigin軸の交差位置PlotRange内できりのいいところ
LineStyle線の描き方適当な色を付ける

などがある。Styleに関するオプションはこの他にもいっぱい考えられる。このへんのパラメータの概念はMathematicaから借りてこよう。

2.Primitive Layer

は、PrimitiveをPlot座標からNormalized座標に変換する。
それは
  1. PlotRange指定から変換行列を作る
  2. Normalized Layerのインスタンスを作る
  3. 変換行列を使ってNormalized Primitiveに変換する
で、これは簡単。

3.Normalized Layer

は、描画先のViewのRectを使ってView座標に変換するのが仕事。これはAspectRatioの指定によってちょっと違う。
縦横比の値NSViewの上でその縦横比になるような変換行列を作る
FillInRectNSViewいっぱいになるような変換行列を作る
縦横比の指定はユーザがする場合と、Automatic指定を受けてPlotRangeから計算される場合がある。これが前回気がついたはみ出しの問題とからむ。あとでもう一度整理する。

4.View Layer

は、View座標に変換されたPrimitiveを、NSBezierPathなどに展開してNSViewの上に描画する。オプションで指定されているStyle、例えば
  • 線の太さ
  • 線の色
  • マーカを置く
  • 影付け、スムージングなどの描画
などがある。もともとCocoaの(Quartzの、というべきか)描画機能を前提にしているので、オプションとNSBezierPathの指定はだいたい1対1に対応できるはず。あまり細かいところは考えてないけど。

ウィンドウのリサイズとかで描画先のNSViewのRectの大きさが変わったときはNormalized Layerから先を作り直すことになる。結構オーバーヘッドがでかいけど、まあええでしょ。実装が簡単な方がいい。

はみ出し問題

さて、やっと問題のはみ出しについて。 前回、繰り返しのアルゴリズムで収束する、と書いたけどちゃんとそれを保証する方法があった。それをもう一度整理する。
例えば図-6のような場合を考える。 0512fig6.png
Plot領域(今の場合、(0,1)区間に収まったNormalized座標の正方形領域)の大きさはView領域に(実際は描画先のNSViewのNSRect)フィットするように拡大縮小される。ここでPlot領域の中のniという位置からviという点がView座標で相対指定されているとする。つまりniはPlotが拡大縮小されるにつれて実際に描画される位置は変わる。そこからviというView座標、つまり画面上のpoint単位で測られる距離だけ離れた位置を指定している、とする。これは文字を書き込む場合など、頻繁にあり得る。このときView領域一杯にPlot領域をマップするのではなく、図のように小さくマップして左右ともView領域内に収まるようにマップする必要がある。

N個のNormalized座標のi番目の(dix, diy)から相対指定されたView座標(Lix, Liy)のNSViewでの描画位置(vix, viy)は
0512eq1.png
となる。αは拡大の係数で、τはシフトの係数になる。普通は3行3列の行列で書くのだろうけど回転させないので非対角要素が無いからこれの方が簡単。

これがViewからはみ出さないという条件は
0512eq3.png
となる。ここでWとHはそれぞれViewの長方形の幅と高さ。NSViewではpointで測った画面上での矩形領域の大きさ。相対座標の符号によって不等号の効く方向が決まるので式-1、2のLiの符号によって分けると
0512eq5.png
となる。つまり、この式のすべてのiについて条件を満足し、かつαが最大(View領域になるべくいっぱい)のものを求めると言う問題になる。これはいわゆる線形計画法の問題に他ならない。線形計画法は物理屋にはあまりなじみは無いけど、資源配分の最大効率化(多くの種類の材料から多くの種類の製品を作るときに利益を最大化するなど)などごく普通に現れる問題なのでよく研究されている。今回の場合、ふたつの変数αとτに関するN個の条件を満足する二つの独立な線形計画問題に帰着する。

また、縦横比が指定されている場合、縦横比εを
0512eq7.png
として
0512eq8.png
となるから、条件式は
0512eq10.png
となって、みっつの変数α、τx、τyに関する2N個の条件を満足する線形計画法とみなせる。
線形計画法としては非常に単純な問題である。

とは言うものの、じつは線形計画法はあまりよく知らない。シンプレックス法というアルゴリズムがあってそれでプログラマチックに解ける、ということぐらいしか知らない。gslの中にも線形計画法は入っていない。MathematicaにはLinearProgramingという関数いっぱつで解けるらしいけどブラックボックスで中身はわからない。

しょうがないのでちょっと勉強しよう。

いや今日は、悩んでたことが知らないなりにも線形計画法という一般的な問題と見なせるということがわかっただけでも収穫。こういうのは充実感があるがな。うれしい。
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

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

トラックバック 0

献立05/12献立05/13 ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。