tmighty
tmighty

Reputation: 11389

Lambda / LINQ to VB.NET

I have a Lambda code that I want to convert to "plain" VB.NET code.

I haven't found any tool that would convert Lambda to code, and I don't understand what this code does.

What would be a good way to understand what this code does?

Especially, I don't know what this line does:

Let p3 = uDestPoints.First(Function(p) Math.Abs(p.X - t.P3.X) < 1 AndAlso Math.Abs(p.Y - t.P3.Y) < 1)
Select New With {Key .X1 = destList.IndexOf(p1), Key .X2 = destList.IndexOf(p2), Key .X3 = destList.IndexOf(p3)}

Thank you.

Public Function GetWarps(ByVal uSourcePoints As IEnumerable(Of Point), ByVal uDestPoints As IEnumerable(Of Point), ByVal uDestTriangles As IEnumerable(Of Triangle)) As IEnumerable(Of Warp)
    ' build lists of source and destination landmark points
    Dim sourceList = uSourcePoints.ToList()
    Dim destList = uDestPoints.ToList()

    ' find all three triangle points in the list of destination landmark points
    Dim indices = From t In uDestTriangles
                  Let p1 = uDestPoints.First(Function(p) Math.Abs(p.X - t.P1.X) < 1 AndAlso Math.Abs(p.Y - t.P1.Y) < 1)
                  Let p2 = uDestPoints.First(Function(p) Math.Abs(p.X - t.P2.X) < 1 AndAlso Math.Abs(p.Y - t.P2.Y) < 1)
                  Let p3 = uDestPoints.First(Function(p) Math.Abs(p.X - t.P3.X) < 1 AndAlso Math.Abs(p.Y - t.P3.Y) < 1)
                  Select New With {Key .X1 = destList.IndexOf(p1), Key .X2 = destList.IndexOf(p2), Key .X3 = destList.IndexOf(p3)}

    ' return enumeration of warps from source to destination triangles
    Return From x In indices
           Select New Warp(New Triangle(sourceList(x.X1), sourceList(x.X2), sourceList(x.X3)), New Triangle(destList(x.X1), destList(x.X2), destList(x.X3)))
End Function

Upvotes: 1

Views: 306

Answers (1)

NetMage
NetMage

Reputation: 26907

Here is my example expansion. I created a problem specific version of First that doesn't use a lambda parameter, and modified the code to use a ValueTuple instead of an anonymous class, since you can't return anonymous classes from a Function.

I also used a List to aggregate the LINQ answers, as an actual expansion into generator functions using Yield didn't appear to me to be clarifying.

Because of these changes, this code is less efficient than the LINQ code in the generation, but more efficient in the First, so perhaps a wash?

Public Function FirstClosePoint(points As IEnumerable(Of Point), TP As Point) As Point
    For Each p In points
        If Math.Abs(p.X-TP.X) < 1 AndAlso Math.Abs(p.Y-TP.Y) < 1 Then
            Return p
        End If
    Next
    Throw New Exception("Unable to find FirstClosePoint")
End Function

Public Function GetWarps(ByVal uSourcePoints As IEnumerable(Of Point), ByVal uDestPoints As IEnumerable(Of Point), ByVal uDestTriangles As IEnumerable(Of Triangle)) As IEnumerable(Of Warp)
    ' build lists of source and destination landmark points
    Dim sourceList = uSourcePoints.ToList()
    Dim destList = uDestPoints.ToList()

    ' find all three triangle points in the list of destination landmark points
    Dim indices = New List(Of (X1 As Integer,X2 As Integer,X3 As Integer))

    For Each t In uDestTriangles
        Dim p1 = FirstClosePoint(uDestPoints, t.P1)
        Dim p2 = FirstClosePoint(uDestPoints, t.P2)
        Dim p3 = FirstClosePoint(uDestPoints, t.P3)
        indices.Add( (destList.IndexOf(p1),destList.IndexOf(p2),destList.IndexOf(p3)) )
    Next

    ' return enumeration of warps from source to destination triangles
    Dim ans = New List(Of Warp)

    For Each x In indices
        ans.Add(New Warp(New Triangle(sourceList(x.X1), sourceList(x.X2), sourceList(x.X3)), New Triangle(destList(x.X1), destList(x.X2), destList(x.X3))))
    Next

    Return ans
End Function

Upvotes: 1

Related Questions