none
New Pointにおける座標配列について・・・。 RRS feed

  • 質問

  • まず 任意の座標361個を作成して直線で連続して結んで閉領域を確保しました。この内部を赤で塗りつぶしたいのです

    (私の場合、たまたま形を円にしましたが、ほかの場合の複雑な図形においてでも)

    私が皆さんに教えてもらいたい問題の内容はNew Point(x,y)の配列を手作業で361個も作成出来ないということです。

    簡単にするにはどうすればいいのでしょうか?ご教授ください。下に一応ソースコードをのせておきます。問題なのは上から13行目の部分です。

    最終的にはどうしてもFillPlygonで内部を塗りつぶしたいのですが、どうしたものやら・・・。どうか何とぞお願いします。

    01 Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        
    02      Dim g As Graphics
    03      g = e.Graphics
    04      g.Clear(Color.White)

    05      Dim x(360) As Integer
    06      Dim y(360) As Integer

    07      For th = 0 To 360 Step 1
    08           x(th) = 150 * Math.Cos(3.14159265358979 / 180 * th)+400
    09           y(th) = 150 * Math.Sin(3.14159265358979 / 180 * th)+400
    10      Next th


    11      Dim myPointArray as Point()
    12      For k=0 To 360 Step 1   
    13           myPointArray = {New Point (CInt(x(k)),CInt(y(k)))}
    14      Next k

    15      g.FillPolygon(Brushes.Red, myPointArray)

    16 End Sub

    2012年4月14日 13:10

回答

  •  System.Array.Resize(myPointArray, pts.Count)のところで

      myPointArrayの下に波線が出て、これ以上前に進めません。 どう改めたらいいでしょうか?

    進めませんって…、「警告」と「エラー」の違いを認識してください。
    「警告」はコード上の問題と思われる箇所を指摘してくれる機能であり、実行自体はできます。「エラー」はコンパイルできないようなコード上の誤りがあるので要修正です。
    まあ、警告であることと、動くコードなので無視できるんですが、警告が出ないようなコードの書き方を目指したいですね。

    • ArrayList を使わずに List(Of T) を使うべし。今回の場合、T は Point なので List(Of Point)、Dim pts As New List(Of Point)。
    • List(Of T) は ToArray メソッドを持っているので、配列をとりたいのであればそれを使うべし。myPointArray = pts.ToArray() みたいに。
    • そもそも、myPointArray(361) と作っておいて、それに (0), (1), (2) という順に代入していけば、ArrayList/List いらなかったんです。
    • この機会にヘルプなり、MSDN なり読む癖をつけておいてください。

    ちなみに、私のこのスレッドの投稿の中で空白が目立つ箇所があったかと思いますが、あの部分をドラッグして選択してみてください。配列でのサンプルが書いてあったはずです。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。

    2012年4月15日 9:05
    モデレータ
  • しかしmyPointArray(361)とする方法は、私にとって使用範囲ではないのです。なんだか未知の世界のように思えました。要するに使い慣れてないということです。

    上の方に白文字で書いてあった、以下のコードが使用範囲ではない、よくわからないということであれば、もう少し勉強しておいてください。

    Dim myPointArray(360) As Point
     For k = 0 To 360 Step 1
     myPointArray(k) = New Point(CInt(x(k)), CInt(y(k)))
    Next k
    ※「•配列ではない 1 つの Point 変数に座標を入れるためにはどのように書けばよいのか。」の下に書いてある。

    なお、MVP は肩書きとか称号とかそういったものなので、名前の一部ととらえないでくださいね。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。

    2012年4月15日 10:45
    モデレータ

