Region.IsVisible () does not work as documented (?) [GDI +]

I see that Region.IsVisible (rectangle) does not work as I expect.
So, to me , who does not expect that it should not, or is it a method that does not what it should ?!

I have the following situation:

alt text http://lh4.ggpht.com/_1TPOP7DzY1E/TCmxn6Tzn2I/AAAAAAAADRc/GJhbStCvabQ/s800/Capture3.gif alt text http://lh5.ggpht.com/_1TPOP7DzY1E/TCmuVyrgPAAAA/AAA/AAA/AJAA .gif

And the following code:

private void Form1_Paint(object sender, PaintEventArgs e) { Point[] points1 = new Point[] { new Point(50, 30), new Point(70, 30), new Point(40, 40), new Point(60, 70), new Point(30, 50) }; Point[] points2 = new Point[] { new Point(70, 150), new Point(50, 110 ), new Point(60, 80), new Point(90, 80), new Point(140, 60) }; Point[] points3 = new Point[] { new Point(100, 10), new Point(130, 40) }; GraphicsPath path1 = new GraphicsPath(); GraphicsPath path2 = new GraphicsPath(); GraphicsPath path3 = new GraphicsPath(); path1.AddLines(points1); path2.AddLines(points2); path3.AddLines(points3); e.Graphics.DrawPath(Pens.DarkBlue, path1); e.Graphics.DrawPath(Pens.DarkGreen, path2); e.Graphics.DrawPath(Pens.DarkOrange, path3); Region r1 = new Region(path1); Region r2 = new Region(path2); Region r3 = new Region(path3); // Create the first rectangle and draw it to the screen in blue. Rectangle blueRect = new Rectangle(20, 20, 100, 100); e.Graphics.DrawRectangle(Pens.Blue, blueRect); bool contained; // Display the result. ControlPaint.DrawGrid(e.Graphics, this.ClientRectangle, new Size(10, 10), Color.Red); contained = r1.IsVisible(blueRect); e.Graphics.DrawString("Path blue contained = " + contained.ToString(), Font, myBrush, new PointF(20, 160)); contained = r2.IsVisible(blueRect); e.Graphics.DrawString("Path green contained = " + contained.ToString(), Font, Brushes.Black, new PointF(20, 180)); contained = r3.IsVisible(blueRect); e.Graphics.DrawString("Path orange contained = " + contained.ToString(), Font, Brushes.Black, new PointF(20, 200)); } 

In addition, a path that is not in the region may be “visible”:

 Point[] points3 = new Point[] { new Point(15, 35), new Point(15, 130), new Point(60 ,130) }; 

EDIT:
Even Intersect does not work for the second L path:

 Point[] points3 = new Point[] { new Point(10, 40), new Point(10, 130), new Point(50 ,130) }; r3.Intersect(blueRect); bool contained = !(r1.IsEmpty(e.Graphics)); e.Graphics.DrawString("Path orange contained = " + contained.ToString(), Font, Brushes.Black, new PointF(20, 200)); // TRUE! instead of desired FALSE 
+4
source share
3 answers

So, the solution for this was to use ... the Widen () method for paths before checking its visibility:

 private void Form1_Paint(object sender, PaintEventArgs e) { Point[] points1 = new Point[] { new Point(50, 30), new Point(70, 30), new Point(40, 40), new Point(60, 70), new Point(30, 50) }; Point[] points2 = new Point[] { new Point(70, 150), new Point(50, 110 ), new Point(60, 80), new Point(90, 80), new Point(140, 60) }; Point[] points4 = new Point[] { new Point(50, 50), new Point(90, 90) }; Point[] points3 = new Point[] { new Point(15, 35), new Point(15, 130), new Point(60 ,130) }; GraphicsPath path1 = new GraphicsPath(); GraphicsPath path2 = new GraphicsPath(); GraphicsPath path3 = new GraphicsPath(); GraphicsPath path4 = new GraphicsPath(); path1.AddLines(points1); path2.AddLines(points2); path3.AddLines(points3); path4.AddLines(points4); e.Graphics.DrawPath(Pens.DarkBlue, path1); e.Graphics.DrawPath(Pens.DarkGreen, path2); e.Graphics.DrawPath(Pens.DarkRed, path3); e.Graphics.DrawPath(Pens.DarkGoldenrod, path4); // <<<< HERE >>>>> path3.Widen(Pens.DarkRed); path4.Widen(Pens.DarkGoldenrod); Region r1 = new Region(path1); Region r2 = new Region(path2); Region r3 = new Region(path3); Region r4 = new Region(path4); // Create the first rectangle and draw it to the screen in blue. Rectangle blueRect = new Rectangle(20, 20, 100, 100); e.Graphics.DrawRectangle(Pens.Blue, blueRect); bool contained; // Display the result. ControlPaint.DrawGrid(e.Graphics, this.ClientRectangle, new Size(10, 10), Color.Red); contained = r1.IsVisible(blueRect); e.Graphics.DrawString("Path blue contained = " + contained.ToString(), Font, Brushes.Black, new PointF(20, 160)); contained = r2.IsVisible(blueRect); e.Graphics.DrawString("Path green contained = " + contained.ToString(), Font, Brushes.Black, new PointF(20, 180)); contained = r3.IsVisible(blueRect); e.Graphics.DrawString("Path orange contained = " + contained.ToString(), Font, Brushes.Black, new PointF(20, 200)); contained = r4.IsVisible(blueRect); e.Graphics.DrawString("Path DarkGoldenrod contained = " + contained.ToString(), Font, Brushes.Black, new PointF(20, 220)); } 

Regarding the question in the thread header: Yes , in fact, IsVisible from Region does not work, as described in MSDN.

Microsoft should add some precision notes to its documentation.

+2
source

From the orange L-shaped example, I see that you don't understand what your code is doing.

Building an area from a path does not give the area as a drawn path. Building an area from an L-shaped orange track does not produce an L-shaped area of ​​the width of one pixel. The path closes, connecting both ends, forming a triangle. The area is then the interior of this triangle, and the blue rectangle is obviously partially contained in this area.

For the original example of a single orange line, the resulting region is a degenerate polygon with two angles - still looking like a line and with zero width in the direction orthogonal to the line (s). Therefore, the region has zero area and does not contain anything (except, perhaps, points on the boundary of the region, if the region is a closed set).

What you really want to do is check the visibility of the path against the rectangular area of ​​the blue rectangle. As far as I know, there is no built-in support for this.

+3
source

Maybe the Region.IsVisible method just checks to see if any of the ends of its component line segments are inside the rectangle or not. Thus, the blue and green lines (each of which has several endpoints of the segment in the rectangle) are true , and the orange line (which has 0 endpoints inside the rectangle) is false .

Technically, your code is actually trying to determine if each irregular Path contains a blue rectangle (and not vice versa). An alternative way to do what you are actually trying to do (but this will probably return the same results):

 r1.Intersect(blueRect); e.Graphics.DrawString("Path blue contained = " + (!r1.IsEmpty(e.Graphics)).ToString(), Font, Brushes.Black, new PointF(20, 200)); 
+1
source

Source: https://habr.com/ru/post/1314066/


All Articles