3

我正在尝试使用 DDA(数字差分分析仪)制作一种画线的算法,该算法也使用 Wu 的算法作为抗锯齿。

问题是输出看起来不太好。尤其是:

  • 我选择的颜色,它会改变(我知道为什么,但我想知道它是否必须是这样的)
  • 像素颜色越亮越亮

如何选择我想要的线条颜色?考虑到它受算法的影响?

这是代码:

void dda(int x0, int y0, int x1, int y1, int z, float red, float green, float blue) {
    float dy = y1-y0;
    float dx = x1-x0;
    float m = dy/dx;

    if (m<=1) {
        int x;
        float y;
        y = y0;
        for (x=x0; x<x1; x++) {
            pixel(x, round(y), z, frame, rfpart(red), rfpart(green), rfpart(blue));
            pixel(x, round(y)+1, z, frame, fpart(red), fpart(green), fpart(blue));
            y = y+m;
        }
    }
}

int round(float d) {
  return floor(d + 0.5);
}

float fpart(float x) {
    if (x < 0)
        return 1 - (x - floor(x));
    return x - floor(x);
}

float rfpart(float x) {
    return 1 - fpart(x);
}
4

1 回答 1

4
  1. 您的代码仅适用于第一个八分圆

    所以我希望你只在那里测试

  2. 你忘了混合背景颜色和线条颜色

    所以添加透明度或直接读取背景像素并自行混合颜色。系数将a,a0是透明度颜色混合的 alpha。在这种情况下,您不应更改r,g,b值,而应仅更改 alpha。此外,如果您知道背景颜色,您可以忽略像素的读取,但结果会在穿过已经渲染的东西时有点。

我将您的代码更改为与我在 C++ 中的编码兼容:

void DDA_line_antialiasing(int x0,int y0,int x1,int y1,int col) // DDA antialiasing
    {
    int   x,y,dx,dy,kx,ky,f,df;
    DWORD a,a0;
    union
        {
        DWORD dd;
        BYTE db[4];
        } c,c0;
    dx=x1-x0; kx=0; if (dx>0) kx=+1; else if (dx<0) { kx=-1; dx=-dx; }
    dy=y1-y0; ky=0; if (dy>0) ky=+1; else if (dy<0) { ky=-1; dy=-dy; }
    if (dx+dy==0)
        {
        pnt(x0,y0,col);
        pnt(x1,y1,col);
        return;
        }
    if (dx>=dy)
     for (df=(dy<<8)/dx,x=x0,y=y0,f=0;;f+=df,x+=kx)
        {
        // fixed point y step
        if (f>=256) { f-=256; y+=ky; }
        // line color + background color mixing
        c.dd=col; c0.dd=pnt(x,y); a=256-f; a0=f;
        c.db[0]=DWORD(((DWORD(c.db[0])*a)+(DWORD(c0.db[0])*a0))>>8);
        c.db[1]=DWORD(((DWORD(c.db[1])*a)+(DWORD(c0.db[1])*a0))>>8);
        c.db[2]=DWORD(((DWORD(c.db[2])*a)+(DWORD(c0.db[2])*a0))>>8);
        pnt(x,y   ,c.dd);
        // line color + background color mixing
        c.dd=col; c0.dd=pnt(x,y+ky); a=f; a0=256-f;
        c.db[0]=DWORD(((DWORD(c.db[0])*a)+(DWORD(c0.db[0])*a0))>>8);
        c.db[1]=DWORD(((DWORD(c.db[1])*a)+(DWORD(c0.db[1])*a0))>>8);
        c.db[2]=DWORD(((DWORD(c.db[2])*a)+(DWORD(c0.db[2])*a0))>>8);
        pnt(x,y+ky,c.dd);
        if (x==x1) break;
        }
    else
     for (df=(dx<<8)/dy,x=x0,y=y0,f=0;;f+=df,y+=ky)
        {
        // fixed point x step
        if (f>=256) { f-=256; x+=kx; }
        // line color + background color mixing
        c.dd=col; c0.dd=pnt(x,y); a=256-f; a0=f;
        c.db[0]=DWORD(((DWORD(c.db[0])*a)+(DWORD(c0.db[0])*a0))>>8);
        c.db[1]=DWORD(((DWORD(c.db[1])*a)+(DWORD(c0.db[1])*a0))>>8);
        c.db[2]=DWORD(((DWORD(c.db[2])*a)+(DWORD(c0.db[2])*a0))>>8);
        pnt(x,y   ,c.dd);
        // line color + background color mixing
        c.dd=col; c0.dd=pnt(x+kx,y); a=f; a0=256-f;
        c.db[0]=DWORD(((DWORD(c.db[0])*a)+(DWORD(c0.db[0])*a0))>>8);
        c.db[1]=DWORD(((DWORD(c.db[1])*a)+(DWORD(c0.db[1])*a0))>>8);
        c.db[2]=DWORD(((DWORD(c.db[2])*a)+(DWORD(c0.db[2])*a0))>>8);
        pnt(x+kx,y,c.dd);
        if (y==y1) break;
        }
    }


更改为定点(8 位小数部分)f,df
更改roundfloor(我的像素已经移动了一半)
添加了与背景颜色混合的颜色 用颜色 绘制
pnt(x,y,col);像素将像素从屏幕/图像读取为 32 位颜色(0x00RRGGBB)工会只是为了方便访问x,ycol
col=pnt(x,y);col
colr,g,b

示例输出

于 2015-05-03T08:34:08.417 回答