前提・実現したいこと
お世話になっております。
VB.netで座標データを格納したcsvファイルのデータ数を平均化して削減したいと考えています。
csvファイルにはX座標、Y座標、Z座標が入っており、値はバラバラです。
この座標データに任意の大きさの格子点(X,Y)を設定し、Z値はその平均値を採用したいです。
下の図がイメージ画像になります。
現在、格子点(X,Y)を設定までは出来ているのですが
各Zの値をどのように与えてあげたら、格子内のZの値や個数が明らかとなるのか分かっていません。
説明がわかりづらくて申し訳ありませんが、ヒントでもよろしいので教えていただけたら幸いです。
発生している問題
格子内のZ値の取り方
該当のソースコード
VB.net
1Public Class Form1 2 3 '構造体の定義(点群データ) 4 Public Structure PointData 5 Dim Xpoint As Double 'X座標 6 Dim Ypoint As Double 'Y座標 7 Dim Zpoint As Double 'Z座標 8 End Structure 9 10 '構造体の定義(グリッドデータ) 11 Public Structure NewPointData 12 Dim NewXpoint As Double 'X座標 13 Dim NewYpoint As Double 'Y座標 14 Dim NewZpoint As Double 'Z座標 15 End Structure 16 17 'メンバ変数 18 Dim PD() As PointData '配列 19 Dim NewPD() As NewPointData '新しい配列 20 Dim PDCount As Double 'データの要素数 21 Dim GridSelect As Double 'グリッドの間隔 22 Dim X_Min As Double = Double.MaxValue 'X座標の最小値 23 Dim Y_Min As Double = Double.MaxValue 'Y座標の最小値 24 Dim X_Max As Double = Double.MinValue 'X座標の最大値 25 Dim Y_Max As Double = Double.MinValue 'Y座標の最大値 26 Dim Xi As Double 'Xのデータの個数 27 Dim Yi As Double 'Yのデータの個数 28 Dim GridX() As Double 'グリッドデータ化したX座標 29 Dim GridY() As Double 'グリッドデータ化したY座標 30 Dim GridZ() As Double 'グリッドデータ化したZ座標 31 Dim Grid(,) As Double '2次元配列 32 Dim sum As Double = 0 'Z座標の合計 33 Dim average As Double 'Z座標の平均 34 Dim SD As Double 'Z座標の標準偏差 35 36 'フォームの初期化 37 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 38 'TextBoxの設定 39 OpenFileText.Enabled = False 40 SaveFileText.Enabled = False 41 TotalDataText.Enabled = False 42 XminText.Enabled = False 43 YminText.Enabled = False 44 XmaxText.Enabled = False 45 YmaxText.Enabled = False 46 End Sub 47 48 'グリッド間隔の設定 (5桁まで入力可能) 49 Private Sub GridSelectText_KeyPress(ByVal sender As System.Object, ByVal e As KeyPressEventArgs) _ 50 Handles GridSelectText.KeyPress 51 If (e.KeyChar < "0"c Or e.KeyChar > "9"c) _ 52 And e.KeyChar <> vbBack And e.KeyChar <> "." Then 53 e.Handled = True 54 End If 55 End Sub 56 57 'アプリケーションの終了 58 Private Sub ExitButton_Click(sender As Object, e As EventArgs) Handles ExitButton.Click 59 Application.Exit() 60 End Sub 61 62 'ファイルを開く 63 Private Sub OpenButton_Click(sender As Object, e As EventArgs) Handles OpenButton.Click 64 With OpenFileDialog1 65 '選択ダイアログを開く 66 .Title = "点群ファイルの読み込み" 67 .FileName = "" 68 .Filter = "点群ファイル(*.csv)|*.csv|すべてのファイル(*.*)|*.*" 69 .DefaultExt = ".csv" 70 71 'ファイル名の表示 72 Dim result As DialogResult 73 result = OpenFileDialog1.ShowDialog 74 If result = Windows.Forms.DialogResult.OK Then 75 OpenFileText.Text = .FileName 76 MessageBox.Show(.FileName & "を読み込みました。", My.Application.Info.Title, MessageBoxButtons.OK, MessageBoxIcon.Warning) 77 78 'ファイルの読み込み 79 Try 80 Dim ReadItems() As String 'CSVの各項目を表す配列 81 82 'ファイルを開く。 83 Dim sr As New IO.StreamReader(.FileName, System.Text.Encoding.GetEncoding("Shift-JIS")) 84 85 'ファイルの最後までループ 86 Do Until sr.Peek() = -1 87 ReDim Preserve PD(PDCount) 88 ReadItems = Split(sr.ReadLine(), ",") 89 90 PD(PDCount).Xpoint = CDbl(ReadItems(0)) 91 PD(PDCount).Ypoint = CDbl(ReadItems(1)) 92 PD(PDCount).Zpoint = CDbl(ReadItems(2)) 93 94 'データ確認 95 Console.WriteLine(PD(PDCount).Xpoint & vbTab & PD(PDCount).Ypoint & vbTab & PD(PDCount).Zpoint) 96 PDCount += 1 97 Loop 98 99 Catch ex As Exception 100 MessageBox.Show(ex.Message) 101 End Try 102 103 Else 104 MessageBox.Show(.FileName & "ファイルの読み込みに失敗しました。", 105 My.Application.Info.Title, MessageBoxButtons.OK, MessageBoxIcon.Warning) 106 End If 107 End With 108 End Sub 109 110 'データ確認 111 Private Sub CheckButton_Click(sender As Object, e As EventArgs) Handles CheckButton.Click 112 Try 113 'データの総数 114 TotalDataText.Text = PDCount 115 116 '最小値確認 117 'X座標の最小値 118 For i As Integer = 0 To PDCount - 1 119 If X_Min > PD(i).Xpoint Then 120 X_Min = PD(i).Xpoint 121 End If 122 Next 123 124 'Y座標の最小値 125 For j As Integer = 0 To PDCount - 1 126 If Y_Min > PD(j).Ypoint Then 127 Y_Min = PD(j).Ypoint 128 End If 129 Next 130 XminText.Text = X_Min 131 YminText.Text = Y_Min 132 133 '最大値確認 134 'X座標の最大値 135 For i As Integer = 0 To PDCount - 1 136 If X_Max < PD(i).Xpoint Then 137 X_Max = PD(i).Xpoint 138 End If 139 Next 140 141 'Y座標の最大値 142 For j As Integer = 0 To PDCount - 1 143 If Y_Max < PD(j).Ypoint Then 144 Y_Max = PD(j).Ypoint 145 End If 146 Next 147 XmaxText.Text = X_Max 148 YmaxText.Text = Y_Max 149 150 Catch ex As Exception 151 MessageBox.Show("ファイルを読み込んでください。") 152 End Try 153 End Sub 154 155 '配列処理 156 Private Sub GridButton_Click(sender As Object, e As EventArgs) Handles GridButton.Click 157 Try 158 GridSelect = CDbl(GridSelectText.Text) 159 Xi = ((X_Max - X_Min) / GridSelect) 160 Yi = ((Y_Max - Y_Min) / GridSelect) 161 162 ReDim GridX(Xi) 163 ReDim GridY(Yi) 164 ReDim Grid(Xi, Yi) 165 '格子点の設定 166 For i As Integer = 0 To Xi 167 For j As Integer = 0 To Yi 168 GridX(i) = X_Min + GridSelect * i 169 GridY(j) = Y_Min + GridSelect * j 170 Grid(i, j) = "" 171 Console.WriteLine(GridX(i) & "," & GridY(j)) 172 Next 173 Next 174 Catch ex As Exception 175 MessageBox.Show("グリッド間隔を設定して下さい。") 176 End Try 177 End Sub
試したこと
Z値の計算方法については確認済みです。
Private Sub GridPointButton_Click(sender As Object, e As EventArgs) Handles GridPointButton.Click
Dim MeshZ(PDCount - 1) As Double
For i As Integer = 0 To UBound(MeshZ)
sum += MeshZ(i)
Next
average = sum / MeshZ.Length
End sub
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
回答2件
あなたの回答
tips
プレビュー