[Schooll_ĐHMT] 算法Breshenham画直线
内容
1. 构建算法
2. 流程图算法
3. 代码插图
4. 所有病例码
阅读更多
1. 画直线的一般原则
2. DDA算法划清界线
3. 中点算法划清界线
给 2 端点M1 (X1, Y1), M2(X2, Y2) 和油漆Ç.
在所有 画直线的一般原则 我们已经建立了表格的直线方程:
为了简化算法,我们考虑与行
在对x的增加每一步都有一个 1 即单位 . 下一步骤是,我们计算 但我们不会做同样的 DDA算法 因为它必须处理的实数数据,并四舍五入导致浪费时间. 我们将根据整数找物业.
假设在第k步,我们得到如下图:
呼叫医疗推出的准确性 . 我将y的值最接近的值 有 . 要做到这一点,我们认为D1和D2.
如果d1 > 同时D2
如果d1 < 同时D2
因此,如果我们确定d1的迹象 – D2,那么我们就知道价值 . 考虑到不断 (我们乘 (X1-X2) 以消除在计算米的取代模式).
DX > 0 应该 只有在D1-D2依赖. 我有:
$胶乳
M = 压裂{Y2,Y1}{X2-X1} \\
\RIGHTARROW P_{到} = (X2-X1)(D1 – D2) \\
\缩进缩进= (X2-X1).\压裂{2(Y2,Y1)(X_{到}+1) +(X2-X1)(-2Y_{到} + 2B – 1)}{X2-X1} \\
\缩进缩进= 2(Y2,Y1)X_{到} – 2(X2-X1)Y_{到} + 2(Y2,Y1) + (X2-X1)(2B-1) \\
\缩进缩进= 2x_{到}两 – 2Y_{到}.DX + Ç
\\
\RIGHTARROW P_{K 1} = 2(X_{到}+1)两 – 2Y_{K 1}DX + Ç, 到 : \左 (C = 2DY + (2B-1)DX 权 ) \\
\\
TH1: P_{到} \GEQ 0 \RIGHTARROW D1 D2 GEQ \\
\缩进缩进 RIGHTARROW Y_{K 1} = Y_{到} + 1 \\
\缩进缩进 RIGHTARROW P_{K 1} = 2(X_{到}+1)两 – 2(Y_{到} + 1)DX + C = P_{到} + 2(两 – DX) \\
\\
TH2: P_{到} < 0 \Rightarrow d1 < d2 \\
\indent \indent \Rightarrow y_{k+1} = y_{k} \\
\indent \indent \Rightarrow P_{k+1} = 2(x_{k}+1)Dy - 2y_{k}Dx + c = P_{k} + 2Dy \\
$
Tính P1, ta có:
$latex
y1 = m.x1 + b = \frac{Dy}{Dx}x1 + b\\
P_{1} = 2x1.Dy - 2y1.Dx + c
= 2x1.Dy - 2\left ( \frac{Dy}{Dx}x1 + b \right )Dx + 2Dy + (2b - 1)Dx\\
= 2Dy - Dx
$
2. 流程图算法
Bresenham算法只对加法和乘法整数运算和计算 2 (允许转换位). 这是一个速度的提高增加显著DDA算法. 该算法的主要思想是,在点P i到下一个判定点.
3. 代码插图
/* Program create in Linux OS * nguyenvanquan7826 */ #include <graphics.h> #define DELAY 10 int color = RED; void Bresenham(int x1, int y1, int x2, int y2){ int x, y, Dx, Dy, p, c1, c2; Dx = abs(x2 - x1); Dy = abs(y2 - y1); p = 2*Dy - Dx; c1 = 2*Dy; c2 = 2*(Dy-Dx); x = x1; y = y1; int x_unit = 1, y_unit = 1; putpixel(x,y,color); while(x != x2){ delay(DELAY); if (p<0) p += c1; else{ p += c2; y += y_unit; } x += x_unit; putpixel(x, y, color); } } int main(){ int gd,gm=VGAMAX; gd=DETECT; initgraph(&gd,&gm,NULL); setbkcolor(WHITE); Bresenham(50,150, 300, 200); // ve duong thang getchar(); return 0; }
4. 所有病例码
下面的代码将借鉴 8 下段 8 方向, 从中心点起.
/* Program create in Linux OS * nguyenvanquan7826 */ #include <graphics.h> #define DELAY 10 int colorRedBlue = BLUE; struct point { int x, y; }; void lineBresenham(int x1, int y1, int x2, int y2){ int x, y, Dx, Dy, p, c1, c2; Dx = abs(x2 - x1); Dy = abs(y2 - y1); p = 2*Dy - Dx; c1 = 2*Dy; c2 = 2*(Dy-Dx); x = x1; y = y1; int x_unit = 1, y_unit = 1; if (x2 - x1 < 0) x_unit = -x_unit; if (y2 - y1 < 0) y_unit = -y_unit; if (x1 == x2) // duong thang dung { while (y != y2+1) { delay(DELAY); y += y_unit; putpixel(x, y, colorRedBlue); } } else if (y1 == y2) // duong ngang { while (x != x2+1) { delay(DELAY); x += x_unit; putpixel(x, y, colorRedBlue); } } else{ putpixel(x, y, colorRedBlue); while(x != x2){ delay(DELAY); if (p<0) p += c1; else{ p += c2; y += y_unit; } x += x_unit; putpixel(x, y, colorRedBlue); } } } int main(){ int gd,gm=VGAMAX; gd=DETECT; initgraph(&gd,&gm,NULL); setbkcolor(WHITE); int x = 100, y = 200; point A[9] = {{getmaxx()/2, getmaxy()/2}, {A[0].x-x, A[0].y-y}, {A[0].x-x, A[0].y+y}, {A[0].x+x, A[0].y+y}, {A[0].x+x, A[0].y-y}, {A[0].x, A[0].y-y}, {A[0].x-x, A[0].y}, {A[0].x, A[0].y+y}, {A[0].x+x, A[0].y}, }; for (int i=1; i<9; i++) { lineBresenham(A[0].x, A[0].y, A[i].x, A[i].y); } getchar(); return 0; }
然而,由于照顾由于四舍五入和舍入已保存以计算行中的值的连续性,以由该算法可以得出是不正确. 我们可以观察到这种算法和DDA用同样的区别 1 联系线.
A[] = { {getmaxx()/2, getmaxy()/2}, {A[0].x-x, A[0].y-y}, {A[0].x-x, A[0].y+y}, {A[0].x+x, A[0].y+y}, {A[0].x+x, A[0].y-y}, {A[0].x, A[0].y-y}, {A[0].x-x, A[0].y}, {A[0].x, A[0].y+y}, {A[0].x+x, A[0].y} }
蓝线是Breshenham, 粉红色是DDA. (DDA更准确). 的水平和垂直线,它们完全配合在一起. 下面是该算法的改进代码Breshenham.
// Ve duong thang Bresenham Cai tien void lineBresenham_1(int x1, int y1, int x2, int y2) { int c2, c, Dx, Dy, x, y; Dx = abs(x2 - x1); Dy = abs(y2 - y1); c = Dx - Dy; c2 = 2*c; x = x1; y = y1; int x_unit = 1, y_unit = 1; if (x2 - x1 < 0) x_unit = -x_unit; if (y2 - y1 < 0) y_unit = -y_unit; putpixel(x, y, colorGreen); if (x1 == x2) // duong thang dung { while (y != y2) { delay(DELAY); y += y_unit; putpixel(x, y, colorGreen); } } else if (y1 == y2) // duong ngang { while (x != x2) { delay(DELAY); x += x_unit; putpixel(x, y, colorGreen); } } else if (x1 != x2 && y1 != y2) // duong xien { while(x != x2+1) { delay(DELAY); c2 =2*c; if (c2 > -Dy) { c = c - Dy; x = x + x_unit; } if (c2 < Dx) { c = c + Dx; y = y + y_unit; } putpixel(x, y, colorGreen); } } }
当你运行该代码比DDA他们完全重合
他要求,M E>1 该算法将描述布氏如何将
你看代码的所有情况下NHE.
我在寻找合适的地方. 详细的说明和易于理解的太. 非常感谢您对您的
该算法可以应用于控制器 2 步进电机移动的工作下启动 1 你的右线. 但我还是如何根据这个算法脉冲输出不懂 ? 希望大家帮我在这种情况下, !
该所以这个算法是画一条线. 你的脉搏出来,我要, 盲人不能帮你,然后.
A到E问,为什么把C =霉素 – 两; 和算法,然后知道如何
否则,如果 (X1 != X2 && Y1 !Y2 =) // 偏置
{
而(X != X + 1)
{
延迟(延迟);
C2 = 2 * C;
如果 (C2 > -两)
{
C = C – 两;
X = X + x_unit;
}
如果 (C2 < DX)
{
C = C + DX;
Y = Y + y_unit;
}
的putpixel(X, 和, 颜色绿色);
}
}
这是代码已经从构建算法转移. 您查看离线算法.
改进了它的想法如何算法?
它的意识形态不圆了,但基于对角比数量要到正确的方向.
#包括
#包括
#包括
#定义Ç青色
INT breseham (INT X1, INT Y1, INT X2, INT Y2){
INT DX = ABS (X2 – X1);
INT DY = ABS (Y2 – Y1);
INT x_unit = 1, y_unit = 1;
如果 (X2-X1 <0)
x_unit = -x_unit;
如果 (Y2,Y1 <0)
y_unit = -y_unit;
如果 (DX == 0 && 两!= 0){
为 (INT I = 0; 在<=两个; 我 ){
的putpixel (X1,Y1,C);
Y1 + = y_unit;
}
}
否则,如果 (2 == 0 && DX!= 0){
为 (INT J = 0; J = DY){
INT p值= 2 * DY-DX;
INT C1 = 2 * DY, C2 = 2 * DY – 2*DX;
而 (X1!= X2){
如果 (P<0)
P + = C1;
其他{
Y1 + = y_unit;
P + = C2;
}
的putpixel (X1,Y1,C);
X1 + = x_unit;
}
}
其他 {
INT P = 2 * DX-DY;
INT C1 = 2 * DX, C2 = 2 * DX – 2*两;
而 (X1!= X2){
如果 (P<0)
P + = C1;
其他 {
X1 + = x_unit;
P + = C2;
}
的putpixel (X1,Y1,C);
Y1 + = y_unit;
}
}
}
}
INT主要 (){
INT X1, Y1,X2,Y2;
的printf ("nhap toa do diem A(X1,Y1), B(X2,Y2)");
的printf ("\n x1= "); scanf函数 ("%d",&X1);
的printf ("\n y1= "); scanf函数 ("%d",&Y1);
的printf ("\n x2= "); scanf函数 ("%d",&X2);
的printf ("\n y2= "); scanf函数 ("%d",&Y2);
initwindow (400,400);
breseham(X1,Y1,X2,Y2);
残培();
}
他问我是正确的声明
这行代码INT GD,GM = VGAMAX; GD = DETECT; 他用什么做的?
初始化图形模式NHE的初始值.
改进算法中有你,因为牙齿问题:
X 1 = X + 1,则代码将得出错误
DX = 1,2,3。. DX即较小的错误代码也画了他的牙医.
谢谢, 我会检讨^^
该初始化取决于不需要设置值屏幕尺寸大小的图形显示的是不正确的语句