原创 轮廓矩形边界与重心

2009-2-23 22:31 2581 9 9 分类: 软件与OS

    轮廓矩形边界即轮廓的左边界、上边界、右边界和下边界。采用线段表可以方便求得,直接求线段端点在水平方向和垂直方向的最小值和最大值即可。需要注意一个概念上的区别,轮廓矩形边界不等于轮廓的最小外接四边形。
    轮廓重心同样采用线段表进行计算,分别计算各线段在水平方向和垂直方向上的加权平均,其权重为线段长度。


#include <vector>


typedef std::vector<POINT> ptvecLineTable;


// 轮廓矩形边界
// 1. LineTable    线段表
BOOL ContourRect(ptvecLineTable LineTable, RECT *pRect)
{
    if (LineTable.empty())
    {
        pRect->left   = 0;
        pRect->top    = 0;
        pRect->right  = 0;
        pRect->bottom = 0;
    }
    else
    {
        pRect->left   = LineTable[0].x;
        pRect->top    = LineTable[0].y;
        pRect->right  = LineTable[0].x;
        pRect->bottom = LineTable[0].y;
        for (ptvecLineTable::iterator i = LineTable.begin(); i != LineTable.end(); i += 2)
        {
            if (pRect->left   > i->x)       pRect->left   = i->x;
            if (pRect->top    > i->y)       pRect->top    = i->y;
            if (pRect->right  < (i + 1)->x) pRect->right  = (i + 1)->x;
            if (pRect->bottom < i->y)       pRect->bottom = i->y;
        }
    }
    return TRUE;
}


// 轮廓重心
// 1. LineTable    线段表
BOOL ContourBarycenter(ptvecLineTable LineTable, POINT *pBarycenter)
{
    long lLength = 0;
    long lArea   = 0;
    pBarycenter->x = 0;
    pBarycenter->y = 0;
    for (ptvecLineTable::iterator i = LineTable.begin(); i != LineTable.end(); i += 2)
    {
        lLength = ((i + 1)->x - i->x + 1);
        pBarycenter->x += (lLength * ((i + 1)->x + i->x) / 2);
        pBarycenter->y += (lLength * i->y);
        lArea  += lLength;
    }
    pBarycenter->x /= lArea;
    pBarycenter->y /= lArea;
    return TRUE;
}


轮廓矩形边界与重心效果:

2e6ea7fe-050b-4911-812c-cc07e3e54ac9.gif630eff60-c0e0-4d67-bb6e-55c00d5e5c62.gif

文章评论0条评论)

登录后参与讨论
我要评论
0
9
关闭 站长推荐上一条 /2 下一条