グラフィックスの生成方法の違いとは?

解決


のりだぁ=  2007-04-21 20:59:01  No: 136177

同じ長さの横線を等間隔で何本か引くプログラムを作っています。
  コード①はピクセル単位で、コード②は㎜単位で書こうとしました。
  コード①
   Private Sub Button1_Click(ByVal・・・EventArgs) Handles Button1.Click
        Dim a, b As Integer
        Dim d As Graphics
        d = PictureBox1.CreateGraphics
        For a = 0 To 20
            b = 50 + 28 * a '縦線の線と線の間隔
            d.DrawLine(Pens.White, b, 30, b, 585)
        Next a
        d.Dispose()
    End Sub
    コード②
    Private Sub Form1_Paints(ByVal sender As Object, ByVal e As       System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
        Dim a, b As Integer
        Dim mypen As New Pen(Color.White, 1 / e.Graphics.DpiX * 25.4)
        e.Graphics.PageUnit = GraphicsUnit.Millimeter
        For a = 0 To 20
            b = 10 + 7.5 * a '縦線の間隔を決める
            e.Graphics.DrawLine(mypen, b, 10, b, 160) '縦線を書く
        Next a
    End Sub
そうすると、コード①ではほぼ等間隔で線を引けるのに対し、コード②では見た目で分かるほど間隔がずれてしまいます。なぜ、そのようになるのかが、よく分かりません。宜しくお願いいたします。


大吉末吉  2007-04-21 21:26:11  No: 136178

>         Dim a, b As Integer
>             b = 10 + 7.5 * a '縦線の間隔を決める

整数型である変数「b」に、小数計算の結果を代入しているから、とか・・・
#「〜.5」は丸められて、「〜.0」になってしまいますね。


のりだぁ=  2007-04-21 23:07:58  No: 136179

ご指摘ありがとうございます。コードを書き直したらコード①の結果と同じ間隔の線が書けました。
コード③
Private Sub Form1_Paints(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
  Dim a, b, d As Decimal
  Dim mypen As New Pen(Color.White, 1 / e.Graphics.DpiX * 25.4)
  e.Graphics.PageUnit = GraphicsUnit.Millimeter
  For a = 0 To 20
  b = 10 + 7.4 * a '縦線の間隔を決める
  e.Graphics.DrawLine(mypen, b, 10, b, 158)  '縦線を書く
  Next a
  e.Dispose()
  End Sub
ここで、本来は5㎜間隔の線を書きたいのになぜ間隔を7.4とコードに書かないといけないのか疑問に思いました。パソコンの機種によってこの数字は変える必要があるのでしょうか?宜しくお願い致します。


  2007-04-23 18:48:43  No: 136180

画面上で5mm間隔の線を引くのであれば
解像度とディスプレイ自体のサイズに依存するのでは?


  2007-04-23 18:52:32  No: 136181

↑ごめんなさい。勘違いです。


大吉末吉  2007-04-23 19:54:13  No: 136182

#初  さんは「勘違い」と言われていませんが・・・
#念の為、解説。

> 本来は5㎜間隔の線を書きたいのになぜ間隔を7.4とコードに書かないといけないのか

ディスプレイ上で、実際に5mmの大きさに見せたいのでしょうか?

> e.Graphics.PageUnit = GraphicsUnit.Millimeter
ここで言う「ミリ単位」は、「論理単位(仮想的な大きさ)」で「物理単位(実際の大きさ)」と同一である保証はありません。

例えば、
ディスプレイの解像度が1024x768で、
DPI(ドット パー インチ)の設定(画面のプロパティの詳細で設定)なら、

画面の横幅は、(実際の大きさに関らず)
1024(ドット)/96=10.66・・・[インチ]
つまり、約270.9[ミリメートル]の大きさがあるものとして動作します。

その為、実際のディスプレイのサイズがコレより小さい場合、大きめにサイズを指定しないと、実際のサイズに見えません。

ちなみの私のノートPCは実際のディスプレイの横幅は約246mmなので、
5mm*270.9/246=5.5を指定すると、ディスプレイ上で5mmに見えますね。

って事で、

> パソコンの機種によってこの数字は変える必要があるのでしょうか

に対する回答は、
「PCの画面設定と、表示に使用するディスプレイの実際のサイズごとに変える必要があります」ですね。


のりだぁ=  2007-04-24 07:51:28  No: 136183

ご指導ありがとうございます。画面上で5mm間隔の直線を引きたいと思っていました。
私のパソコンのディスプレイの解像度は1366×768でした。
DPIの設定は、96なので、
1366÷96=14.229インチ  1インチ=2.54㎝より
14.229×2.54=約36.1㎝=約361㎜
PCの横幅は246㎜なので
5㎜×361cm/246㎜=7.33
となり私の疑問であった7.4という数字の根拠を理解しましたが(誤差は小数点以下を途中で四捨五入してしまったため)、これでよろしいでしょうか?

最後に大変申し訳ありませんが、もう1つ質問があります。
今回は、PC画面上で5㎝間隔の直線を引きました。
もし、これが1㎝間隔、1㎜間隔と限界まで間隔を狭く線を引こうとしたときは、ピクセル単位と㎜単位のどちらが向いているかということです。

私の考えでは、コード①のピクセル単位のコードでは間隔が28
コード③の㎜単位のコードでは間隔が7.4
単純に数字の大きさを比べるとコード①のほうが大きいのでそれだけ線と
線の間隔を細かく設定できる。したがって、コード①の書き方のほうが
より細かい間隔で直線が引けるのではないかと考えますが、いかがでしょうか?貴重なご指導を重ねて宜しくお願い申しあげます。


のりだぁ=  2007-04-24 07:59:11  No: 136184

訂正があります。前の文の10行目は5㎝間隔ではなく5㎜間隔の間違いでした。


大吉末吉  2007-04-24 19:27:11  No: 136185

> 私の疑問であった7.4という数字の根拠を理解しましたが(誤差は小数点以下を途中で四捨五入してしまったため)、
> これでよろしいでしょうか?

あっていると思います。

> コード①のピクセル単位のコードでは間隔が28
> コード③の㎜単位のコードでは間隔が7.4
> 単純に数字の大きさを比べるとコード①のほうが大きいので
> それだけ線と線の間隔を細かく設定できる。

数値の大きさの大小はあまり関係ないと思います。
#小数点表記なので・・・

> したがって、コード①の書き方のほうが
> より細かい間隔で直線が引けるのではないかと考えますが

「ピクセル」が、実際に描画可能な最小単位(ディスプレイの実際の点一つ)ですから、1ピクセルより小さい値を指定しても、見えませんね。
1ピクセルに満たない端数はピクセル単位で丸められますし・・・
#隣り合った点のどちらかになる

そういう意味で、ピクセルで指定可能なら、ピクセルで指定する方が正確ですね。


のりだぁ=  2007-04-24 22:16:01  No: 136186

質問にお答えして頂き誠にありがとうございました。今回の件に関しましては疑問が解決しました。重ねて御礼申し上げます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加