Lijnen trekken in Hexnut 2

In het hexnut-2 project hadden we een aantal grafische functies nodig. Één daarvan was om lijnen te tekenen. Nou heb ik die al eens eerder gemaakt, maar daar was ik niet helemaal tevreden over dus ging ik op zoek naar een nieuwe methode. En nou is de Bresenham functie daar ideaal voor.

Omdat een pure Bresenham functie toch echt té blokkerig was, heb ik na enig experimenteren de volgende geoptimaliseerde functie gemaakt:

void glcdLine(u08 x0, u08 y0, u08 x1, u08 y1, u08 color) {
    int dy = y1 - y0;
    int dx = x1 - x0;
    int stepx, stepy;
    if (dy < 0) {
        dy = -dy;
        stepy = -1;
    } else {
        stepy = 1;
    }
    if (dx < 0) {
        dx = -dx;
        stepx = -1;
    } else {
        stepx = 1;
    }
    dy <<= 1; // dy is now 2*dy
    dx <<= 1; // dx is now 2*dx

    if (color)
        glcdSetDot(x0, y0);
    else
        glcdClearDot(x0, y0);

    if (dx > dy) {
        int fraction = dy - (dx >> 1); // same as 2*dy - dx
        while (x0 != x1) {
            if (fraction >= 0) {
                y0 += stepy;
                fraction -= dx; // same as fraction -= 2*dx
            }
            x0 += stepx;
            fraction += dy; // same as fraction -= 2*dy

            if (color)
                glcdSetDot(x0, y0);
            else
                glcdClearDot(x0, y0);
        }
    } else {
        int fraction = dx - (dy >> 1);
        while (y0 != y1) {
            if (fraction >= 0) {
                x0 += stepx;
                fraction -= dy;
            }
            y0 += stepy;
            fraction += dx;
            if (color)
                glcdSetDot(x0, y0);
            else
                glcdClearDot(x0, y0);
        }
    }
}

Deze functie is afhankelijk van 2 functies. Eentje om een pixel aan te zetten, en een om een pixel weer uit te zetten.

 

Het resultaat kun je in het volgende plaatje zien:

 

 

Comments

2

 

#include <stdio.h>
#include <SDL/SDL.h>
#include <math.h>

#define WIDTH 640
#define HEIGHT 480
#define BPP 4
#define DEPTH 32

SDL_Surface *screen;

void putpixel(SDL_Surface* scr, int x, int y, int color) {
    unsigned int *ptr = (unsigned int*) scr->pixels;
    int lineoffset = y * (scr->pitch / 4);
    ptr[lineoffset + x] = color;
}

void glcdSetDot(Uint8 x, Uint8 y) {
    putpixel(screen, x, y, 0xffffff);
}

void glcdClearDot(Uint8 x, Uint8 y) {
    putpixel(screen, x, y, 0x000000);
}

void TekenScherm(SDL_Surface* scr) {

    if (SDL_MUSTLOCK(scr)) {
        if (SDL_LockSurface(scr) < 0)
            return;
    }
#if 0
    u_int8_t i;
    for (i = 0; i < 128; i++) {
        glcdLine(0, 0, i, 63, 1);

    }
    for (i = 0; i < 64; i++) {
        glcdLine(0, 0, 128, i, 1);

    }

#endif
    int rad;
    int radius = 32;
    for (rad=0; rad<628; rad+=2) {
        uint8_t x = 63 + radius * sin(rad / 100.0);
        uint8_t y = 32 + radius * cos(rad / 100.0);
        glcdLine(63,32,x,y,1);
    }
    if (SDL_MUSTLOCK(scr))
        SDL_UnlockSurface(scr);

    SDL_Flip(scr);
}

int main(int argc, char* argv[]) {
    //SDL_Surface *screen;
    SDL_Event event;

    int keypress = 0;
    int stop = 0;
    //  int h = 0;

    if (SDL_Init(SDL_INIT_VIDEO) < 0)
        return 1;

    if (!(screen = SDL_SetVideoMode(WIDTH, HEIGHT, DEPTH, SDL_FULLSCREEN
                                    | SDL_HWSURFACE))) {
        SDL_Quit();
        return 1;
    }

    while (!stop) {

        while (SDL_PollEvent(&event)) {
            switch (event.type) {
            case SDL_QUIT:
                stop = 1;
                break;
            case SDL_KEYDOWN:
                keypress++;
                TekenScherm(screen);
                break;
            }

        }
        if (keypress > 1)
            stop = 1;
    }

    SDL_Quit();

    return 0;
}


Dit is een voorbeeld van hoe je dit met SDL kan testen. Compile met : gcc -lSDL test.c -o testsdl Pre tags en font colors doen het niet, groet, Edwin van den Oetelaar

Gasten mogen alleen filtered HTML gebruiken, vandaar. Omdat je zulke prachtige kleuren hebt gebruikt heb ik je commentaar aangepast.