算法填充三角形 [英] Algorithm to fill triangle

查看:116
本文介绍了算法填充三角形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在考虑栅格化三角算法。 ( triangle_rasterization_lesson



我使用下面的代码:

  void triangle(int xa, int ya,int xb,int yb,int xc,int yc,TGAImage& image,TGAColor color)
{
line(xa,ya,xb,yb,image,color);
line(xa,ya,xc,yc,image,color);
line(xb,yb,xc,yc,image,color);
for(int x = xa; x <= xb; x ++)
{
for(int y = ya; y <= yb; y ++)
{
line(xc,yc,x,y,image,white);


$ b $ / code>

使用三角形(100,100,100,400,400,100,图像,红色); 它正常工作。
但是,如果我将X(xa,ya)和Z(xc,yc)的坐标交换为不能填充我的方形。

使用三角形(70,50,200,100,20,150,图片,红色); 绘制三角形,但填充出界





解决方案

lang-cpp prettyprint-override> // ---------------------------------- -----------------------------------------
class gfx_main
{
public:
Graphics :: TBitmap * bmp;
int ** pyx,xs,ys;
gfx_main();
〜gfx_main();
void resize(int _xs = -1,int _ys = -1);

void troj(int x0,int y0,int x1,int y1,int x2,int y2,int col); //这是填充三角形
void _troj_line(int * pl,int * pr,int x0,int y0,int x1,int y1); //这只是子程序
};
// -------------------------------------------- -------------------------------
gfx_main :: gfx_main()
{
bmp = new Graphics :: TBitmap;
pyx = NULL;
调整大小(1,1);
}
// --------------------------------------- ------------------------------------
gfx_main ::〜gfx_main()
{
delete bmp;
if(pyx)delete [] pyx;
}
// --------------------------------------- ------------------------------------
void gfx_main :: resize(int _xs,int _ys)
{
if(pyx)delete [] pyx; ((_xs> 0)&&(_ ys> 0)){bmp-> Width = _xs; BMP->身高= _ys; }
xs = bmp->宽度;
ys = bmp->高度;
bmp-> HandleType = bmDIB;
bmp-> PixelFormat = pf32bit;
pyx = new int * [ys]; (int y = 0; y< ys; y ++)pyx [y] =(int *)bmp-> ScanLine [y];
}
// --------------------------------------- ------------------------------------
// ---光栅化:--- -------------------------------------------------- -
// ------------------------------------------ ---------------------------------
void gfx_main :: _ troj_line(int * pl,int * pr ,int x0,int y0,int x1,int y1)
{
int * pp;
int x,y,kx,ky,dx,dy,k,m,p;
// DDA变量(d)abs delta,(k)步进方向
kx = 0; DX = X1-X0;如果(dx> 0)kx = + 1;如果(dx< 0){kx = -1; DX = -dx; }
ky = 0; DY = Y1-Y0;如果(dy> 0)ky = + 1;如果(dy <0){ky = -1; DY = -dy; }
//根据ky方向的目标缓冲区
if(ky> 0)pp = pl; else pp = pr;
//整数DDA线起点
x = x0; Y = Y0;
//修正端点只是为了确定(错误的除法常量+/- 1会导致最后一点丢失)
pp [y1] = x1;第[Y0] = X0;
if(dx> = dy)// x轴为主
{
k = dy + dy;
m =(dy-dx); M + =米;
p = m; $(b; b)为(;;)
{
pp [y] = x;
if(x == x1)break;
x + = kx;
if(p> 0){y + = ky; P + =米; } else p + = k;
}
}
else {// y轴是主
k = dx + dx;
m =(dx-dy); M + =米;
p = m; $(b; b)为(;;)
{
pp [y] = x;
if(y == y1)break;
y + = ky;
if(p> 0){x + = kx; P + =米; } else p + = k;
}
}
}
// ----------------------------- ----------------------------------------------
int rgb2bgr(int col)
{
union
{
BYTE db [4];
int dd;
} c;
BYTE q;
c.dd = col;
q = c.db [0]; c.db [0] = c.db [2]; c.db [2] = Q;
返回c.dd;
}
// --------------------------------------- ------------------------------------
void gfx_main :: troj(int x0,int y0,int x1,int y1,int x2,int y2,int col)
{
col = rgb2bgr(col);
int * pl,* pr; //左/右缓冲区
pl = new int [ys];
pr = new int [ys];
int x,y,yy0,yy1,xx0,xx1;
//边界线坐标到缓冲区
_troj_line(pl,pr,x0,y0,x1,y1);
_troj_line(pl,pr,x1,y1,x2,y2);
_troj_line(pl,pr,x2,y2,x0,y0);
// y范围
yy0 = y0;如果(yy0> y1)yy0 = y1;如果(yy0> y2)yy0 = y2;
yy1 = y0; if(yy1 //用水平线填充
for(y = yy0; y <= yy1; y ++)
{
if(pl [y] else {xx1 = pl [y]; XX0 = PR [Y]; }
for(x = xx0; x <= xx1; x ++)
pyx [y] [x] = col;
}
delete [] pl;
delete [] pr;
}
// --------------------------------------- ------------------------------------

示例用法:
$ b

  / / init 
gfx_main gfx;
gfx.resize(640,480);
//清除屏幕
TCanvas * scr = gfx.bmp->画布;
scr-> Pen - > Color = clAqua;
scr->字体 - >颜色= clYellow;
scr-> Brush-> Color = clBlack;
scr-> FillRect(TRect(0,0,xs,ys));
//三角形
troj(10,10,120,60,70,100,clAqua);
//这里gfx.bmp包含渲染的图像...

来源基于这:


i'm thinking about rasterization triangle algorithm. ( triangle_rasterization_lesson )

I wtote the following code:

void triangle(int xa, int ya, int xb, int yb, int xc, int yc, TGAImage &image, TGAColor color)
{
    line(xa, ya, xb, yb, image, color);
    line(xa, ya, xc, yc, image, color);
    line(xb, yb, xc, yc, image, color);
    for (int x = xa; x<=xb; x++)
    {
        for (int y = ya; y<=yb; y++)
        {
            line(xc, yc, x, y, image, white);
        }
    }
}

With triangle(100, 100, 100, 400, 400, 100, image, red); it works properly. But if i swap X(xa, ya) and Z(xc, yc) coordinates to doesn't fill my square.

With triangle(70, 50, 200, 100, 20, 150, image, red); it draws triangle, but filling comes out of bounds.

Where is the problem?

解决方案

if it helps a bit here is my ancient C++ source for triangle in VCL/GDI:

//---------------------------------------------------------------------------
class gfx_main
    {
public:
    Graphics::TBitmap *bmp;
    int **pyx,xs,ys;
    gfx_main();
    ~gfx_main();
    void resize(int _xs=-1,int _ys=-1);

    void troj(int x0,int y0,int x1,int y1,int x2,int y2,int col); // this is filled triangle
    void _troj_line(int *pl,int *pr,int x0,int y0,int x1,int y1); // this is just subroutine
    };
//---------------------------------------------------------------------------
gfx_main::gfx_main()
    {
    bmp=new Graphics::TBitmap;
    pyx=NULL;
    resize(1,1);
    }
//---------------------------------------------------------------------------
gfx_main::~gfx_main()
    {
    delete bmp;
    if (pyx) delete[] pyx;
    }
//---------------------------------------------------------------------------
void gfx_main::resize(int _xs,int _ys)
    {
    if (pyx) delete[] pyx;
    if ((_xs>0)&&(_ys>0)) { bmp->Width=_xs; bmp->Height=_ys; }
    xs=bmp->Width;
    ys=bmp->Height;
    bmp->HandleType=bmDIB;
    bmp->PixelFormat=pf32bit;
    pyx=new int*[ys];
    for (int y=0;y<ys;y++) pyx[y]=(int*)bmp->ScanLine[y];
    }
//---------------------------------------------------------------------------
//--- rasterisations: -------------------------------------------------------
//---------------------------------------------------------------------------
void gfx_main::_troj_line(int *pl,int *pr,int x0,int y0,int x1,int y1)
    {
    int *pp;
    int x,y,kx,ky,dx,dy,k,m,p;
    // DDA variables (d)abs delta,(k)step direction
    kx=0; dx=x1-x0; if (dx>0) kx=+1;  if (dx<0) { kx=-1; dx=-dx; }
    ky=0; dy=y1-y0; if (dy>0) ky=+1;  if (dy<0) { ky=-1; dy=-dy; }
    // target buffer according to ky direction
    if (ky>0) pp=pl; else pp=pr;
    // integer DDA line start point
    x=x0; y=y0;
    // fix endpoints just to be sure (wrong division constants by +/-1 can cause that last point is missing)
    pp[y1]=x1; pp[y0]=x0;
    if (dx>=dy) // x axis is major
        {
        k=dy+dy;
        m=(dy-dx); m+=m;
        p=m;
        for (;;)
            {
            pp[y]=x;
            if (x==x1) break;
            x+=kx;
            if (p>0) { y+=ky; p+=m; } else p+=k;
            }
        }
    else{       // y axis is major
        k=dx+dx;
        m=(dx-dy); m+=m;
        p=m;
        for (;;)
            {
            pp[y]=x;
            if (y==y1) break;
            y+=ky;
            if (p>0) { x+=kx; p+=m; } else p+=k;
            }
        }
    }
//---------------------------------------------------------------------------
int rgb2bgr(int col)
    {
    union
        {
        BYTE db[4];
        int  dd;
        } c;
    BYTE q;
    c.dd=col;
    q=c.db[0]; c.db[0]=c.db[2]; c.db[2]=q;
    return c.dd;
    }
//---------------------------------------------------------------------------
void gfx_main::troj(int x0,int y0,int x1,int y1,int x2,int y2,int col)
    {
    col=rgb2bgr(col);
    int *pl,*pr;        // left/right buffers
    pl=new int[ys];
    pr=new int[ys];
    int x,y,yy0,yy1,xx0,xx1;
    // boundary line coordinates to buffers
    _troj_line(pl,pr,x0,y0,x1,y1);
    _troj_line(pl,pr,x1,y1,x2,y2);
    _troj_line(pl,pr,x2,y2,x0,y0);
    // y range
    yy0=y0; if (yy0>y1) yy0=y1; if (yy0>y2) yy0=y2;
    yy1=y0; if (yy1<y1) yy1=y1; if (yy1<y2) yy1=y2;
    // fill with horizontal lines
    for (y=yy0;y<=yy1;y++)
        {
        if (pl[y]<pr[y]) { xx0=pl[y]; xx1=pr[y]; }
        else             { xx1=pl[y]; xx0=pr[y]; }
        for (x=xx0;x<=xx1;x++)
         pyx[y][x]=col;
        }
    delete[] pl;
    delete[] pr;
    }
//---------------------------------------------------------------------------

example usage:

// init
gfx_main gfx;
gfx.resize(640,480);
// clear screen
TCanvas *scr=gfx.bmp->Canvas;
scr->Pen  ->Color=clAqua;
scr->Font ->Color=clYellow;
scr->Brush->Color=clBlack;
scr->FillRect(TRect(0,0,xs,ys));
// triangle    
troj(10,10,120,60,70,100,clAqua);
// here gfx.bmp holds the rendered image ...    

Source is based on this:

这篇关于算法填充三角形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