求基本图形的算法
求直线、圆、椭圆、多边形地各种算法,请高手帮帮忙
回复 1# 的帖子
void CDDAlineView::DDAline(int x0, int y0, int x1, int y1, COLORREF color, CDC *pDC){
int x;
double dx, dy, k, y;
dx = x1 - x0;
dy = y1 - y0;
k = dy/dx;
y = y0;
/* //|k|>1时把x与y互换,y每增加1,x相应增加1/k
if(k>1 || k<-1)
{
x = x0;
for(y=y0; y<=y1; y++)
{
pDC->SetPixel(y, int(x+0.5), color);
x = x + 1/k;
}
}
else
*/
for(x=x0; x<=x1; x++)
{
pDC->SetPixel(x, int(y+0.5), color);
y = y +k;
}
}
//中点画线发
void CDDAlineView::MidpointLine(int x0, int y0, int x1, int y1, COLORREF color, CDC *pDC)
{
//中点画线法
int a, b, deltal, delta2, d, x, y;
a = y0 - y1;
b = x1 - x0; //F(x0,y0)=ax0+by0+c=0 代入点(x1,y1)得到a=y0-y1;b=x1-x0;
d = 2 * a + b; //d的初始值 d0=a(x0+1)+b(y0+0.5)+c=F(x0,y0)+a+0.5b=a+0.5b
deltal = 2 * a; //d大于0的时候应该取正右方的哪个象素 d的增量为a
delta2 = 2 * (a + b); //d小于0的时候应该取右上方的哪个象素 d的增量为a+b
//用2d来代替d,避免了小数点的出现 我们使用的仅仅是d的符号 用2d是一样的
x = x0;
y = y0;
pDC->SetPixel(x, y, color);
while(x<x1)
{
if(d<0)
{
x++; y++;
d += delta2;
}
else
{
x++;
d += deltal;
}
pDC->SetPixel(x, y, color);
}
}
//Bresenham画线法
void CDDAlineView::Bresenham_Line(int x0, int y0, int x1, int y1, COLORREF color, CDC *pDC)
{
int x, y, dx, dy;
double k, e;
dx = x1 - x0;
dy = y1 - y0;
k = dy/dx;
e= -0.5; x = x0; y = y0;
for(int i=0; i<=dx; i++)
{
pDC->SetPixel(x,y,color);
x = x + 1;
e = e + k;
if(e>=0)
{
y = y + 1;
e = e - 1;
}
}
/* //为了避免小数和除法可以用以下方法实现 e'=2*e*dx;
int x, y, dx, dy;
double e;
dx = x1 - x0;
dy = y1 - y0;
k = dy/dx;
e= -dx; x = x0; y = y0;
for(int i=0; i<=dx; i++)
{
pDC->SetPixel(x,y,color);
x = x + 1;
e = e + 2 * dy;
if(e>=0)
{
y = y + 1;
e = e - 2 * dx;
}
}
*/
}
//圆的扫描转换
void CDDAlineView::MidpointCircle(int r, COLORREF color, CDC *pDC)
{
/*
int x, y;
double d;
x = 0;
y = r;
d = 1.25 - r; //d的初始值
pDC->SetPixel(x, y, color);
while(x<y)
{
if(d<0)
{
d+=2*x+3; //右边的一个象素
x++;
}
else
{
d+=2*(x-y)+5; //右下方的一个象素
x++;
y--;
}
pDC->SetPixel(x,y,color);
}
*/
/*
int x, y;
double d;
x = 0;
y = r;
d = 1 - r; //d的初始值
pDC->SetPixel(x, y, color);
while(x<y)
{
if(d<0)
{
d+=2*x+3; //右边的一个象素
x++;
}
else
{
d+=2*(x-y)+5; //右下方的一个象素
x++;
y--;
}
pDC->SetPixel(x,y,color);
}
*/
/**/
int x, y;
double d, delta_x, delta_y;
x = 0;
y = r;
delta_x = 3; delta_y = 2 - r - r;
d = 1 - r; //d的初始值
pDC->SetPixel(x, y, color);
while(x<y)
{
if(d<0)
{
d+=delta_x; //右边的一个象素
delta_x+=2;
x++;
}
else
{
d+=(delta_x+delta_y); //右下方的一个象素
delta_x+=2; delta_y+=2;
x++;
y--;
}
pDC->SetPixel(x,y,color);
}
}
//Bresenham画圆法
void CDDAlineView::Bresenham_Circle(int r, COLORREF color, CDC *pDC)
{
int x, y, delta, delta1, delta2, direction;
x = 0; y = r;
delta = 2 * (1 - r);
while(y>=0)
{
pDC->SetPixel(x, y, color);
if(delta < 0)
{
delta1 = 2 * (delta1 - x) -1;
if(delta1<=0)
direction = 1;
else
direction = 2;
}
else if(delta>0)
{
delta2 = 2 * (delta - x) -1;
if(delta2<=0)
direction = 2;
else
direction = 3;
}
else
direction = 2;
switch(direction)
{
case 1:
x++;
delta+=2*x+1;
break;
case 2:
x++;
y--;
delta+=2*(x-y+1);
break;
case 3:
y--;
delta+=(-2*y+1);
break;
}
}
}
//椭圆的扫描转换
void CDDAlineView::MidpointEllipse(int a, int b, COLORREF color, CDC *pDC)
{
int x, y;
double d1, d2;
x = 0; y = b;
d1 = b * b + a * a * (-b + 0.25);
pDC->SetPixel(x, y, color);
while(b*b*(x+1)<a*a*(y-0.25))
{
if(d1<0)
{
d1=d1+b*b*(2*x+3);
x++;
}
else
{
d1+=(b*b*(2*x+3)+a*a*(-2*y+2));
x++; y--;
}
pDC->SetPixel(x, y, color);
}/*上半部分*/
d2=sqrt(b*(x+0.5))+sqrt(a*(y-1))-sqrt(a*b);
while(y>0)
{
if(d2<0)
{
d2+=b*b*(2*x+2)+a*a*(-2*y+3);
x++; y--;
}
else
{
d2+=a*a*(-2*y+3);
y--;
}
pDC->SetPixel(x, y, color);
}
}