![]() |
| ||
| Draw the perimiter of a PointF collection? 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 |
| All times are GMT -4. The time now is 9:54 pm. |
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC