Rectangle From Polygon (Points Array)
-
Hi Guys I was wondering if anyone knew an approach to retrieve a rectangle that would contain the points of a polygon? I had a crack at it as below:
Dim size As New SizeF(400.0F, 500.0F) Dim points(5) As PointF points(0) = New PointF(20.0F, 20.0F) points(2) = New PointF(92.0F, 25.0F) points(3) = New PointF(115.0F, 60.0F) points(4) = New PointF(127.0F, 90.0F) points(5) = New PointF(130.0F, 167.0F) Using image As New Bitmap(CInt(size.Width), CInt(size.Height)) Using graphics As Graphics = graphics.FromImage(image) Dim path As New GraphicsPath Dim region As New Region path.AddPolygon(points) region.Union(path) Return region.GetBounds(graphics) End Using End Using
However this returned a bizzar rectangle{X=-4194304,Y=-4194304,Width=8388608,Height=8388608}
regardless of the coordinates. Any help, greatly appreciated! Thanks Tom -
Hi Guys I was wondering if anyone knew an approach to retrieve a rectangle that would contain the points of a polygon? I had a crack at it as below:
Dim size As New SizeF(400.0F, 500.0F) Dim points(5) As PointF points(0) = New PointF(20.0F, 20.0F) points(2) = New PointF(92.0F, 25.0F) points(3) = New PointF(115.0F, 60.0F) points(4) = New PointF(127.0F, 90.0F) points(5) = New PointF(130.0F, 167.0F) Using image As New Bitmap(CInt(size.Width), CInt(size.Height)) Using graphics As Graphics = graphics.FromImage(image) Dim path As New GraphicsPath Dim region As New Region path.AddPolygon(points) region.Union(path) Return region.GetBounds(graphics) End Using End Using
However this returned a bizzar rectangle{X=-4194304,Y=-4194304,Width=8388608,Height=8388608}
regardless of the coordinates. Any help, greatly appreciated! Thanks TomYou can do this several different ways. In all cases, you keep track of the lowest and highest values for the points involved. You can either use a custom Structure to do this and not keep track of the points themselves, only the result, or you can hold the points in a custom implementation of an Array, ArrayList, or List class so you can add and remove points and update the tracked values as the changes are made. But, basically, the first call to this class/structure would set the upper and lower bounds of the bounding rectangle.
\_lowX = newPoint.X : \_highX = newPoint.X \_lowY = newPoint.Y : \_highY = newPoint.Y
After that, subsequent calls would simply do something like this:
\_lowX = Math.Min(\_lowX, newPoint.X) \_lowY = Math.Min(\_lowY, newPoint.Y) \_highX = Math.Max(\_highX, newPoint.X) \_highY = Math.Max(\_highY, newPoint.Y)
I knew I had something like this around here. I'll modify it for what you're looking for and post a quick article on it later tonight.
Dave Kreskowiak Microsoft MVP - Visual Basic
-
Hi Guys I was wondering if anyone knew an approach to retrieve a rectangle that would contain the points of a polygon? I had a crack at it as below:
Dim size As New SizeF(400.0F, 500.0F) Dim points(5) As PointF points(0) = New PointF(20.0F, 20.0F) points(2) = New PointF(92.0F, 25.0F) points(3) = New PointF(115.0F, 60.0F) points(4) = New PointF(127.0F, 90.0F) points(5) = New PointF(130.0F, 167.0F) Using image As New Bitmap(CInt(size.Width), CInt(size.Height)) Using graphics As Graphics = graphics.FromImage(image) Dim path As New GraphicsPath Dim region As New Region path.AddPolygon(points) region.Union(path) Return region.GetBounds(graphics) End Using End Using
However this returned a bizzar rectangle{X=-4194304,Y=-4194304,Width=8388608,Height=8388608}
regardless of the coordinates. Any help, greatly appreciated! Thanks TomHere, try this. It's based off something I used for a custom graphing component. A couple modifications and it was all set to go:
Imports System.Collections.Generic
...
Public Class BoundingRectangle
Inherits List(Of Point)
Private _lowX As Single
Private _lowY As Single
Private _highX As Single
Private _highY As Single
Public Shadows Sub Clear()
_lowX = 0 : _lowY = 0 : _highX = 0 : _highY = 0
MyBase.Clear()
End Sub
Public ReadOnly Property Rectangle() As Rectangle
Get
UpdateBounds()
Return New Rectangle(_lowX, _lowY, _highX - _lowX, _highY - _lowY)
End Get
End Property
Public Sub New()
MyBase.New()
Me.Clear()
End Sub
Public Shadows Sub Add(ByVal p As Point)
MyBase.Add(p)
End Sub
Private Sub UpdateBounds()
' If we have no points in our list, the bounding rectangle is (0,0)-(0,0)
If MyBase.Count = 0 Then
Me.Clear()
Exit Sub
Else
' If this is the first point we have, it defines the starting bounding rectangle
With MyBase.Item(0)
_lowX = .X : _highX = .X
_lowY = .Y : _highY = .Y
End With
End If
If MyBase.Count > 1 Then
' We have more than one point, find the new bounding rectangle.
For i As Integer = 1 To MyBase.Count - 1
With MyBase.Item(i)
_lowX = Math.Min(_lowX, .X)
_lowY = Math.Min(_lowY, .Y)
_highX = Math.Max(_highX, .X)
_highY = Math.Max(_highY, .Y)
End With
Next
End If
End Sub
End ClassI can't get the article written tonight, so this will have to do for now. It's primarily going to be about creating your own custom typed collections, with added functionality, like tracking and returning a bounding rectangle! ;)
Dave Kreskowiak Microsoft MVP - Visual Basic
-
Here, try this. It's based off something I used for a custom graphing component. A couple modifications and it was all set to go:
Imports System.Collections.Generic
...
Public Class BoundingRectangle
Inherits List(Of Point)
Private _lowX As Single
Private _lowY As Single
Private _highX As Single
Private _highY As Single
Public Shadows Sub Clear()
_lowX = 0 : _lowY = 0 : _highX = 0 : _highY = 0
MyBase.Clear()
End Sub
Public ReadOnly Property Rectangle() As Rectangle
Get
UpdateBounds()
Return New Rectangle(_lowX, _lowY, _highX - _lowX, _highY - _lowY)
End Get
End Property
Public Sub New()
MyBase.New()
Me.Clear()
End Sub
Public Shadows Sub Add(ByVal p As Point)
MyBase.Add(p)
End Sub
Private Sub UpdateBounds()
' If we have no points in our list, the bounding rectangle is (0,0)-(0,0)
If MyBase.Count = 0 Then
Me.Clear()
Exit Sub
Else
' If this is the first point we have, it defines the starting bounding rectangle
With MyBase.Item(0)
_lowX = .X : _highX = .X
_lowY = .Y : _highY = .Y
End With
End If
If MyBase.Count > 1 Then
' We have more than one point, find the new bounding rectangle.
For i As Integer = 1 To MyBase.Count - 1
With MyBase.Item(i)
_lowX = Math.Min(_lowX, .X)
_lowY = Math.Min(_lowY, .Y)
_highX = Math.Max(_highX, .X)
_highY = Math.Max(_highY, .Y)
End With
Next
End If
End Sub
End ClassI can't get the article written tonight, so this will have to do for now. It's primarily going to be about creating your own custom typed collections, with added functionality, like tracking and returning a bounding rectangle! ;)
Dave Kreskowiak Microsoft MVP - Visual Basic
Dave Thanks for the time you put into this, very helpful. I have to say, I considered this loop/test method originally, but assumed there would be an approach somewhere in the framework that would do the task. Glad my fruitless search was not down to my incompetence! Cheers again. Tom P.S. Worked like a charm! -- modified at 4:46 Monday 9th October, 2006