New operators/behaviour for irr::core::rect<T>

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
gerdb
Posts: 194
Joined: Wed Dec 02, 2009 8:21 pm
Location: Dresden, Germany

New operators/behaviour for irr::core::rect<T>

Post by gerdb »

// RE: by BenjaminHampe@gmx.de
// pls add the possibility to add/sub rects to others,
// to get a new desired rect quickly

Code: Select all

 
//! add rectangles
template <class T>
irr::core::rect<T> operator+ (const irr::core::rect<T>& rThis, const irr::core::rect<T>& rOther)
{
    irr::core::rect<T> result(rThis);
    result.UpperLeftCorner.X += rOther.UpperLeftCorner.X;
    result.UpperLeftCorner.Y += rOther.UpperLeftCorner.Y;
    result.LowerRightCorner.X += rOther.LowerRightCorner.X;
    result.LowerRightCorner.Y += rOther.LowerRightCorner.Y;
    return result;
}
 

Code: Select all

 
//! sub rectangles
template <class T>
irr::core::rect<T> operator- (const irr::core::rect<T>& rThis, const irr::core::rect<T>& rOther)
{
    irr::core::rect<T> result(rThis);
    result.UpperLeftCorner.X -= rOther.UpperLeftCorner.X;
    result.UpperLeftCorner.Y -= rOther.UpperLeftCorner.Y;
    result.LowerRightCorner.X -= rOther.LowerRightCorner.X;
    result.LowerRightCorner.Y -= rOther.LowerRightCorner.Y;
    return result;
}
 
// RE: BenjaminHampe@gmx.de
// USAGE: if you have a rect AbsoluteRect, like in IGUIElement
// and you like to have a new rect that fits in AbsoluteRect
// but 2 pixels border on each side just add rect(2,2,-2,-2)
//
// Example:

Code: Select all

 
irr::core::recti NewRect = AbsoluteRect + irr::core::recti(2,2,-2,-2);
 
PROBLEM #2

Code: Select all

 
        //! compares size of rectangles
        bool operator<(const rect<T>& other) const
        {
            return getArea() < other.getArea();
        }
 
// RE: by BenjaminHampe@gmx.de
// This behaviour does not make any sense for most cases,
// because it does not compare absolute coords,
// pls change behaviour! if you like to compare Areas, just do
// what the function does getArea() < other.getArea(), but
// pls dont waste operators for such simple, never needed behaviour.

// REPLACEMENTS:

Code: Select all

 
//! compares coords of rectangles
template <class T>
bool operator< (const irr::core::rect<T>& rThis, const irr::core::rect<T>& rOther)
{
    return (
    (rThis.UpperLeftCorner.X<rOther.UpperLeftCorner.X) &&
    (rThis.UpperLeftCorner.Y<rOther.UpperLeftCorner.Y) &&
    (rThis.LowerRightCorner.X<rOther.LowerRightCorner.X) &&
    (rThis.LowerRightCorner.Y<rOther.LowerRightCorner.Y));
}
 
//! compares coords of rectangles
template <class T>
bool operator> (const irr::core::rect<T>& rThis, const irr::core::rect<T>& rOther)
{
    return (
    (rThis.UpperLeftCorner.X>rOther.UpperLeftCorner.X) &&
    (rThis.UpperLeftCorner.Y>rOther.UpperLeftCorner.Y) &&
    (rThis.LowerRightCorner.X>rOther.LowerRightCorner.X) &&
    (rThis.LowerRightCorner.Y>rOther.LowerRightCorner.Y));
}
template <class T>
bool operator<= (const irr::core::rect<T>& rThis, const irr::core::rect<T>& rOther)
{
    return (
    (rThis.UpperLeftCorner.X<=rOther.UpperLeftCorner.X) &&
    (rThis.UpperLeftCorner.Y<=rOther.UpperLeftCorner.Y) &&
    (rThis.LowerRightCorner.X<=rOther.LowerRightCorner.X) &&
    (rThis.LowerRightCorner.Y<=rOther.LowerRightCorner.Y));
}
 
