`Rectangle.Contains` must be exclusive on `Width` and `Height`
See original GitHub issueDescribe the bug
Current implementation of Rectangle.Contains
includes additional row and column also, which means, for instance, that zero height rectangle contains 1 horizontal line of height 1, which means that height=0 is not less than height=1, which is mathematically wrong.
public bool Contains(Point p)
{
return p.X >= _x && p.X <= _x + _width &&
p.Y >= _y && p.Y <= _y + _height;
}
Right and down boundaries must be exclusive, like p.Y < _y + _height
rather than p.Y <= _y + _height
.
One more example is rectangle with height=1. It’s drawn like a line, 1 pixel height (not like two lines of 1 pixel height). If we click on it, avalonia by mistake will count next line (where no rectangle is drawn) also as a part of rectangle:
To Reproduce Rectangle with height=1:
-------------------------
*
---- - represents a rectangle with height=1 (0,0,20,1) *-represents point of mouse click (4,1) As you see, we have clicked below the rectangle, but Avalonia counts it as a click on the rectangle.
Additional context Standard .NET class rectangle also contains wrong implementation and includes one more horizontal and one more vertical lines with width=1 in to considiration.
Issue Analytics
- State:
- Created a year ago
- Comments:11 (11 by maintainers)
Top GitHub Comments
Yeah, I’m really not sure why
Contains
is like it is though it would appear there’s a mathematical reason. As you can see from the commit history, it was exclusive at one point and then I changed it to inclusive, but didn’t write my reasoning in a commit message (bad Steven). The only clue wasContains(r.TopLeft) && Contains(r.BottomRight)
. I’m guessing I wrote that, saw it was wrong, checked WPF and noticed it was inclusive, so changed it to be like WPF.If I’d not done that, then at this point I’d be saying “Avalonia is correct, WPF is wrong” but since I did do that, I think as you say, changing it silently at this point would be causing more trouble than its worth because it’s not functionality that will obviously break for anyone already using it - it’s an insidious change that will probably break things in minor ways. Of course it may also fix just as many things in minor ways, but hard to know.
So given that, I think we should fix our hit-testing to use
ContainsExclusive
and leaveRect.Contains
to match WPF/UWP/QT. So yeah I think we’re in agreement here 😉@grokys If we use
ContainsExclusive
everywhere, why to keep original? Just to keep things similar? I just don’t see any applications for inclusiveContains
. To be honest, I don’t completely understand Hans argument. While doing a drawing system, we have to carry about anti-aliasing and similar stuff, we don’t do just simple overlaps of random shapes. And even if we did that, we don’t need to use Contains for that. My overall point is just that inclusiveContains
is wrong in all senses and does not have any possible applications neither in computer science nor in math. I still can’t find anything useful for that. Even Koshi math does not work with it correctly.Relative to the topic: https://github.com/Rust-SDL2/rust-sdl2/issues/569