ピクチャーボックス(pctBar)
に以下のようなコードで直線を書こうとしました。
等間隔で、線をひくはずなのに実行してみると
どうみても不均等な線がひけてしまっています。
特に間隔の値を太さに近づけたときに不均衡さが
顕著になるようです。
この現象が生じる理由、回避する手段をおわかりの方が
いらっしゃいましたらご教授お願いします。
よろしくお願いします。
Private Sub cmdDraw_Click()
Dim i, 間隔, 太さ, 最大値 As Integer
間隔 = 20
太さ = 15
最大値 = 1000 / 間隔
pctBar.ScaleWidth = 1000
pctBar.ScaleHeight = 1000
pctBar.Cls
For i = 1 To 最大値
pctBar.Line (間隔 * i, 100)-(間隔 * i + 太さ, 900), , BF
Next
End Sub
誤差を小さくしたかったら、
ScaleModeをvbPixelにして、整数で座標指定して
縦横線のみを描画してください。
同じ幅でひいたはずの縦線と横線の幅が異なって見えたり、
斜め線に見えたり、ゆがんで見えるときは、
ディスプレイを調整してください。
恐らく、ScaleWidthとScaleHeightに値を代入しているからだと思います。
ScaleWidthとScaleHeightに値を入れると、例えば、pctBarが800×800ドット
だとしても、サイズが1000×1000になってしまいます。
画面に表示するときの最小単位はドットですので、実際の座標は
Int(800/(間隔 * i))となり誤差が生じるので不均等になります。
> pctBar.ScaleWidth = 1000
> pctBar.ScaleHeight = 1000
じゃなくて
pctBar.Width = 1000 + pctBar.Width - pctBar.ScaleWidth
pctBar.Height = 1000 + pctBar.Height - pctBar.ScaleHeight
とすれば、うまくいくと思います。
すばやいお返事ありがとうございます。質問者です。
LESIAさんのご回答をみてなるほどと思い
どれだけの誤差が生じるか確かめてみました。
テストしたピクチャーボックスのピクセルサイズ(x方向)は6735だったので、
int(6735*間隔 / 1000) とint((6735*間隔 +太さ) / 1000)の
(実ピクセルへの変換式はこうですよね?)
差をとってみたのですが、線の間隔に対しては誤差3%程度、線の太さにいたっては1%もありませんでした。
実際に画面に出ている差はそれどころではないので、別の原因があると
思うのですが、他に考えられないでしょうか?
また、pctBar.Width = はピクチャーボックスの幅自体が変わってしまうので
できれば避けたいです。
Sayさんのディスプレイの調節に関しては、ピクチャーボックスが画面上の
どこにある場合も結果はかわらないので、大丈夫だと思います。
ScaleModeをピクセルにしても同じ結果が生じてしまいます。
もしここまでの情報でなにかわかる方いらっしゃいましたら
どうかよろしくお願いいたします。
画面上で表示できる最小単位は1Pixelです。
VBの標準単位TwipはWindowsの画面プロパティーで変更がなければ、
1Pixelあたり15Twipです。(Screen.TwipsPerPixelX、TwipsPerPixelY)
座標(0, 0)と座標(14, 14)は同一Pixelです。
20Twip=1.3333333333333....Pixel
Twip=Pixel*TwipsPerPixel?
Pixel=Twip/TwipPerPixel?
# この辺の事はVBでグラフィックを書く人には基本知識だと思うけど?
# 入門書に書いてないのかな?
“座標(0, 0)と座標(14, 14)は同一Pixelです”
はちょっと違う.座標の受け口は大概 Sigle で,TwipsPerPixel? が15 なら,丸められて,(14, 14) は (15, 15) になってしまうだろう.
“座標(0, 0)と座標(7, 7)は同一Pixelです”
のほうがいい.
“基本知識だと思うけど?”,“入門書に書いてないのかな?” は言わずもがなか….
訂正: Sigle -> Single です.すみません.
そんな誤差が出る面倒な計算しなくても、
均等に線を引くだけならこれだけでいいんじゃないの?
Private Sub cmdDraw_Click()
Dim i As Single, 間隔 As Single, 太さ As Single
間隔 = 10
太さ = 5
pctBar.Cls
pctBar.ScaleMode = vbPixels
For i = 0 To pctBar.ScaleWidth Step 間隔
pctBar.Line (i, 0)-(i + 太さ, pctBar.ScaleHeight), , BF
Next
End Sub
>Dim i, 間隔, 太さ, 最大値 As Integer
それと、
この変数の宣言の仕方だと最大値以外は全部Variantになるよ
質問者です。
みなさま、ありがとうございました。
普段VBでは組まないのに、都合でVBを使わざるをえなくなりまして・・・
おかげさまでよくわかりました。Twipsなんてあるんですね。
特にbatchmanさん、ありがとうございます。
>この変数の宣言の仕方だと最大値以外は全部Variantになるよ
これも知りませんでした!
どうも、ありがとうございました。
入門書も参考書もまったく手元にない状態なので助かりました。
おかげさまで作りたかったプログラムが完成しました。
ツイート | ![]() |