//! compares coords of rectangles
template <class T>
bool operator>= (const irr::core::rect<T>& rThis, const irr::core::rect<T>& rOther)
{
    return (
    (rThis.UpperLeftCorner.X>=rOther.UpperLeftCorner.X) &&
    (rThis.UpperLeftCorner.Y>=rOther.UpperLeftCorner.Y) &&
    (rThis.LowerRightCorner.X>=rOther.LowerRightCorner.X) &&
    (rThis.LowerRightCorner.Y>=rOther.LowerRightCorner.Y));
}
 
// thx for reading
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: New operators/behaviour for irr::core::rect<T>

Post by hybrid »

Well, IMHO both of your suggestions don't make enough sense to add them. Addition of two rects is not properly defined, so choosing a proper implementation is hard anyway. But yours does not even take into account any geometrical reasoning about the positions. What you seem to want is adding a dimension2d to a rectangle. And IIRC, we already have that.
Your second suggestion seesm far worse than the current implementation. Why would a rectangle with area 10, lying at a position far left from the origin, be smaller than a rectangle of area 1, centered at the origin?!
Please don't waste my time with such never needed patches...
gerdb
Posts: 194
Joined: Wed Dec 02, 2009 8:21 pm
Location: Dresden, Germany

Re: New operators/behaviour for irr::core::rect<T>

Post by gerdb »

hi, thx for answering,

i know choosing a proper definition of what operators should do is not easy,
1.)
What you seem to want is adding a dimension2d to a rectangle. And IIRC, we already have that.
maybe im blind, but i simply do not find

operator+ (dimension2di)
operator+ (dimension2du)
operator- (dimension2du)

in rect.h. (using 1.7.3)!!!

2.)
i belive the mathematically correct result of adding a position (point) to a rect would be a polygon consisting of all points of the rect and the one point.
So what you really do, has nothing to do with correct math (set theory/Mengenlehre), it has to do with usability (transforming the rect) by adding
each component to each other. this same behaviour would do as i suggested!

3.) to the comparison operators:
for me a rect is just a vector with 4 elements, so comparing them, would compare all coords seperatly, not their area.

4.)
But yours does not even take into account any geometrical reasoning about the positions
neither the equality operator does take any geometrical properties into account, why should i?
just compares coords

Code: Select all

 
                //! equality operator
                bool operator==(const rect<T>& other) const
                {
                        return (UpperLeftCorner == other.UpperLeftCorner &&
                                LowerRightCorner == other.LowerRightCorner);
                }
 
takes geometrical reasoning into account

Code: Select all

 
                //! equality operator
                bool operator==(const rect<T>& other) const
                {
                        return (getPos() == other.getPos() && 
getSize() == other.getSize());
                }
 
the whole class does not take geometric into account, if it did, the properties would be x,y,w,h, not x1,y1,x2,y2
a point has x,y
a line has x,y,x2,y2 --> so your rect is in fact a line (by geometric reasoning)
a circle has x,y,r
a ellipse has x,y,rx,ry ... etc...

just i.m.h.o.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: New operators/behaviour for irr::core::rect<T>

Post by hybrid »

1./2. Yes, looks like we only have a point addition for now. But the correct extension of this semantics would definitely be a vector2d, not a rect.
Hull operations are just a different use case. Since these were not implemented in the first way, there's no way to add them now by overloading the same operator with different semantics. If you need a hull operation, use a separate operation.
3. It does not matter what you think a rect is. For the < and == operators, it is very important to get a good order. Otherwise you cannot use rects in sorted arrays or trees.
4. If there's no need for geometrical reasoning, or if the same test can be done using a simpler way, than that's ok. But introducing a completely different order without any interpretation is simply not possible.
Post Reply