Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / Drawing / July 2005

Tip: Looking for answers? Try searching our database.

Region.IsVisible - rounding error?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
matt tag - 19 Jul 2005 02:41 GMT
I posted this same code long ago and nobody had an answer. I'll try
again.

Does Region.IsVisible have rounding problems? The code below returns
True for a point inside a RectangleF, and False for the same point
inside a Region created from the same RectangleF.

thanks,
matt tag

     Dim FRect As RectangleF
     Dim FRgn As Region
     Dim FPt As PointF

     FRect = New RectangleF(168.0, 361.0, 13.2, 12.01)
     FRgn = New Region(FRect)
     FPt = New PointF(171, 373)

     Debug.WriteLine(FRect.Contains(FPt))
     Debug.WriteLine(FRgn.IsVisible(FPt))
Phil Wright - 19 Jul 2005 21:06 GMT
Remember that the Region is a complex shape and so performing a IsVisible
call is only going to be a close guess at the correct answer. In edge cases
it might not be as exact as you would like. You should use it as a rough
guide more than anything else.

Phil Wright
Follow my C# microISV startup at...
http://componentfactory.blogspot.com

>I posted this same code long ago and nobody had an answer. I'll try
> again.
[quoted text clipped - 16 lines]
>      Debug.WriteLine(FRect.Contains(FPt))
>      Debug.WriteLine(FRgn.IsVisible(FPt))
matt tag - 19 Jul 2005 21:39 GMT
I'll accept that, but I still need to perform a precise hittest against
an arbitrary polygon. Using a Region is not necessary, but I cannot use
Rectangle.Contains because my polygons will not always be rectangles

Does a precise PointInPolygon method exist in the .NET framework, or
has someone written an algorithm?

matt tag
Gerald Hernandez - 20 Jul 2005 03:08 GMT
> I'll accept that, but I still need to perform a precise hittest against
> an arbitrary polygon. Using a Region is not necessary, but I cannot use
[quoted text clipped - 4 lines]
>
> matt tag

Precise? Not that I am aware of. Almost everything built into the Framework
is to deal with displayed graphics, not necessarily any sort of meaningful
analysis.

Below is some code I threw together that might help. It is based on some
other code I use elsewhere in a full Polygon Class, but have altered it to
work within your described context. I haven't thoroughly tested it as
presented, so make sure to test it well. It isn't exactly the most efficient
and certainly not the only method, but it is conceptually "simple" and works
well. You probably don't really need to worry about optimizations unless
your needs are beyond what I glean from here. Clearly, a number of things,
like obvious error trapping, and other things were left out. But as far as
simple polygons are concerned, it should be much more precise than what the
Framework provides.

   '------------------------------------------------------------
   'PointInPolygon - Basic PIP test
   ' Uses simple and popular method based upon intersection count
   ' along the X axis. This version treats special cases as follows:
   ' If point falls directly on left or top edge, then is inside.
   ' If point falls directly on right or bottom edge, then is outside.
   ' Meaning for our puposes, a point is always either Inside or not.
   ' TestPoint    - PointF to test for containment
   ' PolyPoints() - Array of ordered vertices defining an arbitrary
   '   polygon. Coincident endpoints are implied and generated
   '   within this method.
   '------------------------------------------------------------
   Private Function PointInPolygon(ByVal TestPoint As PointF, _
       ByVal PolyPoints() As PointF) As Boolean

       Dim V0, V1 As PointF
       Dim D1, D2 As Single
       Dim idx As Integer, numPoints As Integer
       Dim inside As Boolean = False

       numPoints = PolyPoints.GetUpperBound(0)

       ' An imaginary closing segment is implied,
       '   so begin testing with that.
       V1 = PolyPoints(numPoints)
       For idx = 0 To numPoints
           V0 = PolyPoints(idx)
           D1 = (TestPoint.Y - V0.Y) * (V1.X - V0.X)
           D2 = (TestPoint.X - V0.X) * (V1.Y - V0.Y)
           If (TestPoint.Y < V1.Y) Then
               'V1 below ray
               If (V0.Y <= TestPoint.Y) Then
                   'V0 on or above ray
                   'Perform intersection test
                   If (D1 > D2) Then
                       inside = Not inside 'Toggle state
                   End If
               End If
           ElseIf (TestPoint.Y < V0.Y) Then
               'V1 is on or above ray, V0 is below ray
               'Perform intersection test
               If (D1 < D2) Then
                   inside = Not inside 'Toggle state
               End If
           End If

           V1 = V0 'Store previous endpoint as next startpoint
       Next

       Return inside

   End Function
   '------------------------------------------------------------
Bob Powell [MVP] - 20 Jul 2005 11:05 GMT
A region is a collection of rectangles that defines an area in terms of
absolute pixels. It has no floating point values and the hit-test is only
accurate to the nearest pixel.

To hit test things in world coordinate space using inches or other
real-world measurements you'll have to use the GraphicsPath.

Signature

Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.

>I posted this same code long ago and nobody had an answer. I'll try
> again.
[quoted text clipped - 16 lines]
>      Debug.WriteLine(FRect.Contains(FPt))
>      Debug.WriteLine(FRgn.IsVisible(FPt))
matt tag - 22 Jul 2005 00:10 GMT
I'll try the PointInPolygon function, thanks.

FWIW, the GraphicsPath is not working, either.

  Dim FRect As RectangleF
     Dim FRgn As Region
     Dim FPt As PointF
     Dim gp As graphicspath

     FRect = New RectangleF(168.0, 361.0, 13.2, 12.01)
     FRgn = New Region(FRect)
     FPt = New PointF(171, 373)

     gp = New GraphicsPath(FillMode.Winding)
     gp.AddRectangle(FRect)

     Debug.WriteLine(FRect.Contains(FPt))
     Debug.WriteLine(FRgn.IsVisible(FPt))
     Debug.WriteLine(gp.IsVisible(FPt))

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.