グラフィックスで点を描画する方法

タグの編集
投稿者 マルちゃん  (社会人) 投稿日時 2011/5/30 21:25:59
Visual Basic 2008を使っています。

例えば二次関数のグラフを描く場合、DrawLineを使わずに点で描く方法を教えてください。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2011/5/30 22:04:34
数学的には、点というのものは大きさという概念を持ちません。

ゆえに描画される点というのは、実際には「直径1ドット以上の円」や
「線分の長さが1ドットの線」「縦横 1ドットの矩形」んどで置き換えられる事が多いです。

円の描画なら DrawEllipse / FillEllipse
線分の描画なら DrawLine
矩形の描画なら DrawRectangle / FillRectangle
http://bbs.wankuma.com/index.cgi?mode=al2&namber=15900&KLOG=32

あるいは、描画先が Bitmap である場合には、Bitmap.SetPixel メソッドを用いることもできます。
ただし SetPixel は比較的低速な処理ですので、下記のように直接操作する事もあります。
http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=9445
投稿者 shu  (社会人) 投稿日時 2011/5/30 22:07:42
Graphicsへの描画を対象とした場合、
点というのは半径0の円とか0×0の四角とかになるので
描画することが出来ません。なので
Graphics.FillRectangle で両方の辺を短めにした四角を描くか
Graphics.FillEllipse で半径の小さい円を描くことになります。

Bitmapを使用した場合、Pixcel単位の操作が可能なので
Bitmap.SetPixelを使用すれば点を書くことが出来ます。
点の数が多い場合はLockBitsをして配列に転送して
配列の書き換えをしてUnLockBitsする方法が処理が速いです。
http://msdn.microsoft.com/ja-jp/library/5ey6h79d(v=vs.80).aspx
を参照のこと
投稿者 shu  (社会人) 投稿日時 2011/5/30 22:09:13
魔界の仮面弁士さんと被ってしまいましたmm
投稿者 マルちゃん  (社会人) 投稿日時 2011/5/31 21:46:36
 shuさんありがとうございました。
URLを試しましたがエラーがでてうまくいきませんでした。

VB2008を使い出して日が浅いのですが、いつかはマンデルブロ集合を描きたいと思っています。
PsetPixelの使い方を具体的に教えてください。
投稿者 マルちゃん  (社会人) 投稿日時 2011/5/31 22:02:24
魔界の仮面弁士さんありがとうございました。

Jitta on the way さんのプログラムを試したのですがうまくいきませんでした。
もう一つのURLの方はうまくできました。

いつかはマンデルブロ集合を描きたいと思っています。
点群描画の方法を教えてください。

VB2008に慣れていないので、できれば具体的にお願いします。
投稿者 るきお  (社会人) 投稿日時 2011/5/31 22:26:35
こんにちは。

とりあえず、点を描く具体的なサンプルです。

    
Public Class Form1

    Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint

        '背景を黒にする 
        e.Graphics.Clear(Color.Black)

        '座標(20, 30)に赤い点を描画 
        e.Graphics.FillRectangle(Brushes.Red, 20, 30, 1, 1)

        '座標(25, 40)に赤い点を描画 
        e.Graphics.FillRectangle(Brushes.Red, 25, 40, 1, 1)

        '座標(30, 50)に赤い点を描画 
        e.Graphics.FillRectangle(Brushes.Red, 30, 50, 1, 1)

        '座標(35, 60)に赤い点を描画 
        e.Graphics.FillRectangle(Brushes.Red, 35, 60, 1, 1)

        '座標(40, 70)に赤い点を描画 
        e.Graphics.FillRectangle(Brushes.Red, 40, 70, 1, 1)

        '座標(45, 80)に赤い点を描画 
        e.Graphics.FillRectangle(Brushes.Red, 45, 80, 1, 1)

    End Sub

End Class


>VB2008に慣れていないので、できれば具体的にお願いします。
知りたいことがよくわからないです。
VBでの描画の手法を知りたくて、それを使って自分でマンデルブロ集合を描画したいのでしょうか?
それとも、VBの手法はどうでもよくマンデルブロ集合を描画するプログラムをずばり知りたいのでしょうか?

>VB2008に慣れていないので、できれば具体的にお願いします。
と書かれているので、後者かなと思いました。
であれば、ずばり知りたいことを聞いた方がよいですよ。


前者なら、
>URLを試しましたがエラーがでてうまくいきませんでした。

>Jitta on the way さんのプログラムを試したのですがうまくいきませんでした。

>もう一つのURLの方はうまくできました。

>VB2008に慣れていないので、できれば具体的にお願いします。

これらから学ぶ意図がくみ取れないのでやはりこの問答を通して何が知りたいのかわからないです。
投稿者 るきお  (社会人) 投稿日時 2011/5/31 23:01:54
中学校の数学ででてくるような2次関数を描画する例も載せておきます。

魔界の仮面弁士さんとshuさんがおっしゃっている理屈により、線をなす関数のグラフ「点」ではなく「線」で描画するのが良いです。
この例も線で描画しています。
コンピューターのディスプレイはデジタルなので、アナログなものを表示する場合はどうしても無理が発生するのです。
どのような無理が発生しているかは、コメントとして埋め込んだ「点」での描画を試させるとわかります。


Public Class Form1

    Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint

        '背景を黒にする 
        e.Graphics.Clear(Color.Black)

        '学校数学の座標系に変換。(さらに、横方向を8倍に拡大。このくらいしないと2次関数がとんがりすぎる) 
        e.Graphics.MultiplyTransform(New Drawing2D.Matrix(8, 0, 0, -1, Me.ClientRectangle.Width \ 2, Me.ClientRectangle.Height \ 2))


        '▼座標系のX軸とY軸の描画 
        'X軸 
        e.Graphics.DrawLine(Pens.DarkGray, 0, Me.ClientRectangle.Height, 0, -Me.ClientRectangle.Height)
        'Y軸 
        e.Graphics.DrawLine(Pens.DarkGray, Me.ClientRectangle.Width, 0, -Me.ClientRectangle.Width, 0)

        '▼ y = x ^ 2 の関数の点を計算 
        Dim points() As Point
        ReDim points(Me.ClientRectangle.Width)

        For i = 0 To Me.ClientRectangle.Width
            Dim x As Integer
            Dim y As Integer

            x = i - (Me.ClientRectangle.Width \ 2)
            y = x ^ 2
            points(i) = New Point(x, y)

            'あくまで「点」で描画するなら、この下の行のコメントをはずし、DrawLinesの行をコメントにする。 
            'e.Graphics.FillRectangle(Brushes.Red, x, y, 1, 1) 
        Next

        '▼点を線で結ぶ 
        e.Graphics.DrawLines(Pens.Blue, points)

    End Sub

    Private Sub Form1_Resize(sender As System.Object, e As System.EventArgs) Handles MyBase.Resize

        Me.Invalidate()

    End Sub
End Class
投稿者 マル  (社会人) 投稿日時 2011/6/1 20:19:18
るきお さん
ありがとうございました。

このような動作をするんだなと分かりました。
自分なりに応用できるようにがんばります。