Hello,
- Supposing the vertical axis is z.
- Supposing you might have more points in your CSV than vertices on the 3DPolyline.
- Supposing the CSV is organized such as column A: x values, B: y values, C: z values.
- Supposing there is not a ton of points otherwise another algorithm would be faster.
- Supposing the 3DPolyline is not vertical so the distance is not only checked on the z value but on the global 3D distance.
- Supposing the CSV file is not ordered (so all points have to be checked).
You can check, for each point of the CSV, the distance to all the points in the line and find the closest one.
I wrote this code for an Excel VBA macro which should work, to give you an idea on how to deal with the problem. Since I never wrote macros for CSV files it converts it to an xlsx file. It creates a 2D array with, for each of the CSV Rows, the point coordinates on the line which is closest to the CSV row point. You can adapt it if you want to use it in a different way.
Probably some tweaking to do since you gave few informations.
Best regards.
Private xlsxFile As Workbook
Sub main()
' main function call, your CSV file path here
getClosestPoints "C:\Book1.csv"
End Sub
Sub openCSV(csvFilePath As String)
Set xlsxFile = Workbooks.Open(csvFilePath, local:=True)
xlsxFile.SaveAs Filename:=Replace(csvFilePath, ".csv", ".xlsx"), FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
End Sub
Function getClosestPoints(csvFilePath As String) As Double()
' converting the CSV file to a excel file for ease of use
openCSV csvFilePath
Dim acadApp As AcadApplication, ThisDrawing As AcadDocument
Set acadApp = GetObject(, "AutoCAD.Application")
Set ThisDrawing = acadApp.ActiveDocument
AppActivate acadApp.Caption
acadApp.ZoomAll
' picking the line in the drawing
On Error GoTo pickline
Dim line As Acad3DPolyline
pickline:
ThisDrawing.Utility.GetEntity line, ptx
On Error GoTo 0
Dim linePts As Variant
linePts = line.Coordinates
Dim endI As Long, endJ As Long
endI = xlsxFile.Worksheets(1).Range("A1").End(xlDown).row
endJ = (UBound(linePts) + 1) \ 3 - 1
Dim closePtsList() As Double
ReDim closePtsList(1 To endI, 0 To 2)
Dim minDist As Double, indexDist As Long, currentDist As Double
Dim i As Long, j As Long, k As Long
' reading all the lines of the CSV
For i = 1 To endI
minDist = 1000000#
' reading the points of the line
For j = 0 To endJ
' calculating the distance from the CSV point to the line point
currentDist = distance( _
CDbl(linePts(3 * j)), CDbl(linePts(3 * j + 1)), CDbl(linePts(3 * j + 2)), _
getCSVXYZ(i, 1), getCSVXYZ(i, 2), getCSVXYZ(i, 3) _
)
' if current distance is minimal, save its index
If minDist > currenDist Then
minDist = currentDist
indexDist = j
End If
Next j
' copying the point in the return list, or copy it to your workbook if you prefer
For k = 0 To 2
closePtsList(i, k) = CDbl(linePts(3 * indexDist + k))
' Debug.Print closePtsList(i, k)
Next k
Next i
' returning the array
getClosestPoints = closePtsList
End Function
Function getCSVXYZ(row As Long, col As Long) As Double
getCSVXYZ = xlsxFile.Worksheets(1).Cells(row, col).Value
End Function
Function distance(x1 As Double, y1 As Double, z1 As Double, _
x2 As Double, y2 As Double, z2 As Double) As Double
' Returns the distance between two 3D points
' pt1 and pt2 are (x: Double, y: Double, z: Double)
distance = Sqr( _
(x1 - x2) ^ 2 + _
(y1 - y2) ^ 2 + _
(z1 - z2) ^ 2 _
)
End Function