OpenGL直线剪裁

这次是用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--;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/wyg1997/article/details/78480442