描画の基礎知識

  1. クリッピング領域

    ピクチャー コントロールをはみ出して、描画命令を実行するような場合には、外側の部分を切り落とす必要がある。つまりクリッピング 領域 (region)を設定しなければならない。クリッピング領域は使い終わったら、削除しなければならない。

    // (x1, y1) が左上の頂点の座標
    // (x2, y2) が右上の頂点の座標
    // x1, y1, x2, y2 はすべて整数値
    CRgn s;
    s.CreateRectRgn(x1, y1, x2, y2);
    pDC-$ >$SelectClipRgn(&s);
    // クリッピング領域の削除
    s.DeleteObject();

  2. 曲線の描画

    直線はMoveToとLineToで描けるが,曲線は描けない。そこで,曲線を描くには,点を打っていくという方法をとる。そのための関数として,SetPixel(x座標,y座標,RGB)がDCに用意してある。

    pDC-$ >$SetPixel(int(xg),int(yg),RGB(255,0,0));
    により,赤の点を座標(xg,yg)に打っていく。

    これで,一応仕様を満たすプログラムは完成したが,目盛線とx軸が揃わなかったり,xの値に目盛り幅をかけて調節したりとあまり綺麗ではない。そこで,

  3. 座標系と表現

既定の座標系
標準の座標系はテキストの描画に便利な MM_TEXT モードで、表示部分の左上を原点とする。y座標は値が大きくなると下の位置になる。座標の単位は画素数(整数)である。 マッピングモード
DCは複数のマッピングモード(座標系)を持っている。マッピングモードは
SetMapMode(MM_TEXT)
で設定できる。また、原点は、
SetWindowOrg(x,y)
で設定をすることができる。

マッピングモードの種類

マッピングモードには、MM_TEXT以外にも多くの種類が用意されている。

論理座標系と物理座標系

画素単位の既定状態のマッピングモードは物理座標系(DP)となる。マウスやボタンの座標はこの物理座標系で位置が渡される。一般の座標系は論理座標系(LP)と呼ばれる。座標系や原点が移動した場合、相互の変換が必要である。
LPtoDP()、DPtoLP()
がこの変換を行う。

座標系(MM_ISOTROPIC、MM_ANISOTROPIC)

このモードでは、通常の数学と同様の座標系に設定できる。座標の値の範囲はSetWindowExt(lx,ly)で設定可能で、単位は整数だが画素数には拘束されない。この、値の範囲で、描画するウインドウの範囲を、SetViewportExt(dx,dy);で設定する。dyを負にすると、y軸の方向が逆になりy座標が大きくなると、座標の位置は高くなる。原点の位置をSetViewportOrg()で設定できる。原点の位置を中央にすれば、座標に符合が利用できる。 MM_ISOTROPICはx,yの比率を1:1にするが、MM_ANISOTROPIICは変更可能である。

マッピングモードの設定例

以下の例では、マッピングモードをMM_ISOTROPICとし、論理座標の範囲を-1000..+1000とする。  GetClientRect()はダイアログ全体の矩形のサイズをboundに設定する。表示画面は、ダイアログ全体であるが(ボタンの範囲である)右側80を標示用のビューポートからはずす。y軸の正の方向を上にするため、SetViewportEx()tのyの値は負にする。SetViewportOrg()で、ビューポート(物理)座標系で原点の位置を標示領域の中央に指定する。

dc.SetWindowExt(1000,1000);
GetClientRect(bound);
bound.right-=80;
dc.SetViewportExt(bound.Width(),-bound.Height());
dc.SetViewportOrg(bound.Width()/2,bound.Height()/2);

論理座標の範囲を超えると この設定は論理座標と物理座標の対応関係の設定に利用されるだけで、設定値より大きな論理座標を指定すると、はみ出して表示をする。

dc.SetMapMode(MM_ISOTROPIC);

固定系

座標系をインチ、メートル、ポイント(文字の大きさの単位)に固定する。実寸で印刷をするには便利だ。MM_LOMETRICは0.01インチ、MM_HIMETRICは0.001インチ単位になる。