[Schooll_ĐHMT] アルゴリズムBreshenhamは直線を引く
コンテンツ
1. 構成アルゴリズム
2. フローチャートアルゴリズム
3. コードイラスト
4. すべてのケースのためのコード
続きを読む
1. 直線を描くの一般原則
2. 線を引くためのDDAアルゴリズム
3. 線を引くための中間点アルゴリズム
与える 2 エンドポイントM1 (X1, Y1), M2(X2, Y2) とCを描く.
全部で 直線を描くの一般原則 我々は、フォームの直線方程式を構築しています:
アルゴリズムを簡略化するために、我々は行を考える
Xが増加するため、各ステップ1で、 1 すなわちユニット . 次のステップは、私たちが計算され 私たちは同じことを行うことはありません DDAアルゴリズム それが失われた時間に実数と丸めリード上のデータを扱う必要があるため、. 私たちは、整数に応じてプロパティを見つけることができます.
ステップkで、我々は以下の画像を取得したと:
コールメディカルは精度を立ち上げる . 私は、yの値が最も近い値であるがかかります がある . これを行うには、d1とd2を検討.
D1の場合 > 一方、D2
D1の場合 < 一方、D2
したがって、我々はD1の兆候を識別する場合 – D2、我々はの価値を知っている . 定数を考慮してください (私たちは、乗算 (×1、×2) 計算mにおける置換パターンを除去する).
Dxは > 0 すべきである 唯一のD1 -d2に依存. 私が持っている:
$ラテックス
メートル= FRAC{Y2-Y1}{X2-X1} \\
\RIGHTARROW P_{へ} = (X2-X1)(D1 – D2) \\
\インデントインデント= (X2-X1).\FRAC{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)(2のb 1) \\
\インデントインデント= 2x_{へ}二つ – 2Y_{へ}.Dxは + ℃
\\
\RIGHTARROW P_{のk 1} = 2(X_{へ}+1)二つ – 2Y_{のk 1}Dxは + ℃, へ : \左 (C = 2Dy + (2のb 1)DX 権 ) \\
\\
TH1: P_{へ} \GEQ 0 \RIGHTARROW D1 GEQ D2 \\
\インデントインデント 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. フローチャートアルゴリズム
唯一の加算と乗算に整数演算と計算上のブレゼンハムアルゴリズム 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よりも、このコードを実行すると、彼らは完全に一致している
依頼する教師メートルfにあります>1 このアルゴリズムは、どのようにAブレセンハムを説明します
あなたはオフラインですべてのケースのコードを参照してください。.
私は適切な場所を探しています. 詳細な手順ので、理解しやすいです. どうもありがとうございました
このアルゴリズムは、制御装置に適用することができます 2 ステッピングモータは、作業が下の開始に移動します 1 あなたの右のライン. しかし、私はまだどのようにパルス出力このアルゴリズムに従って理解していません ? あなたはこのケースで私を助けるホープ !
したがって、このアルゴリズムは、線を引くです. あなたのパルスが出てくる、私がする必要はあり, ブラインドは、あなたを助けることができません.
eまでなぜC = Dxを入れて尋ねます – 二つ; およびアルゴリズムは、どのように理解しました
それ以外の場合 (X1 != x2の && Y1 != Y2) // 付勢
{
同時に(X != X2 + 1)
{
ディレイ(ディレイ);
C2 = 2 * cを;
もし (C2 > -二つ)
{
C = C – 二つ;
X = X + x_unit;
}
もし (C2 < Dxは)
{
C = C + Dxは;
Y = yの + y_unit;
}
putpixel(X, と, colorGreen);
}
}
このコードは、構成アルゴリズムから転送されたです. あなたはアルゴリズムをオフラインで確認します.
そのアイデアをどのように改善されたアルゴリズム?
そのイデオロギーはもはや円形ではなく、対角比の数に基づいて、右方向に移動するには.
#含まれる
#含まれる
#含まれる
#CのCYANを定義します
int型breseham (int型×1, int型Y1, int型×2, int型Y2){
int型DX =腹筋 (X2 – X1);
int型DY =腹筋 (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){
のために (I = 0 int型; で<= 2; 私 ){
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型×1, 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);
getchは();
}
彼は正しく私にその宣言を尋ねました
このコード行のint型のGD,GM = VGAMAX; GD = DETECT; 彼が行うために使用?
グラフィックモードの初期値を初期化NHE.
改善されたアルゴリズムは、歯の問題、あなたを持っているので、:
X1 = X2 + 1、コードが間違って描画されます
DX = 1,2,3。. DXすなわち小さいエラーコードはまた彼の歯科医を描い.
ありがとう, 私は検討します^^
それは右ではないに値を設定する必要はありません、画面のサイズに応じてサイズのグラフィック表示を初期化ステートメント