[Schooll_ĐHMT] Algorithm Breshenham draw straight lines

Content
1. Construction algorithm
2. Flowchart algorithm
3. Code illustrations
4. Code for all cases
Read more
1. General Principles of drawing straight lines
2. DDA algorithm to draw the line
3. Midpoint algorithm to draw the line



1. Construction algorithm Breshenham

Give 2 endpoints M1 (x1, y1), M2(x2, y2) and paint C.
In all General principles of drawing straight lines we have built a straight line equation of the form:

y = mx + b. \text{ Trong do: }  \begin{cases}  m = \frac{y2 - y1}{x2-x1} = \frac{Dy}{Dx} \\  b = y1 - m.x1  \end{cases}

To simplify the algorithm we consider the line with m in [0,1] , Dx > 0
At each step one for x increases 1 ie unit x_{k + 1} = x_{k} + 1 . The next step is we compute y_{k + 1} but we will not do the same DDA algorithm because it must handle data on real numbers and rounding leads to lost time. We'll find properties according to the integer.

Suppose that at step k we get the following picture:
algorithm Breshenham
Call Medical is launching accuracy y_{k + 1}. I will take the value of y is the value closest to y_{k} + 1 there are y_{k}. To do this we consider d1 and d2.
d1 = y - y_{k} = m(x_{i} + 1) + b - y_{k} \\  d2 = y_{k} + 1 - y = y_{k} + 1 - m(x_{i}+1) - b \\  => d1 - d2 = 2m(x_{i} +1) - 2y_{k} + 2b - 1
If d1 > Meanwhile d2 y_{k + 1} = y_{k} + 1
If d1 < Meanwhile d2 y_{k + 1} = y_{k}
Therefore, if we identify signs of d1 – d2, then we will know the value of y_{k+1} . Consider the constant P_{k} = (x1-x2)(d1-d2) (We multiply (x1-x2) to eliminate the substitution pattern in the calculation m).
Dx > 0 should P_{k} depends only on d1 -d2. I have:
$latex
m = frac{y2-y1}{x2-x1} \\
\Rightarrow p_{to} = (x2-x1)(d1 – d2) \\
\indent indent= (x2-x1).\frac{2(y2-y1)(x_{to}+1) +(x2-x1)(-2y_{to} + 2b – 1)}{x2-x1} \\
\indent indent = 2(y2-y1)x_{to} – 2(x2-x1)y_{to} + 2(y2-y1) + (x2-x1)(2b-1) \\
\indent indent = 2x_{to}Two – 2y_{to}.Dx + c

\\
\Rightarrow p_{k 1} = 2(x_{to}+1)Two – 2y_{k 1}Dx + c, to : \left (c = 2Dy + (2b-1)Dx right ) \\
\\
TH1: P_{to} \geq 0 \Rightarrow d1 geq d2 \\
\indent indent rightarrow y_{k 1} = Y_{to} + 1 \\
\indent indent Rightarrow P_{k 1} = 2(x_{to}+1)Two – 2(y_{to} + 1)Dx + c = P_{to} + 2(Two – Dx) \\
\\
TH2: P_{to} < 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. Flowchart algorithm
Breshenham

Bresenham algorithm only on integer operations and calculations on addition and multiplication 2 (allows translation bit). This is a speed improvement increases significantly DDA algorithm. The main idea of ​​this algorithm is that at point P i to the next decision point.

3. Code illustrations

/* 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. Code for all cases
The following code will draw 8 segment under 8 direction, starting from the center point.

/* 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;
}

However, due to continuity of care due to rounding and rounding the value that was saved to calculate the line to be drawn by this algorithm is incorrect. We can observe the difference between this algorithm and DDA with the same 1 Contact the line.

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}
}

compare Breshenham and DDA
The blue line is the Breshenham, Pink is the DDA. (DDA more accurate). The horizontal and vertical lines, they fit perfectly together. And here's the code for the algorithm improvements 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);
		}
	}
}

When you run this code than the DDA they completely coincide