Есть ли эффективная линейная функция Xiaolin Wu с SDL (или дополнением)?

Я сделал программу на C++ с SDL2, которая рисует кривую из списка точек, связывая их линиями. Я предполагаю, что я использую функцию SDL_RenderDrawLine, которая основана на алгоритме Брезенхэма.

Затем я сделал другую функцию, основанную на алгоритме Сяолин Ву, чтобы заменить SDL (потому что она более плавная). Это работает хорошо, но это намного (намного!) Медленнее, чем функция SDL. На самом деле я изо всех сил стараюсь рисовать более дюжины линий в секунду, тогда я могу без проблем рисовать тысячи линий в секунду с помощью функции SDL.

Поэтому я ищу библиотеку SDL, в которой алгоритм Сяолиня Ву уже реализован, потому что компьютерщики, конечно, лучше меня. Эта библиотека существует? Или я должен сделать это сам?

Если я должен сделать это сам, у вас есть советы, чтобы улучшить мою функцию? Вот он, основанный на псевдокоде Википедии:

void drawXWLine(SDL_Renderer *renderer, double x1, double y1, double x2, double y2, SDL_Color color, uint8_t a)
{
    double dx = x2 - x1;
    double dy = y2 - y1;

    if (abs(dx) > abs(dy)) // horizontal lines
    {
        if (x2 < x1)
        {
            // swap the two points
        }

        double gradient = dy / dx;

        // draw the extreme points of the line
        int xend, xpxl1, xpxl2, ypxl1, ypxl2;
        double yend, xgap, intery;
        xend = round(x1);
        yend = y1 + gradient * (xend - x1);
        xgap = 1.0 - mod(x1 + 0.5, 1.0);
        xpxl1 = xend;
        ypxl1 = int(yend);
        SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, uint8_t((1.0 - mod(yend, 1.0)) * xgap * a));
        SDL_RenderDrawPoint(renderer, xpxl1, ypxl1);
        SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, uint8_t(mod(yend, 1.0) * xgap * a));
        SDL_RenderDrawPoint(renderer, xpxl1, ypxl1+1);
        intery = yend + gradient;

        xend = round(x2);
        yend = y2 + gradient * (xend - x2);
        xgap = 1.0 - mod(x2 + 0.5, 1.0);
        xpxl2 = xend;
        ypxl2 = int(yend);
        SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, uint8_t((1.0 - mod(yend, 1.0)) * xgap * a));
        SDL_RenderDrawPoint(renderer, xpxl2, ypxl2);
        SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, uint8_t(mod(yend, 1.0) * xgap * a));
        SDL_RenderDrawPoint(renderer, xpxl2, ypxl2+1);

        // draw the whole line
        for(int x = xpxl1 + 1 ; x < xpxl2 ; x++)
        {
            SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, uint8_t((1.0 - mod(intery, 1.0)) * xgap * a));
            SDL_RenderDrawPoint(renderer, x, int(intery));
            SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, uint8_t(mod(intery, 1.0) * xgap * a));
            SDL_RenderDrawPoint(renderer, x, int(intery)+1);

            intery += gradient;
        }
    }
    else
    {
        // do the same with vertical lines
    }
}

0 ответов

Другие вопросы по тегам