すべての返信

  • 何がわからないのか、よくわかりません。

    x や y と同じように Point を配列にして、ループ内で代入していったらよいだけでは?
    13 行目は 1 個の Point で配列を作って代入しているのかな?

    配列への代入は 8 行目と 9 行目をまねして書けば済む話でしょう。
    それがわからないとなると、何か変な誤解をされているか、コードの内容を理解できていないかでしょうか…。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。

    2012年4月14日 13:17
    モデレータ
  • AzuleanMVPさま「それがわからないとなると、何か変な誤解をされているか、コードの内容を理解できていないかでしょうか…。」 ええ。その通りです

    だから模範となるコードを直に記述していただきたいのです。

    2012年4月14日 13:39
  • AzuleanMVPさま「それがわからないとなると、何か変な誤解をされているか、コードの内容を理解できていないかでしょうか…。」 ええ。その通りです

    だから模範となるコードを直に記述していただきたいのです。

    「何か変な誤解をされている」 or 「コードの内容を理解できていない」のいずれかだとして、「模範となるコードを記述していただきたい」となるのはどういったことでしょうか。コードを記述すれば、どうなるのでしょうか?

    コードを書くこと、提示することは、かんたんです。
    しかし、答えを求めるだけでは開発者になんてなれませんし、その人のためにならないと私は思っています。
    答えを求めているわけではない、あるいは質問者自身やスレッドを見に来た第三者のためになると私が思えれば、喜んで提供します。(ここでいう「ためになる」は、課題を解決するだけのこと、製品を完成させるためだけのことを除外します)

    たぶん、以下の事柄を理解できれば、あとは応用だけのはずなんですが。

    • 配列に順番に入れていくためにはどうすればよいのか。(8 行目と 9 行目が何をしているのか)
    • 配列ではない 1 つの Point 変数に座標を入れるためにはどのように書けばよいのか。

    Dim myPointArray(360) As Point
    For k = 0 To 360 Step 1
    myPointArray(k) = New Point(CInt(x(k)), CInt(y(k)))
    Next k

    ※この投稿において、X 座標と Y 座標はあらかじめ計算されて配列に格納されていることを前提とでき、最終成果として Point の配列がほしいものと要求を解釈したものです。この前提のとらえ違いがある場合、上述のヒントは役に立たない恐れがあります。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。

    2012年4月14日 14:28
    モデレータ
  • >配列ではない 1 つの Point 変数に座標を入れるためにはどのように書けばよいのか。

    この方法がわからないんです。


    上述のコードだとエラーが出て前に進めないんです。
    2012年4月15日 6:03
  • 要は

    12      For k=0 To 360 Step 1   
    13           myPointArray = (何らかのステートメント){New Point (CInt(x(k)),CInt(y(k)))}
    14      Next k

    などとすることでmyPointArrayに361個の(x,y)を自動的に読み込ませたいのです。

    2012年4月15日 7:49
  • >配列ではない 1 つの Point 変数に座標を入れるためにはどのように書けばよいのか。

    この方法がわからないんです。

    それを最初から書いてください。
    コードのサンプルを書いてほしいという広い範囲で要求するのではなく、本当にほしい部分だけを質問すべきです。
    そうでないと、回答しようと思った人に余計な負担を負わせますよ。

    こういうときは「New Point VB.NET」といった形で検索してみれば、いくつか見つかります。
    もちろん、目的のことに合わないページもあるとは思いますが、内容を少し読んだり、試したりすれば合う・合わないは判断できるかと思います。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。

    2012年4月15日 8:01
    モデレータ
  • 行き違いになっていました。

    要は

    12      For k=0 To 360 Step 1   
    13           myPointArray = (何らかのステートメント){New Point (CInt(x(k)),CInt(y(k)))}
    14      Next k

    などとすることでmyPointArrayに361個の(x,y)を自動的に読み込ませたいのです。

    とりあえず、いくつか指摘しておきます。

    1. { } は配列を作るための書き方です。それの戻り値は配列になります。
    2. For の中で毎回 1 個の要素しかない配列を作って、myPointArray に入れていたら、361 個になることはありません。
    3. 8 行目や 9 行目と比べたとき、= の左の書き方に違和感を覚えませんか?

    考え方としては、361 個の配列(箱)を用意して、それぞれの箱に代入することです。
    この事例において、For の中で { } は使わないことです。

    // 私の一つ前の投稿と、この投稿の「3」を組み合わせれば書けるんじゃないかなぁと期待しています。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。

    2012年4月15日 8:34
    モデレータ
  • コードを次のように書き改めました。

     Dim g As Graphics
            g = e.Graphics
            g.Clear(Color.White)

            Dim x(361) As Integer
            Dim y(361) As Integer

            For th = 0 To 360 Step 1
                x(th) = 150 * Math.Cos(3.14159265358979 / 180 * th) + 400
                y(th) = 150 * Math.Sin(3.14159265358979 / 180 * th) + 400
            Next th

            Dim pts As New ArrayList()
            Dim myPointArray As Point()

            For k = 0 To 360 Step 1
                pts.Add(New Point(CInt(x(k)), CInt(y(k))))
            Next k

            System.Array.Resize(myPointArray, pts.Count)
            pts.CopyTo(myPointArray)

            g.FillPolygon(Brushes.Red, myPointArray)

    しかしまたもやエラーが出てしまいました

     System.Array.Resize(myPointArray, pts.Count)のところで

      myPointArrayの下に波線が出て、これ以上前に進めません。 どう改めたらいいでしょうか?

    2012年4月15日 8:50
  •  System.Array.Resize(myPointArray, pts.Count)のところで

      myPointArrayの下に波線が出て、これ以上前に進めません。 どう改めたらいいでしょうか?

    進めませんって…、「警告」と「エラー」の違いを認識してください。
    「警告」はコード上の問題と思われる箇所を指摘してくれる機能であり、実行自体はできます。「エラー」はコンパイルできないようなコード上の誤りがあるので要修正です。
    まあ、警告であることと、動くコードなので無視できるんですが、警告が出ないようなコードの書き方を目指したいですね。

    • ArrayList を使わずに List(Of T) を使うべし。今回の場合、T は Point なので List(Of Point)、Dim pts As New List(Of Point)。
    • List(Of T) は ToArray メソッドを持っているので、配列をとりたいのであればそれを使うべし。myPointArray = pts.ToArray() みたいに。
    • そもそも、myPointArray(361) と作っておいて、それに (0), (1), (2) という順に代入していけば、ArrayList/List いらなかったんです。
    • この機会にヘルプなり、MSDN なり読む癖をつけておいてください。

    ちなみに、私のこのスレッドの投稿の中で空白が目立つ箇所があったかと思いますが、あの部分をドラッグして選択してみてください。配列でのサンプルが書いてあったはずです。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。

    2012年4月15日 9:05
    モデレータ
  • Azulean(MVP)さま、コードを次のように改めたところ、すべてうまくいきました。

    お恥ずかしい話ですが、私はList(Of T)の存在や働きを知らなかったんです。

    Azulean(MVP)さま、おかげでコード記述で波線もでないようになり、ほんとうによかったです。どうもありがとうございました。

    しかしmyPointArray(361)とする方法は、私にとって使用範囲ではないのです。なんだか未知の世界のように思えました。要するに使い慣れてないということです。

    まあ何はともあれ ほんとうにありがとうございました。成功したコードを下にのせておきますね。

    Dim g As Graphics
            g = e.Graphics
            g.Clear(Color.White)

            Dim x(361) As Integer
            Dim y(361) As Integer
            For th = 0 To 360 Step 1
                x(th) = 150 * Math.Cos(3.14159265358979 / 180 * th) + 250
                y(th) = 150 * Math.Sin(3.14159265358979 / 180 * th) + 250
            Next th

            Dim pts As New List(Of Point)
            Dim myPointArray As Point()

            For k = 0 To 360 Step 1
                pts.Add(New Point(CInt(x(k)), CInt(y(k))))
            Next k

            myPointArray = pts.ToArray()

            g.FillPolygon(Brushes.Red, myPointArray)

    2012年4月15日 9:31
  • しかしmyPointArray(361)とする方法は、私にとって使用範囲ではないのです。なんだか未知の世界のように思えました。要するに使い慣れてないということです。

    上の方に白文字で書いてあった、以下のコードが使用範囲ではない、よくわからないということであれば、もう少し勉強しておいてください。

    Dim myPointArray(360) As Point
     For k = 0 To 360 Step 1
     myPointArray(k) = New Point(CInt(x(k)), CInt(y(k)))
    Next k
    ※「•配列ではない 1 つの Point 変数に座標を入れるためにはどのように書けばよいのか。」の下に書いてある。

    なお、MVP は肩書きとか称号とかそういったものなので、名前の一部ととらえないでくださいね。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。

    2012年4月15日 10:45
    モデレータ
  • Azuleanさま、さっきご教授いただいたように

    myPointArray(360)を使ったコードに書き改めました。   ↓

     Dim g As Graphics
            g = e.Graphics
            g.Clear(Color.White)

            Dim x(360) As Integer
            Dim y(360) As Integer
            For th = 0 To 360 Step 1
                x(th) = 150 * Math.Cos(3.14159265358979 / 180 * th) + 250
                y(th) = 150 * Math.Sin(3.14159265358979 / 180 * th) + 250
            Next th


            Dim myPointArray(360) As Point

            For k = 0 To 360 Step 1
                myPointArray(k) = New Point(CInt(x(k)), CInt(y(k)))
            Next k

            g.FillPolygon(Brushes.Red, myPointArray)

    驚きました。

    g.FillPolygon(Brushes.Red, myPointArray)のところで

    myPointArrayのうしろに何もつけたさなくて、それでうまくいくんですね。

    いやーびっくりです。

    いい勉強になりました。ありがとうございました。

    2012年4月15日 16:27
  • g.FillPolygon(Brushes.Red, myPointArray)のところで

    myPointArrayのうしろに何もつけたさなくて、それでうまくいくんですね。

    そのコメントは何かおかしくないですかね。
    「g.FillPolygon(Brushes.Red, myPointArray)」のところは元の質問から何も変わっていませんよ?(元の質問も途中の ArrayList/List を使ったコードも同じ)

    元の質問とそのコード、どのように違い、どのような意味があるのか、きちんと説明できるようになってください。
    意味をきちんと理解できないで終わってしまうと、開発者としての成長になりません。(本当の意味で勉強になっていない)


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。

    2012年4月15日 22:12
    モデレータ