我重写了以下代码:
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);
}
}
}
使用triangle(100, 100, 100, 400, 400, 100, image, red);
它可以正常工作。
但如果我交换X(xa,ya)和Z(xc,yc)坐标而不填充我的方格。
使用triangle(70, 50, 200, 100, 20, 150, image, red);
,它会绘制三角形,但会填充comes out of bounds.
问题出在哪里?
答案 0 :(得分:1)
如果它有点帮助这里是VCL / GDI中三角形的古老C ++源:
//---------------------------------------------------------------------------
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;
}
//---------------------------------------------------------------------------
示例用法:
// 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 ...
来源基于:
答案 1 :(得分:0)
每个循环都会增加x和y。但是你不能为每个三角形做到这一点。当x增加时,取决于三角形角度,可能y减小。例如,如果三角形为90度,则不会增加x或y。我不能很好地解释自己,但有代码和图像解释:
http://www.sunshine2k.de/coding/java/TriangleRasterization/TriangleRasterization.html
答案 2 :(得分:0)
此算法有效:
void function fill_triangle(x1,y1,x2,y2,x3,y3)
//get length of all sides
d1 = sqrt(((y2-y1)**2)+((x2-x1)**2))
d2 = sqrt(((y3-y2)**2)+((x3-x2)**2))
d3 = sqrt(((y1-y3)**2)+((x1-x3)**2))
if(((d1<d2)or(d1=d2))and((d1<d2)or(d1=d2))) //the first side is the shortest
tx = x1
ty = y1
vx = (x2-x1)/d1
vy = (y2-y1)/d1
counter = 0
while(counter<d1)
draw_line(x3,y3,tx,ty)
//drawing a line from point(x3,y3) to point(tx,ty).
tx = tx + vx
ty = ty + vy
counter = counter + 1
else if((d2<d3)or(d2=d3)) //the second side is the shortest
tx = x2
ty = y2
vx = (x3-x2)/d2
vy = (y3-y2)/d2
counter = 0
while(counter<d2)
draw_line(x1,y1,tx,ty)
tx = tx + vx
ty = ty + vy
counter = counter + 1
else // the third side is shortest
tx = x3
ty = y3
vx = (x1-x3)/d3
vy = (y1-y3)/d3
counter = 0
while(counter<d3)
draw_line(x2,y2,tx,ty)
tx = tx + vx
ty = ty + vy
counter = counter + 1
它在做什么的视觉解释: