My brain hurts again.

I want to take a collection of PointF objects and crate a path that is the outer perimiter of the collection, so that I don't get a criss-cross problem. I'm assuming no wierd shapes with undercuts; just a collection of 'border' points. The best I could come up with is a 'Clock Hand' type radial sorting function (below). There HAS to be a better way. Anyone?

(Note: The seGpsPoint object contains a .DrawingPoint property that is a PointF object, everything else is standard)

''' <summary>

''' Sorts the DrawingPoints ofa a collection

''' of seGpsPoints in a clockwise direction

''' for use in drawing a path or polygon around

''' the outer perimeter of the collection

''' </summary>

''' <param name="GPSPointCollection">Collection of seGpsPoints to sort</param>

''' <param name="Bounds">Rectale defining sort area</param>

''' <param name="GraphicsObject">System.Graphics object to scan</param>

''' <returns></returns>

''' <remarks></remarks>

Public Function RadialSort(ByVal GPSPointCollection As Collection, ByVal Bounds As RectangleF, ByVal GraphicsObject As Graphics) As PointF()

Dim oPoint As New Point

Dim oGPS As New seGpsPoint

Dim oColl As New Collection

Dim oTemp As New Collection 'Collection of Points already captured

Dim CenterPt As New Point

Dim oMatrix As New Matrix

Dim iAngle As Integer = 0

'Set Sweep Centerpoint

CenterPt.X = CInt(Bounds.X + Bounds.Width / 2)

CenterPt.Y = CInt(Bounds.Y + Bounds.Height / 2)

Dim oSweepRect As New RectangleF

'Define Sweep Arm rectangle

oSweepRect.Y = CenterPt.Y

'Conservatively define Sweep Arm

oSweepRect.Width = Convert.ToSingle(Math.Max(10, Bounds.Width / 20))

oSweepRect.X = (CenterPt.X - oSweepRect.Width / 2)

'Trig to make sure all points are in Sweep Radius

oSweepRect.Height = Convert.ToSingle(Math.Sqrt(((Bounds.Height / 2) ^ 2 + (Bounds.Width / 2) ^ 2))) + 10

Dim oSweepRegion As New Region(oSweepRect)

'Collection of seGpsPoint Objects, each with a PointF

oColl = GPSPointCollection

'Target PointF Array to be returned length = Collection Count

Dim aryPoints(oColl.Count - 1) As PointF

'Dim return array index counter

Dim iCtr As Integer = 0

'Dim index counter for Rectange Objects

'that will approximate the Sweep Arm using

'the GetRegionScans method

Dim iIndex As Integer = 0

'Define rotation as 1 degree

oMatrix.RotateAt(1, CenterPt)

GraphicsObject.FillRegion(Brushes.Transparent, oSweepRegion)

'Make sure all 360 degrees are covered

For iAngle = 0 To 361

'This will rotate the Matrix by 1 degree

oSweepRegion.Transform(oMatrix)

GraphicsObject.FillRegion(Brushes.Transparent, oSweepRegion)

Dim aryArm() As RectangleF = oSweepRegion.GetRegionScans(oMatrix)

'This is a processor intensive bit

For iIndex = 0 To aryArm.Length - 1

For Each oGPS In GPSPointCollection

If aryArm(iIndex).Contains(oGPS.DrawingPoint) Then

Dim strKey As String

strKey = oGPS.GpsID.ToString

'Don't duplicate points, in case arms

'recapture a point on this iteration

If Not oTemp.Contains(strKey) Then

'Add seGpsPoint object and key to 'already captured' Collection

oTemp.Add(oGPS, oGPS.GpsID.ToString)

aryPoints(iCtr) = oGPS.DrawingPoint

'Increment array index when new point is captured

iCtr += 1

If iCtr = oColl.Count Then

'Commit array and exit when array is full

RadialSort = aryPoints

Exit Function

End If

End If

End If

Next

Next

Next

'This code should never be executed if all is well:

RadialSort = aryPoints

End Function