Вот мой пример расширения.Я создал проблемную версию First
, в которой не используется лямбда-параметр, и изменил код для использования ValueTuple
вместо анонимного класса, поскольку вы не можете вернуть анонимные классы из Function
.
Я также использовал List
для агрегирования ответов LINQ, поскольку фактическое расширение функций генератора с использованием Yield
не показалось мне ясным.
Из-за этих измененийэтот код менее эффективен, чем код LINQ в поколении, но более эффективен в First
, так что, возможно, мытье?
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