Someone recently asked about determining if a point resides within a polyline using VBA. There are a few ways to achieve this, some being more complex than others, each with their own advantages. However, there is one way that is particularly simple within the AutoCAD® environment, as we are able to use built in features such as the IntersectWith method.

The concept for finding out if a point is within a polyline is this – if we were to draw a line from the point in any direction to infinity, the number of intersections the line would have with the polyline would be an odd number. Think about it – if it was a square, it would cross the polyline once. For irregular shapes where the line crosses it many times, it firstly has to exit the shape – any re-entry to the shape must have a corresponding exit – so if the point is within the polyline, any line eminating from it to infinity **must** cross the boundary an odd number of times. And for the same reason, any point outside the boundary **must** cross the boundary an even number of times.

So, armed with this knowledge, we need a way to actually achieve this in AutoCAD®. And what better way of doing so is there than to simply draw a Ray in any direction, and find out how many intersections with the boundary there are? Well, that’s exactly what this code does:

```
```Option Explicit
Sub main()
Dim selPolyline As AcadLWPolyline
Dim selPoint As AcadPoint
Dim pnt As Variant
Randomize 'Initialise random number generator
ThisDrawing.Utility.GetEntity selPolyline, pnt, "Pick polyline"
ThisDrawing.Utility.GetEntity selPoint, pnt, "Pick point"
If isPointInPolyline(selPolyline, selPoint) Then
ThisDrawing.Utility.Prompt "The point resides within the polyline"
Else
ThisDrawing.Utility.Prompt "The point resides outside the polyline"
End If
End Sub
Function isPointInPolyline(pl As AcadLWPolyline, pnt As AcadPoint) As Boolean
Dim p1 As Variant
Dim p2 As Variant
Dim ray As AcadRay
Dim arr As Variant
Dim upperbound As Long
Dim IntersectionCount As Long
p1 = pnt.Coordinates
p2 = p1
' edit on 03/12/2010 for increased reliability
' horizontal ray exchanged for a ray with a random direction
p2(0) = p2(0) + 1 - Rnd * 2 'offset x coordinate for secondary point in Ray by random amount
p2(1) = p2(1) + 1 - Rnd * 2 'offset y coordinate for secondary point in Ray by random amount
' end of edit
Set ray = thisSpace.AddRay(p1, p2)
arr = ray.IntersectWith(pl, acExtendNone)
upperbound = UBound(arr)
If upperbound = -1 Then
' No intersections - the point must not be inside the polyline
' Assumes no elevation
isPointInPolyline = False
Else
IntersectionCount = (upperbound + 1) / 3
'number of elements in array is equal to the upperbound + 1 because of element zero
'we divide by 3 to find the number of individual intersections because each has
'3 coordinates - X, Y and Z
If IntersectionCount Mod 2 = 0 Then
'There are an even number of intersections - it cannot be inside the polyline
isPointInPolyline = False
Else
'There are an odd number of intersections - it must be inside the polyline
isPointInPolyline = True
End If
End If
ray.Delete
End Function
Function thisSpace() As AcadBlock
If ThisDrawing.ActiveSpace = acModelSpace Then
Set thisSpace = ThisDrawing.ModelSpace
Else
Set thisSpace = ThisDrawing.PaperSpace
End If
End Function

Do consider subscribing to my blog – I’ll always be posting code snippets like this, and always with a decent explanation. Please also feel free to leave comments.

Will