# Thread: [RESOLVED] Getting Unique Points from List of Points

1. ## [RESOLVED] Getting Unique Points from List of Points

Hello,

I have following points in a list ( Dim myList of List(of Point) )

SNO X Y Z
1 0 12000 6850
2 0 6000 7000
3 6000 6000 7000
4 6000 12000 7000
5 0 12000 7000
6 6000 6000 0
7 6000 12000 0
8 0 12000 0
9 0 6000 0
10 6000 5995.7 6850
11 0 12000 7000
12 250 6000 7000
13 6000 6000 7000
14 6000 12000 7000
15 6000 6000 7000
16 6000 12000 7000
17 0 12000 7000
18 0 6000 7000
I am trying to build a set of unique points, which was easily achieved by
using the following function:

Code:
`myPtList.Distinct.ToList`
Now, I want to exclude node(s) that are close to neighboring nodes by a dist (say 400m).

for example, in the point list, nodes 3 & 10 are close (150mm), so one of these nodes can be excluded from the new list.
Similarly, Node 2 & 12 are close to each other (250mm), one of these nodes also can be excluded from the new list.

Wondering if anyone can suggest an elegant solution for this problem.

many thanks  Reply With Quote

2. ## Re: Getting Unique Points from List of Points

Use nested loops... the outer loop going thru each element (except the last), and the inner loop comparing it to each of the later elements (so 16 in the outer loop would be compared to 17 and 18 in the inner loop).

If the two points are close, remove one of them. The code is easier if you always remove the later one (just loop backwards, and .RemoveAt(innerIndex) ), but it is also possible to remove the earlier one if you want (but you'll need to re-start the loops, which is trickier code and takes longer to run).

An example of "always remove the later one":
Code:
```For outerIndex as Integer = myList.Count - 2 To 0 Step - 1
For innerIndex as Integer = myList.Count - 1 To outerIndex + 1 Step - 1
If myList(innerIndex) is too close to myList(outerIndex) Then
myList.RemoveAt(innerIndex)
End If
Next
Next```  Reply With Quote

3. ## Re: Getting Unique Points from List of Points

Is this for school?

Here is an idea that uses a tolerance that you define and then filters points within the tolerance distance of another.

You can see the graphed result on the right as you adjust the tolerance using the NumericUpDown control. Its good for duplicate and close points and then as you get larger tolerance you loose more points and can see the results. The order of the points in the list eventually determines which ones get filtered first. In the right image the upper left points of the square are completely removed which may or may not be the point you wanted.

You can experiment with different methods of filtering. Code:
```Public Class Form3
Private WithEvents Nud1 As New NumericUpDown With {.Parent = Me,
.Location = New Point(300, 10), .Maximum = 10000, .Minimum = 100,
.Increment = 100, .Value = 100}
Private PtsList As New List(Of PointF)
Private DtsList As New List(Of Boolean)
Private FilteredPtsList As New List(Of PointF)

ClientSize = New Size(500, 400)
DoubleBuffered = True

Calculate()

End Sub

Private Sub Form3_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
Dim dn As Integer = PtsList.Count - FilteredPtsList.Count
e.Graphics.DrawString("Total Pts = " & PtsList.Count.ToString, Font, Brushes.Black, 10, 10)
e.Graphics.DrawString("Filtered Pts = " & FilteredPtsList.Count.ToString, Font, Brushes.Black, 10, 30)

DrawPtsList(e.Graphics, PtsList, New Rectangle(20, 60, 200, 200))
DrawPtsList(e.Graphics, FilteredPtsList, New Rectangle(260, 60, 200, 200))

End Sub

Private Sub DrawPtsList(g As Graphics, pts As List(Of PointF), rect As Rectangle)
Dim max As Single = 15000
Dim r As Single = 5 * max / rect.Width

With g
Using f As New Font("tahoma", 2 * r)

.ResetTransform()
.FillRectangle(Brushes.White, rect)
Dim sr As Single = CSng((rect.Width / max))
.TranslateTransform(rect.X, rect.Y)
.ScaleTransform(sr, sr)

Dim n As Integer

For x As Single = 0 To max Step 2000
.DrawLine(Pens.LightSkyBlue, x, 0, x, max)
.DrawLine(Pens.LightSkyBlue, 0, x, max, x)
n = CInt(x / 1000)
.DrawString(n.ToString, f, Brushes.Gray, -3 * r, x)
.DrawString(n.ToString, f, Brushes.Gray, x, -3 * r)

Next

For i As Integer = 0 To pts.Count - 1
.FillEllipse(Brushes.AntiqueWhite, pts(i).X - r, pts(i).Y - r, 2 * r, 2 * r)
.DrawEllipse(Pens.Green, pts(i).X - r, pts(i).Y - r, 2 * r, 2 * r)

.DrawString(i.ToString, f, Brushes.Red, pts(i))
Next
End Using
End With
End Sub

Private Sub Calculate()
DtsList.Clear()
FilteredPtsList.Clear()

For i As Integer = 0 To PtsList.Count - 1
Next
Dim dx, dy, dr As Double

For i As Integer = 0 To PtsList.Count - 1

For j As Integer = 0 To PtsList.Count - 1
If i <> j AndAlso Not DtsList(i) Then
dx = PtsList(i).X - PtsList(j).X
dy = PtsList(i).Y - PtsList(j).Y
dr = Math.Sqrt((dx * dx) + (dy * dy))
If dr < Nud1.Value Then
DtsList(j) = True
End If

End If
Next
Next

For i As Integer = 0 To PtsList.Count - 1
Next

For i As Integer = DtsList.Count - 1 To 0 Step -1
If DtsList(i) Then
FilteredPtsList.Remove(PtsList(i))
End If
Next

End Sub
Private Sub Nud1_ValueChanged(sender As Object, e As EventArgs) Handles Nud1.ValueChanged
Calculate()
Invalidate()
End Sub
End Class```  Reply With Quote

4. ## Re: Getting Unique Points from List of Points

Many thanks for your detailed and quick response.

Was trying to implement this logic in a CAD app.

Will revert shortly and thanks again...  Reply With Quote

5. ## Re: Getting Unique Points from List of Points

Many thanks tommytwotrain and si_the_geek for your time.
TommyTwoTrain your inputs have been quite useful..  Reply With Quote

6. ## Re: Getting Unique Points from List of Points Originally Posted by surya Many thanks tommytwotrain and si_the_geek for your time.
TommyTwoTrain your inputs have been quite useful..
You are welcome. Thanks for letting us know!  Reply With Quote

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•