none
pictureBoxにグラフを描画する方法 RRS feed

  • 質問

  • VB.netでpictureBoxに複数のグラフを描画したいのですが、

    pictureBoxは左上が原点ですよね。

    そのために、普通のX-Yのグラフを書くためには、座標の変換が

    必要になると思いますが、一つ描くくらいならそれでも出来ますが、

    一つのpictureBoxに複数のグラフを書きたいので、座標変換

    が沢山出てくるので、ソースコードがとても見づらくなってしまいました。

    こういう場合に、何かお勧めの方法はありますか?よろしく。

    2007年3月2日 12:35

すべての返信

  • 私の方法がよいかどうかは知りませんが、

    原点とX軸ベクトルY軸ベクトルを設定してそれから計算するメソッドを作ってやってます。

    Origin.X=0

    Origin.Y=Picture1.Height-1

    VectorX.X=1

    VectorX.Y=0

    VectorY.X=0

    VectorY.Y=-1

    Private Function ConvertPoint(byval srcP as Point) as desP as Point

      省略

    End Function

     

    srcP.X=10、srcP.Y=10のとき、desP.X=10,desp.Y=Picture1.Height-11を返す。

    ここから編集モード
    直書きしたのでas desP as pointなんて変なこと書いてるし。すみません。

    2007年3月2日 13:09
  • GraphicsクラスのTranslateTransform、ScaleTransformメソッドについて調べてみてください。例えば、フォーム上にPictureBox1、Button1、Button2が貼り付けてあるとして、以下のような感じで座標を原点に移動できます。サンプルソースはVB2005で書いてます。

    Public Class Form1
        Private g As Graphics
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            PictureBox1.Image = New Bitmap(PictureBox1.Width, PictureBox1.Height)
            g = Graphics.FromImage(PictureBox1.Image)
            g.Clear(Color.White)
            g.TranslateTransform(PictureBox1.Width \ 2, PictureBox1.Height \ 2)
            g.ScaleTransform(1, -1)
        End Sub

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            g.DrawLine(Pens.Blue, 0, 0, 100, 100)
            PictureBox1.Refresh()
        End Sub

        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            g.DrawLine(Pens.Red, 0, 0, -100, -100)
            PictureBox1.Refresh()
        End Sub
    End Class

     

    2007年3月2日 13:14
  • サンプルありがとうございました。

    TranslateTransformやScaleTransformを使うと、座標変換部分がほとんど必要なくなり、

    かなりいい感じでグラフを書くことができるような気がします。

    でも、もう一つ教えてください。例えば、width=100, height=100のpictureBoxに

    x=0 ~ 1.0

    y=0 ~ 1.0

    のような座標系を取りたいのですが、TranslateTransformやScaleTransformを使うと座標系の設定は

    できると思いますが、最終的に描画を行うDrawLine、FillRectangleなどの関数は、引数が整数値だと思います

    ので、0~1.0みたいな座標系を定義しても、そこに描画する方法が思いつかないのですが

    何か良い方法はありますか?よろしくお願いします。

     

    2007年3月2日 15:30
  • 一晩考えたのですが、よくわかりません。

    結局、みなさん、VBやVCで複雑な数学のグラフや2Dの等高線などを表示する場合、

    どういう方式でやられているんでしょうか?

    描画領域(pictureBox)の任意の場所に自分でローカルな座標系を設定できるような

    方法があればベストなのですが、どうすれば可能でしょうか?

    DirectXとかOpenGLなどを使われているんでしょうか?

    アドバイス、よろしくおねがいします。

    2007年3月3日 2:55
  • 昔のCADで言う所のWindowとViewportの関係ですが、それはともかく、ユーザー座標からPicturebox座標への変換は簡単です。 見づらいですが、横並びで書きます。 ユーザー座標とユーザー座標系サイズを ux, uy, usizx, usizy とします。 同じくPictureboxについても Px, Py, Psizx, Psizy とします。 Pictureboxの座標は単なる比例計算で Px = Psizx / usizx * ux  Py = Psizy / usizy * uy となります。 Y軸を下から上にしたい場合はその後 Py = Psizy - Py とします。 (この場合、TranslateTransformやScaleTransformは使いません、使うと分かり難くなるので。) この Px, Py で線を引けばOKです。  なお計算は全て実数する必要があります。  必要あれば計算後に整数化します。 作図用の関数かSubを定義しても良いでしょう。 (やり方は他にも色々あるでしょう。)
    2007年3月3日 8:33
  • 結局、
    よねKEN さんに教えていただいた
    g.TranslateTransform
    g.ScaleTransform
    の方法でPictureBoxの原点を左下にしてわかりやすくしておいて、
    そのpictureBoxに対して葉流奈津さんに教えていただいた方法で
    pictureBox座標からユーザー座標に座標変換するというミックス方式で
    やることにしました。

    ありがとうございました。


     

    2007年3月4日 4:11
  • 補足です。

    g.TranslateTransform
    g.ScaleTransform

    を使って左下を原点に設定したら、drawStringで描いた文字が上下逆転してしまいました。

    というわけで、結局、Transformは中止して、葉流奈津さんのアドバイスに従ってやってみます。

     

    2007年3月4日 17:18