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--;
        }
    }
}
發佈了688 篇原創文章 · 獲贊 134 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章