[ create a new paste ] login | about

Link: http://codepad.org/paQRFwur    [ raw code | output | fork ]

sehe - C++, pasted on Jul 12:
// Final proposal: combine adjacent rectangles, 
// if they are 'flush': almost touching

#include <iostream>

struct R
{
    int x1,y1,x2,y2;
    int height() const { return y2-y1; }
    int width() const  { return y2-y1; }

    void normalize() 
    { 
        if (x1>x2) std::swap(x1,x2);
        if (y1>y2) std::swap(y1,y2);
    }

    /*
     * adjacent: return whether two rectangles
     * are adjacent; the tolerance in pixels
     * allow you to specify the gap:
     *    tolerance = 0: require at least one pixel overlap
     *    tolerance = 1: accepts 'flush' adjacent neighbours
     * Negative tolerance require more overlap;
     * tolerance > 1 allows gaps between rects;
     */
    bool adjacent(R const& other, int tolerance=1) const
    {
        return !( (other.x1 - x2) > tolerance
               || (x1 - other.x2) > tolerance
               || (other.y1 - y2) > tolerance
               || (y1 - other.y2) > tolerance);
    }
};

/* 
 * tolerance: see R::adjacent()
 * 
 * strict: only allow strict ('pure') combinations of rects
 */
R combined(R const& a, R const& b, int tolerance=1, bool strict=false)
{
    if (!a.adjacent(b, tolerance))
        throw "combined(a,b): a and b don't satisfy adjacency requirements (are the coords normalized?)";

    R r = { min(a.x1, b.x1), 1,1,1};
    r.x1 = min(a.x1, b.x1);
    r.y1 = min(a.y1, b.y1);
    r.x2 = max(a.x2, b.x2);
    r.y2 = max(a.y2, b.y2);

    if (!strict)
        return r;

    if ( (r.height() <= max(a.height(), b.height()))
     &&  (r.width () <= max(a.width (), b.width ())) )
        return r;
    else
        throw "combined(a,b): strict combination not available";
}

std::ostream& operator<<(std::ostream &os, R const& r)
{
    return os << '(' << r.x1 << "," << r.y1 << ")-(" << r.x2 << ',' << r.y2 << ')';
}

int main()
{
    const int tolerance = 1;
    {
        std::cout << "sample from original question" << std::endl;
        R a = { 0, 0,   320, 119 }; /* a.normalize(); */
        R b = { 0, 120, 320, 239 }; /* b.normalize(); */

        std::cout << "a: " << a << "\t b: " << b << std::endl;
        std::cout << "r: " << combined(a,b, tolerance) << std::endl;
    }
    {
        std::cout << "sample from the comment" << std::endl;
        R a = { 0, 0, 1, 320 }; /* a.normalize(); */
        R b = { 0, 0, 2, 320 }; /* b.normalize(); */

        std::cout << "a: " << a << "\t b: " << b << std::endl;

        // NOTE: strict mode
        std::cout << "r: " << combined(a,b, tolerance, true) << std::endl;
    }
}


Output:
1
2
3
4
5
6
sample from original question
a: (0,0)-(320,119)	 b: (0,120)-(320,239)
r: (0,0)-(320,239)
sample from the comment
a: (0,0)-(1,320)	 b: (0,0)-(2,320)
r: (0,0)-(2,320)


Create a new paste based on this one


Comments: