myugaruの色々構想中・・・!

「C#」「画像処理」「XNA未対応PCでゲームIDE作りの無謀な野望」

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  98  : 記事  0  : コメント  2322  : トラックバック  59

ニュース

myugaru
仕事(昔)=ヲタク系プログラマー~マスコミ系サポートデスク
仕事(今)=電子機器系サービス業
趣味a=パズルゲーム全般、シューティングは主に見学
趣味b=画像処理関係の勉強
趣味c=プログラミング言語の勉強
趣味d=アキバ系ヲタク
趣味e=芸能アイドル系ヲタク
d,e色の強いもう一つのブログ
最新目標=シューティングゲームを作る

わんくまりんく

わんくま同盟blog C#,VB.NET掲示板

ぶろぐつーる

あわせて読みたい

はてなりんぐ

書庫

日記カテゴリ

ギャラリ

お友達

リンク

●前回まで

[画像処理](x1,y1,x2,y2) vs (x,y,width,height)
[画像処理](x1,y1,x2,y2) vs (x,y,width,height) その2
[画像処理](x1,y1,x2,y2) vs (x,y,width,height) その3
[画像処理](x1,y1,x2,y2) vs (x,y,width,height) その4

※以下PnPとPnSは私の造語です。
PnP・・・Point and Point。座標2つで矩形領域を表す方式
PnS・・・Point and Size。座標1つと領域のサイズで矩形領域を表す方式


前回はGDIとGDI+の矩形描画の仕組みを私なりに書いてみました。
しかし色々と調査してみるとGDIの「内接する矩形を描画している」という解釈はどうやら不正解のようです。
●線分描画アルゴリズムからの考察
説明のために縦の辺についてだけ抜き出します。
前回説明を省きましたが緑が仮想座標上の辺、
青が実際のディスプレイに表示されるピクセルです。

内接すると仮定すると図1(A)のようになります。

 

緑の線に対して青のピクセル位置を求めようとすると、
左右のそれぞれ別の(線分描画の)計算が必要となります。
果たして縦線を2通りの計算で求めるなどわざわざやるか?という問題です。
その可能性は0では無いでしょうが、どの縦線も同じ計算で求めていると考えた方が自然ではないでしょうか?
そしてその場合は図1(B)のようになります。
するとこれはRightは-1した値を用いて計算するという事になります。
あるいはLeftを+1する説も考えられますが数学の世界で上限を未満で表現する体系がありますのでRight-1という解釈の方が妥当だろうと思います。

ここにきて「GDIは右下座標を用いない。左上以上、右下未満で範囲指定する」
という俗説がやっぱり正解なんだなあとわかります。
なんとか別の説をひねり出したかったのですが今日の所はあきらめます。


●線幅について
前回の最後で考慮がもれていると書いたアレは線幅でした。
線幅をテストできるように実験プログラムを修正しました。
http://myugaru.wankuma.com/GDIvsGDIplus.zip
見やすいようにグリッドも表示しています。

 

GDIの矩形(塗潰し)Left=2,Top=2,Right=8,Bottom=8を線幅1~3で表示すると次のようになります。

こうしてみると線幅2の時は緑の線が青の中心を通っています。
線幅1や3の場合には中心がピクセル中央となってしまいますので、
誤差の0.5だけ右下方向へずらして描画しているようです。

すでにGDIの矩形は内接矩形の描画では無いだろうと書きましたが、
線幅2以上の矩形の図の説明を内接矩形でするとかなり無理が生じます。
そういう意味でもやはり内接矩形論は正しくないのだろうと考えられます。


●GDI+の線幅2以上はどうか
GDI+について線幅2以上で書くとGDIと全く同じ考え方になっているとわかります。
つまり線幅が偶数の場合は緑の線が青の中心を通り、
線幅が奇数の場合は緑の線の右下へ0.5ずれるという仕様です。
●まとめ
GDIもGDI+もどちらも上の緑の線で表現されるような仮想図形を想定しており、
ディスプレイのピクセルで表現する際に誤差が生じているのだとわかりました。
ディスプレイ主体で考えると色々な疑問が生じるのはそのせいです。
また矩形描画について実験した結果はGDIもGDI+もどうやら誤差の扱い方は同じだということもわかりました。
またGDIは右下を使用しないという仕様を再確認できました。
●次回
このシリーズは私は結構おもしろいと思ってやっていますが、
読んでる人はそろそろ飽きて来たのではないかと思っています。
昨日書いたリバースエンジニアリングの話にしてもいいかなと思ったり、
あるいはUMLの勉強で序章が終わりましたので、
ゲーム製作の方を進展させるのもいいかなと思っています。
投稿日時 : 2008年3月21日 15:53

コメント

# re: [画像処理](x1,y1,x2,y2) vs (x,y,width,height) その5 2008/03/21 23:52 junki

こんばんは。

GDI+ では Pen クラスの Alignment プロパティーでそのあたりは自由に設定できますよね。 ちなみに PenAlignment 列挙体には

Center   Pen オブジェクトの中心が、理論上の線上に配置されることを指定します。
Inset   Pen が、理論上の線の内側に配置されることを指定します。
Left    Pen が、理論上の線の左側に配置されることを指定します。
Outset  Pen が、理論上の線の外側に配置されることを指定します。
Right   Pen が、理論上の線の右側に配置されることを指定します。

とあります。(ヘルプより)


# re: [画像処理](x1,y1,x2,y2) vs (x,y,width,height) その5 2008/03/22 2:17 myugaru
To junkiさん
こんばんは。
なるほど確かにAlignmentプロパティがありますね。
ということは上の結果はデフォルトの動作なのですね。
さっそく実験してみることにします。
コメントありがとうございました。


Post Feedback

タイトル
名前
Url:
コメント