OpenGL直线剪裁

来源:互联网 发布:windows live影音 编辑:程序博客网 时间:2024/05/22 04:28

这次是用MFC+OpenGL写的,代码没法全部贴上,上传到下载栏目里好了。点击打开下载链接(现在好像不能上传0积分下载的东西了QAQ)


运行效果:
这里写图片描述
这里写图片描述
这里写图片描述


核心代码(剪裁的核心代码):

int GraphyCut::getCode(const Point a)       //得到编码{    int code = 0;    if (a.y > max(st.y, endd.y))        code |= 8;    if (a.y < min(st.y, endd.y))        code |= 4;    if (a.x > max(st.x, endd.x))        code |= 2;    if (a.x < min(st.x, endd.x))        code |= 1;    return code;}bool GraphyCut::isLinesAcross(const Line a, const Line b)       //跨立试验{    int num1 = (a.b.x - a.a.x)*(b.a.y - a.a.y) - (a.b.y - a.a.y)*(b.a.x - a.a.x);    int num2 = (a.b.x - a.a.x)*(b.b.y-a.a.y) - (a.b.y - a.a.y)*(b.b.x - a.a.x);    if (num1/abs(num1)*num2 <= 0)       //这里不能用乘法计算,因为可能出现溢出(难查的bug)        return true;    return false;}bool GraphyCut::isRemain(Line &line){    int code1 = getCode(line.a);    int code2 = getCode(line.b);    if (code1 == 0 && code2 == 0)       //在中间,保留        return true;    else if (code1&code2)       //边界外,舍去        return false;    else if (!(isLinesAcross(line, Line(st, endd)) || isLinesAcross(line, Line(Point(st.x, endd.y), Point(endd.x, st.y)))))    {        //进行跨立试验,如果不通过则表示在框外        return false;    }    else    {        if (fabs(line.a.x - line.b.x) <= 2)        {            if (line.a.y > max(st.y, endd.y))                line.a.y = max(st.y, endd.y);            else if (line.a.y < min(st.y, endd.y))                line.a.y = min(st.y, endd.y);            if (line.b.y > max(st.y, endd.y))                line.b.y = max(st.y, endd.y);            else if (line.b.y < min(st.y, endd.y))                line.b.y = min(st.y, endd.y);            return true;        }        do        {            if (code1 == 0 && code2 == 0)                break;            int code = code1 == 0 ? code2 : code1;            double x, y;            if (code&1)            {                y = line.a.y + (line.b.y - line.a.y)*(min(st.x,endd.x) - line.a.x) / (line.b.x - line.a.x);                x = (double)min(st.x,endd.x);            }            else if (code&2)            {                y = line.a.y + (line.b.y - line.a.y)*(max(st.x,endd.x) - line.a.x) / (line.b.x - line.a.x);                x = (double)max(st.x,endd.x);            }            else if (code&4)            {                x = line.a.x + (line.b.x - line.a.x)*(min(st.y,endd.y) - line.a.y) / (line.b.y - line.a.y);                y = (double)min(st.y,endd.y);            }            else if (code&8){                x = line.a.x + (line.b.x - line.a.x)*(max(st.y,endd.y) - line.a.y) / (line.b.y - line.a.y);                y = (double)max(st.y,endd.y);            }            if (code == code1)            {                line.a.x = x;                line.a.y = y;                code1 = getCode(line.a);            }            else            {                line.b.x = x;                line.b.y = y;                code2 = getCode(line.b);            }        } while (true);        return true;    }}void GraphyCut::CutLines(){    for (int i = 0; i < lines.size(); i++)    {        if (!isRemain(lines[i]))        {            lines.erase(lines.begin() + i);            i--;        }    }}