QRect and QRectF - contains menthod
-
Hi
I had a quick question on a version of the contans method for QRect and QRectF
QRect
bool QRect::contains(const QRect & rectangle, bool proper = false) const
This is an overloaded function.
Returns true if the given rectangle is inside this rectangle. otherwise returns false. If proper is true, this function only returns true if the rectangle is entirely inside this rectangle (not on the edge).QRectF
bool QRectF::contains(const QRectF & rectangle) const
This is an overloaded function.
Returns true if the given rectangle is inside this rectangle; otherwise returns false.For the QRectF version, will it return true if the second rectangle is entirely in the first rectangle?
Or on the edge?
Or both both on the edge and inside the first rectangle?
Are there any plans to have an overloaded version of this function that takes the proper boolean flag?Thanks
Damien -
Hi, welcome to devnet.
I don't think there will be a flag like that for the RectF class.
It's just that it's hard(if not impossible) to define equality for floating point numbers. It would have to be defined in terms of some epsilon margin value, which would complicate interface. For example what if the two rects had different epsilons? If you need such functionality you can always define your own utility that will exactly match your needs. -
Hi Chris
Thanks for your response. That makes sense
On analyzing my requirement again, I think I should be able to get away with using a qRect as opposed a qRectFThanks for your help
-
Just ran into this issue as well for QRect/QRectF containing points.
[code]
QRect r1(30, 30, 30, 30);
QRect r2(60, 30, 30, 30);
bool b1 = r1.contains(60, 30); // false
bool b2 = r2.contains(60, 30); // trueQRectF r3(30, 30, 30, 30);
QRectF r4(60, 30, 30, 30);
bool b3 = r3.contains(60, 30); // true
bool b4 = r4.contains(60, 30); // true
[/code]Intuitively this appears wrong, but the epsilon Chris mentions being used to compare the floats explains it well.
A custom function like
[code]
bool contains(const QRectF& rect, const QPointF& point)
{
if ( rect.topLeft().x() <= point.x()
&& rect.topLeft().y() <= point.y()
&& rect.bottomRight().x() > point.x()
&& rect.bottomRight().y() > point.y())
{
return true;
}
return false;
}
[/code]has the behavior I want, but it has assumptions and conditions that don't fit a general concept:
- Top and left edge are considered inside (<=)
- Bottom and right edge are considered not inside (<)
- No epsilon so I will probably have fun with rounding errors soon
Until then I hope it will work if I keep everything consistent.
-
Yeah, it comes down to the fact that practically there's no well behaved operator== or operator <= or anything that resembles equality for floating points.
The best you can do is add third float parameter to your function and replace
@rect.topLeft().x() <= point.x()@
with this
@rect.topLeft().x() < (point.x() + eps)@But this has another set of rounding problems so usually the answer is simple: don't bother. If you care about edges stick to fixed point math where edge has a clear representation.