smooth color interpolation along a “bresenham” lin

2019-07-16 11:32发布

问题:

I am trying to interpolate color along a line so that, given two points and their respective RGB values, I can draw a line with a smooth color gradient. Using Bresenham's Line Algorithm, I can now draw lines, but am not sure how to begin interpolating colors between the two end points. The following is part of the drawLine() function that works for all line whose slope are less than 1.

    int x_start = p1.x, x_end = p2.x, y_start =p1.y, y_end = p2.y;
    int dx = Math.abs(x_end-x_start), dy = Math.abs(y_end-y_start);

    int x = x_start, y = y_start;       
    int step_x = x_start < x_end ? 1:-1;
    int step_y = y_start < y_end ? 1:-1;

    int rStart = (int)(255.0f * p1.c.r), rEnd = (int)(255.0f * p2.c.r);
    int gStart = (int)(255.0f * p1.c.g), gEnd = (int)(255.0f * p2.c.g);
    int bStart = (int)(255.0f * p1.c.b), bEnd = (int)(255.0f * p2.c.b);

    int xCount = 0;


//for slope < 1
        int p = 2*dy-dx;
        int twoDy = 2*dy, twoDyMinusDx = 2*(dy-dx);         
        int xCount = 0;

        // draw the first point
        Point2D start = new Point2D(x, y, new ColorType(p1.c.r, p1.c.g, p1.c.b));           
        drawPoint(buff, start);

        float pColor = xCount / Math.abs((x_end - x_start));
        System.out.println(x_end + "  " + x_start);

        while(x != x_end){
            x+= step_x;
            xCount++;
            if(p<0){
                p+= twoDy;
            }
            else{
                y += step_y;
                p += twoDyMinusDx;
            }

            Point2D draw_line = new Point2D(x, y, new ColorType(p1.c.r*(1-pColor)+p2.c.r*pColor,p1.c.g*(1-pColor)+p2.c.g*pColor,p1.c.b*(1-pColor)+p2.c.b*pColor));
            System.out.println(pColor);
            drawPoint(buff,draw_line );
        }

So what I'm thinking is that, just like drawing lines, I also need some sort of decision parameter p to determine when to change the RGB values. I am thinking of something along lines of as x increments, look at each rgb value and decide if I want to manipualte them or not.

I initialized rStart and rEnd(and so on for g and b) but have no idea where to start. any kind of help or suggestions would be greatly appreciated!

Edit: thanks @Compass for the great suggestion ! Now I've ran into another while trying to implementing that strategy, and I am almost certain it's an easy bug. I just can't see it right now. For some reason my pColor always return 0, I am not sure why. I ran some print statements to make sure xCount is indeed increasing, so I am not sure what else might've made this variable always 0.

回答1:

I remember figuring this out way back when I was learning GUI! I'll explain the basic concepts for you.

Let's say we have two colors, RGB(A,B,C) and RGB(X,Y,Z) for simplicity.

If we know the position percentage-wise (we'll call this P, a float 0 for beginning, 1.0 at end) along the line, we can calculate what color should be there using the following:

Resultant Color = RGB(A*(1-P)+X*P,B*(1-P)+Y*P,C*(1-P)+Z*P)

In other words, you average out the individual RGB values along the line.



回答2:

Actually you will be drawing the line in RGB space as well !

Bresenham lets you compute point coordinates from (X0, Y0) to (X1, Y1).

This is done by a loop on X or Y, with a linear interpolation on the other coordinate.

Just extend the algorithm to draw a line from (X0, Y0, R0, G0, B0) to (X1, Y1, R1, G1, B1), in the same loop on X or Y, with a linear interpolation on the other coordinates.