растеризовать полигон с антиалиазингом
От: linux_fan  
Дата: 25.10.09 09:34
Оценка:
Здравствуйте аткой вопрос, хочу понять как можно растеризовать полигон с антиалиазингом
Заполнить полигон проблем особых не вижу, сам антиалиазинг я так понимаю нужен только при рисовании границ полигона, то есть при растеризации ребер.
По сути ребро представляет собой прямую, и соответственно прозрачность пикселя прямо пропорционально той площади, которую он занимает в многоугольнике.
Мне кажется грубый метод наверное выглядит, так, что есть ребро (x1. y1) и (x2. y2) x1 < x2, y1 < y2 и для простоты ребро лежит в первом октанте ось У — направлена в верх,
Его можно представить прямой y = k * x + b,
где k = y2 – y1 / x2 – x1, b = y1 – k * x1;



Допустим я иду по Брезенхему и в каждом получившемся пикселе считаю его площадь, лежащею справа от прямой, в результате пересечения пикселя и прямой получиться трапеция, либо треугольник



То есть, к примеру, Брезенхем выдал координаты Xi, Yi,

То пересечение ребра с осью Yi , будет равно
Xo = (Yi – b) / k. если Xo получается больше Xi + 1, то у нас площадь равна площади треугольника, с катетами k1 = k (Xi + 1) + b, и k2 = ((Yi – 1) – b) / k, иначе площадь ограничивается трапецией с высотой равной высоте пикселя и основаниями Xo и k2 = ((Yi – 1) – b) / k.
И так в принципе можно исходя из площади задавать прозрачность пикселю, для того что бы работать с целочисленными координатами увеличить размер пикселя к примеру в 256 раз. Для последующего вычисления площади использовать сохраненные ранее значения пересечений с Xi и Yi.
Но вот вопрос в Брезенхеме уже есть вычисление ошибки можно ли как то ее попытаться использовать для оценке величины прозрачности пикселя.


    void line(int x1, int y1, int x2, int y2) 
    {
           int dx = abs(x2 - x1);
        int dy = abs(y2 - y1);

            int sx = x2 >= x1 ? 1 : -1;
            int sy = y2 >= y1 ? 1 : -1;
            if(dy <= dx)
            {
                int derr = (dy << 1) - dx;
                int dS = dy << 1;
                int  dD = (dy - dx) << 1;
                m_ren->blend_pixel(x1, y1, m_line_color);
                for (int x = x1 + sx, y = y1, i = 1; i <= dx; i++, x += sx)
                {

                    if(derr > 0)
                    {
                        derr += dD;
                        y += sy;
                    }
                    else 
                    {
                        derr += dS;
                    }
                    m_ren->blend_pixel(x, y, m_line_color, cover_full);
                }


            }
            else 
            {
                int derr = (dx << 1) - dy;
                int dS = dx << 1;
                int  dD = (dx - dy) << 1;
                m_ren->blend_pixel(x1, y1, m_line_color, cover_full);
                
                for (int x = x1 , y = y1 + sy, i = 1; i < dy; ++i, y += sy)
                {
                            if (derr > 0)
                    {

                        derr += dD;
                        x += sx;
                    }
                    else
                    {
                        derr += dS;
                    }
                 
                  m_ren->blend_pixel(x, y, m_line_color, cover_full);
                     }
            }
        }


Хотелось бы использовать derr, без дополнительного вычисления площадей.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.