dcsimg
Results 1 to 6 of 6

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

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2005
    Posts
    428

    Resolved [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

  2. #2
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,240

    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

  3. #3
    Hyperactive Member
    Join Date
    Jun 2018
    Posts
    434

    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.

    Name:  a1.png
Views: 56
Size:  22.6 KB

    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)
    
        Private Sub Form3_Load_1(sender As Object, e As EventArgs) Handles MyBase.Load
            ClientSize = New Size(500, 400)
            DoubleBuffered = True
    
            PtsList.Add(New PointF(1000, 6000))
            PtsList.Add(New PointF(3000, 6000))
            PtsList.Add(New PointF(4000, 6000))
            PtsList.Add(New PointF(0, 12000))
            PtsList.Add(New PointF(0, 6000))
            PtsList.Add(New PointF(6000, 6000))
            PtsList.Add(New PointF(6000, 12000))
            PtsList.Add(New PointF(0, 12000))
            PtsList.Add(New PointF(6000, 6000))
            PtsList.Add(New PointF(6000, 12000))
            PtsList.Add(New PointF(0, 12000))
            PtsList.Add(New PointF(0, 6000))
            PtsList.Add(New PointF(6000, 5995.7))
            PtsList.Add(New PointF(0, 12000))
            PtsList.Add(New PointF(250, 6000))
            PtsList.Add(New PointF(6000, 6000))
            PtsList.Add(New PointF(6000, 12000))
            PtsList.Add(New PointF(6000, 6000))
            PtsList.Add(New PointF(6000, 12000))
            PtsList.Add(New PointF(0, 12000))
            PtsList.Add(New PointF(0, 6000))
    
            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
                DtsList.Add(False)
            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
    
            'non linked copy
            For i As Integer = 0 To PtsList.Count - 1
                FilteredPtsList.Add(PtsList(i))
            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

  4. #4

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2005
    Posts
    428

    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...
    Last edited by surya; Apr 10th, 2019 at 10:56 PM.

  5. #5

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2005
    Posts
    428

    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..

  6. #6
    Hyperactive Member
    Join Date
    Jun 2018
    Posts
    434

    Re: Getting Unique Points from List of Points

    Quote Originally Posted by surya View Post
    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!

Posting Permissions

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



Featured


Click Here to Expand Forum to Full Width