Objective
In mathematics, the ideal line is no width, it is a collection of countless points. When a line is rasterized, it is only possible to determine the best approximation of a set of pixels in a given, finite number of pixels in a matrix, and to scan the line order.
This section describes three common algorithms for plotting lines with a line width of one pixel: numerical differentiation , midpoint drawing lines , and Bresenham algorithms .
Numerical differential method
The straight segment L (x1, y1) of the endpoint P0 (x0, y0), P1 (P0, P1) is known, and the line slope is k = (y1-y0)/(x1-x0).
So yi+1 = kxi+1 + B.
As a result, x increases 1,y for each additional K. When you draw a point, you also need to judge the Int (y+0.5) to be rounded down.
1 //numerical differential method, pseudo-code2 voidDdaline (intX0,intY0,intX1,inty1) {3 intDX, DY, x=x0, y=y0;4 DoubleK;5DX = x0-x1; DY = y0-Y1;6K = dy/DX;7 Draw (x, y)8 while(x <=x1) {9X + =1;TenY + =K; OneDraw (X,int(y+0.5)); A } -}
The following (0,1) (5, 4):
Midpoint Drawing Line Method
Suppose the segment F (M) = ax + by + c = 0. (A=y0-y1; b=x1-x0; C=X0Y1-X1Y0).
The idea of the midpoint line method is the next point M(xp+1,y+0.5) of the point (XP,YP), which compares the midpoint to the actual point, and if the actual point is above the midpoint (F (M) < 0), the next point is taken (xp+1,yp+1). If the actual point is below the midpoint (that is, the value of the midpoint-to-line equation is greater than 0,f (M) >= 0), then take (xp+1, YP).
To speed up calculations, we usually take an incremental approach.
Assuming that the line is drawn from (XP,YP), the initial value of D D0 = f (x0+1, y0+0.5) = f (x0,y0) +a+0.5. (d = a+0.5b)
- If the d>=0, that is, the midpoint into the original line equation value is greater than 0, that is, the midpoint in the target line above, we should take the following point (Xp+1, YP). When judging the position of the next pixel, you should calculate d = F (xp+2,yp+0.5) = d + A, and the increment is a.
- If d < 0, i.e. the midpoint is below the target line, the point above the midpoint (xp+1,yp+1) is taken. When judging the position of the next pixel, you should calculate d = F (xp+2, yp+1.5) = d + A + B, and the increment is a+b.
Because we just need to know the positive and negative of D, so we can adjust d ' = 2a + B.
1 voidMidpoint (intX0,intY0,intX1,inty1) {2 intA, B, D1, D2, D, X, y;3A = y0-Y1;4b = x1-x0;5D =2*a +b;6D1 =2*a, d2 =2* (A +b);7x = x0, y =y0;8 Draw (x, y);9 while(X <x1) {Ten if(D <0) One{x + +, y++, d+=D2;} A Else -{x + +; d+=D1;} - Draw (x, y); the } -}
effects such as (0,1) (5, 4):
Bresenham algorithm
The Bresenham algorithm also uses the increment method, y each time accumulates K, exceeds 0.5 midpoint position to take above the point, then increments to subtract one. If the start value of our increment is set to d-0.5. Can be compared directly with 0.
Each time compared with 0.5 is more troublesome, so assume that a grid width of 2dx, 2dx High, then a k is 2dy.
So if we set the starting increment to-DX ( -0.5*2DX). Each time the unit is 1, the increment increases by 2dy, then the increment and 0 are compared, if it is greater than 0, take the above point, and then increment to reduce the 2dx.
1 voidIntegerbresenham (intX0,intY0,intX1,inty1) {2 intx, y, dx, dy;3DX = x0-x1, dy = y0-y1, E =-DX;4x = x0, y =y0;5 for(i=0; i<=dx; ++i) {6 Draw (x, y);7x + +, e=e+2*dy;8 if(e >=0) {y++; e =2*DX;}9 }Ten}
Here are the following:
Full code
1 ImportMatplotlib.pyplot as Plt2 fromMatplotlib.tickerImportMultiplelocator3 4 #Numerical Differential method5 defDDA (x0, y0, x1, y1):6DY = y0-Y17DX = x0-X18K = dy/DX9x =x0Teny =y0 One AA = [] -b = [] - while(x <=x1): the a.append (x) -x + = 1 -B.append (int (y+0.5)) -y = y+k +Plt.scatter (A, B, color='R') - + #Midpoint Drawing Line Method A defmidpoint (x0, y0, x1, y1): atA = y0-Y1 -b = x1-x0 -D = 2 * A +b -D1 = 2 *a -D2 = 2 * (A +b) - Print(A, B, D1, D2, D) inx =x0 -y =y0 to +A =[x0] -b =[y0] the whileX <X1: * ifD <0: $x + = 1Panax NotoginsengY + = 1 -D + =D2 the Else: +x + = 1 AD + =D1 the a.append (x) + b.append (y) -Plt.scatter (A, B, color='R') $ $ defBresenham (x0, y0, x1, y1): -DX = x1-x0 -dy = y1-y0 theE =-DX -x =x0Wuyiy =y0 the -A = [] Wub = [] - while(x <=x1): About a.append (x) $ b.append (y) -x + = 1 -E = e + 2 *Dy - ifE >=0: AY + = 1 +E = e-2 *DX thePlt.scatter (A, B, color='R') - $X_target = [0, 5] theY_target = [1, 4] the theAx = Plt.subplot (111); the Plt.plot (X_target, Y_target) -Ax.xaxis.grid (True, which='Major') inAx.yaxis.grid (True, which='Major') theAx.xaxis.set_major_locator (Multiplelocator (1)) theAx.yaxis.set_major_locator (Multiplelocator (1)) About the #DDA (0, 1, 5, 4) the #Midpoint (0, 1, 5, 4) theBresenham (0, 1, 5, 4) +Plt.show ()
Raster Graphics (i): a scanning conversion algorithm for straight line segments