直线裁剪算法

const static int min_clip_x = 200;
const static int min_clip_y = 200;

const static int max_clip_x = 760;
const static int max_clip_y = 440;

#define WEST  0b0001
#define EAST  0b0010
#define SOURTH 0b0100
#define NORTH  0b1000

// 进行直线裁剪
void ZorderLayer::clipLine(int x1,int y1,int x2,int y2)
{
    
    // 排除部分 裁剪区域外的情况
    int code1,code2;
    
    // 是否裁剪结束
    bool done = false;
    
    // 是否需要绘制
    bool plotLine = false;
    
    // 斜率
    float k = 0;
    
    while (!done) {
        
        code1 = getEncode(x1,y1);
        code2 = getEncode(x2,y2);
        
        if (accept(code1, code2)) {
            done = true;
            plotLine = true;

        }else
        {
            if (reject(code1,code2)) {
                done = true;
            }else
            {
                if (inside(code1)) {
                    //若lineBegin端点在裁剪区内则交换两个端点使它在裁剪区外
                    int temp_x = x1;
                    int temp_y = y1;
                    x1 = x2;
                    y1 = y2;
                    x2 = temp_x;
                    y2 = temp_y;
                    
                    int temp_code = code1;
                    code1 = code2;
                    code2 = temp_code;
                }
                
                //计算斜率
                if (x1 != x2) {
                    k = (float)(y1 - y2)/(float)(x1 - x2);
                }
                
                //开始裁剪,以下与运算若结果为真,
                //则lineBegin在边界外,此时将lineBegin移向直线与该边界的交点
                if (code1 & WEST) {
                    x1  = min_clip_x;
                    y1 = y1 + k*(min_clip_x - x1);
                }else if (code1 & EAST)
                {
                    x1 = max_clip_x;
                    y1 = y1 + k * (max_clip_x - x1);
                }else if (code1 & SOURTH)
                {
                    y1 = min_clip_y;
                    if (x1 != x2) {
                        x1 = x1  + (min_clip_y - y1)/k;
                    }
                }else if (code1 & NORTH)
                {
                       y1 = max_clip_y;
                    if (x1 != x2) {
                        x1 = x1  + (max_clip_y - y1)/k;
                    }
                }
            }
        }
    }
    
    
    if (plotLine) {
        ccDrawLine(ccp(x1, y1), ccp(x2, y2));
    }

}



int ZorderLayer::getEncode(int x1,int y1)
{
    int code = 0;
    if (x1 < min_clip_x) {
        code |= WEST ;
    }
    
    if (x1 > max_clip_x) {
        code |= EAST;
    }
    
    if (y1 < min_clip_y) {
        code |= SOURTH;
    }
    
    if (y1 > max_clip_y) {
        code |= NORTH;
    }
    return  code;
}


// 能否完全接受一条直线
bool ZorderLayer::accept(int c1,int c2)
{
     int result = c1 | c2;
    if (result > 0) {
        return  false;
    }else
    {
        return true;
    }
}


// 能否完全排除一条直线
bool ZorderLayer::reject(int c1,int c2)
{
    return c1 & c2;
}

// 判断是否在裁剪区域内
bool ZorderLayer::inside(int c1){
    return !c1;
}

posted @ 2013-10-21 17:35  Dai Hanlong  阅读(264)  评论(0)    收藏  举报