2010-10-15

矩形データ構造

いくつかの環境でプログラミングをしていると、単純な(二次元直交座標系上の各辺が座標軸に沿った)矩形を表すのにいくつかの異なった方法があることに気がつく。

たとえばWin32のRECT構造体は左、上、右、下の各座標値を保持する。これは矩形の対角線の端点座標を保持している(左上の点と右下の点、あるいは、右上の点と左下の点を保持している)と解釈しても良いし、各座標軸における範囲(下限値と上限値)を保持していると解釈しても良い。

一方Java AWTのRectangleクラスは左、上の座標値と幅、高さを保持する。

他にも、位置の表現方法と大きさの表現方法を工夫すれば無限に考え出すことができる。中でも中心座標と幅高さ(または半径)を保持するような構造はポピュラーな方だろうか。

矩形を表現する構造は何もコンパクトでなくてもよい。矩形はある種の点の集まりなのだから、代表的な点を可変個数保持するような構造も考えられる。この構造は矩形のしめる範囲だけを表すのには無駄が多いが、個々の点が最終的に矩形の構成要素としての意味を持つのであれば、矩形を表現する構造と言える。ただ、「矩形のしめる範囲」以外の情報も多分に含んでいるので、今回の話からはやや外れる存在かもしれない。

幾何学上の性質を元に考えれば、矩形の占める範囲は最低四つの数があれば表現でき、それらをどのように組み合わせて矩形を表現しても同じことになる。

このように一見同じものを表現するにも色々と方法があるわけだが、コンピュータの数値上で扱うには色々と細かい点で違いが出てくる。

面倒なので詳しくは書かないけれど、派生属性の計算コストとか値域とか精度とかそういった色々な都合で最適な構造は変わってくるので、どれか一つに統一というわけにもいかない。煩わしい。unionやintersectionの計算は左右上下構造の方が分かりやすいと思う。でも左右上下構造は特に浮動小数点数の場合平行移動しただけでサイズが変わるという問題があったり。

ちなみに、上では左、上、幅、高さ等という語を断り無く使っているが、これらの語は座標の取り方に依存するので誤解が生じる場合もある。厳密には第一軸(X軸)負方向端、第一軸に沿ったサイズ、などと表現した方が良いかもしれない。