•
•
•
•
What is DaniWeb IT Discussion Community?
You're currently browsing the VB.NET section within the Software Development category of DaniWeb, a massive community of 374,447 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 2,756 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our VB.NET advertiser:
Views: 1833 | Replies: 0
![]() |
•
•
Join Date: Nov 2005
Posts: 19
Reputation:
Rep Power: 3
Solved Threads: 0
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
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
![]() |
•
•
•
•
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
•
•
•
•
•
•
•
•
DaniWeb VB.NET Marketplace
- URGENT!! - Constructive Criticism needed on www.giftday.co.za (Website Reviews)
- How to use collection in java (Java)
- Graphics In Pixel: Part II (C++)
- DVD Collection Program (Visual Basic 4 / 5 / 6)
- Can draw one Frame in a variable? (Java)
Other Threads in the VB.NET Forum
- Previous Thread: Check to see if null
- Next Thread: X,Y,Z to Isometric? My brain hurts.


Linear Mode