Algoritmo de recorte de polígonos de Sutherland-Hodgeman

Objetivo:

Utilice el algoritmo de recorte de polígonos de Sutherland-Hodgeman para recortar el polígono que se muestra en la figura.Se requiere dibujar los gráficos correspondientes para cada clip e indicar los vértices de entrada y salida. Compruébalo con el programa de recorte de polígonos de Sutherland-Hodgeman escrito por ti mismo

Principio experimental:

Recorta el polígono un borde de la ventana a la vez.

Considere un borde de la ventana y la línea de recorte formada por la línea de extensión que divide el plano en dos partes: el lado visible y el lado invisible. Puntos extremos S y P de cada lado del polígono. Solo hay cuatro relaciones posicionales entre ellos y la línea de recorte.

La figura 1 solo genera un vértice P;

Figura 2 salidas 0 vértices;

la figura 3 genera un punto de intersección I del segmento de línea SP y la línea de recorte;

la figura 4 genera un punto de intersección I y un punto final P del segmento de línea SP y la línea de recorte;

Tres: pasos experimentales y código fuente

关键代码:
//判断点在线段的内侧还是外侧
int Inside(Point p, Boundary b, Point wMin, Point wMax)
{
    switch (b)
    {
    case Left:
        if (p.x < wMin.x) return (false);
        break;
    case Top:
        if (p.y > wMax.y) return (false);
        break;
    case Right:
        if (p.x > wMax.x) return (false);
        break;
    case Bottom:
        if (p.y < wMin.y) return (false);
        break;
    }
    return true;
}
//判断两点在同侧还是异侧
int Cross(Point p1, Point p2, Boundary b, Point wMin, Point wMax)
{
    if (Inside(p1, b, wMin, wMax) == Inside(p2, b, wMin, wMax))
        return (false);
    else
        return true;
}
//求交点
Point Intersect(Point p1, Point p2, Boundary b, Point    wMin, Point wMax)
{
    Point iPt = { 0,0 };
    float m = 0;
    if (p1.x != p2.x) m = (p2.y - p1.y) / (p2.x - p1.x);
    switch (b) 
    {
    case Left:
        iPt.x = wMin.x;
        iPt.y = p2.y + (wMin.x - p2.x) * m;
        break;
    case Right:
        iPt.x = wMax.x;
        iPt.y = p2.y + (wMax.x - p2.x) * m;
        break;
    case Bottom:
        iPt.y = wMin.y;
        if (p1.x != p2.x)iPt.x = p2.x + (wMin.y - p2.y) / m;
        else iPt.x = p2.x;
        break;
    case Top:
        iPt.y = wMax.y;
        if (p1.x != p2.x) iPt.x = p2.x + (wMax.y - p2.y) / m;
        else iPt.x = p2.x;
        break;
    }
    return iPt;
}
//返回裁剪后的顶点个数
int edgeCliper(Boundary b, Point wMin, Point wMax, Point* pIn, int cnt, Point* pOut)
{
    Point s;
    int i, Outcnt = 0;
    s = pIn[0];

    for (i = 1; i <= cnt; i++)
    {
        if (!Inside(s, b, wMin, wMax) && Inside(pIn[i], b, wMin, wMax))
        {
            pOut[Outcnt] = Intersect(s, pIn[i], b, wMin, wMax);
            Outcnt++;
            pOut[Outcnt] = pIn[i];
            Outcnt++;
        }
        else if (Inside(s, b, wMin, wMax) && Inside(pIn[i], b, wMin, wMax))
        {
            pOut[Outcnt] = pIn[i];
            Outcnt++;
        }
        else if (Inside(s, b, wMin, wMax) && (!Inside(pIn[i], b, wMin, wMax)))
        {
            pOut[Outcnt] = Intersect(s, pIn[i], b, wMin, wMax);
            Outcnt++;
        }
        s = pIn[i];
    }
    return (Outcnt);
}
void ClipPolygonSuthHodg(vector<VERTEX>& polygon)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    int i, cnt, Outcnt, b;
    Point points[6] = { {400, 100}, {500, 400}, {800, 100}, {600, 800}, {100, 500},{400, 100} };
    cnt = 5;
    Point pOut[20], pIn[20];
    Point wMin = { 200, 200 }, wMax = { 600, 600 };
    for (i = 0; i < 4 * cnt; i++)
    {
        pIn[i].x = 0.0;
        pIn[i].y = 0.0;
        pOut[i].x = 0.0;
        pOut[i].y = 0.0;
    }
    for (i = 0; i <= cnt; i++) pIn[i] = points[i];
    glColor3f(0.0, 0.0, 0.0);
    glBegin(GL_LINE_LOOP);
    glVertex2f(wMin.x, wMin.y);
    glVertex2f(wMax.x, wMin.y);
    glVertex2f(wMax.x, wMax.y);
    glVertex2f(wMin.x, wMax.y);
    glEnd();

    glLineWidth(1.0);
    glLineStipple(1, 0x0F0F);
    glBegin(GL_LINE_LOOP);
    for (i = 0; i < cnt; i++)
        glVertex2f(pIn[i].x, pIn[i].y);
    glEnd();
    for (b = 0; b < 4; b++)
    {
        Outcnt = edgeCliper(Boundary(b), wMin, wMax, pIn, cnt, pOut);
        for (int i = 0; i < Outcnt; i++)
            for (i = 0; i < Outcnt; i++)
                pIn[i] = pOut[i];
        pIn[Outcnt] = pOut[0];
        cnt = Outcnt;
    }
    glDisable(GL_LINE_STIPPLE);
    glLineWidth(2.0);
    glColor3f(1.0, 0.0, 0.0);
    glBegin(GL_LINE_LOOP);
    for (i = 0; i < cnt; i++)
        glVertex2f(pOut[i].x, pOut[i].y);
    glEnd();
    glFlush();
}

Resultados Experimentales y Análisis

Gráficos originales:

Gráficos recortados

Análisis: Los gráficos recortados según el algoritmo del polígono se muestran en la línea roja de arriba, que es lo que queremos. Recortar cada borde una vez volverá a obtener una secuencia de vértices. Los cuatro bordes se cortan cuatro veces en total. La idea del algoritmo no es difícil, pero la implementación del algoritmo es más problemática y el cálculo del punto de intersección también es un poco difícil.

Supongo que te gusta

Origin blog.csdn.net/weixin_52732185/article/details/129134073
Recomendado
Clasificación