 # Graphics Primitives: line

## Presentation on theme: "Graphics Primitives: line"— Presentation transcript:

Graphics Primitives: line
Computer Graphics Graphics Primitives: line

Pixel Position

Line-Scan Conversion Algorithms
Line scan conversion: determine the nearest pixel position (integer) along the line between the two endpoints and store the color for each position in the frame buffer. Three common algorithms DDA Midpoint Bresenham

Line Equations The Cartesian slope-intercept equation ((x0,y0)(xend,yend)) Y=mx+b

Naive Idea Costly floating point computations !!
void NaiveLine(int x0,int y0,int xend,int yend,int color)  int x; float y, m, b; m=(yend-y0)/(xend-x0); b = y0 – m*x0; for (x=x0; xxend; x++)  drawpixel (x, int(y+0.5), color); y=m*x+b;  Costly floating point computations !! Multiplications, additions, roundings

DDA (Digital Differential Analyzer) ALGORITHM
The digital differential analyzer (DDA) samples the line at unit intervals in one coordinate corresponding integer values nearest the line path of the other coordinate. The following is the basic scan-conversion(DDA) algorithm for line drawing (sample at unit x intervals ) for x from x0 to xend Compute y=mx+b Draw_fn(x, round(y)) How to improve???

Reuse Previous Value Increment For
Start from x=x0 and y=y0, every position (x,y) can be computed by incrementation, x by 1 and y by m. Mxi+mdx+b=mxi+b+ mdx= yi +mdx, untuk oktan 1 ketika garis agak landai lompatan lebih rapat adalah x

No more multiplications, but still have fp
void DDALine(int x0,int y0,int xend,int yend,int color)  int x; float dx, dy, y, m; dx = xend-x0, dy=yend-y0; m=dy/dx; y=y0; for (x=x0; xxend; x++)  drawpixel (x, int(y+0.5), color); y=y+m;  No more multiplications, but still have fp additions, roundings

Example：draw segment x y int(y+0.5) round

DDA Illustration (xi+1, Round(yj+m)) (xi, yj) (xi+1, yj+m)
Desired Line (xi+1, Round(yj+m)) (xi, yj) (xi+1, yj+m) (xi, Round(yj)) y2 y1 x1 x2

The above DDALine only suit the condition that xend>x0 and 0 < m < 1 (octant #1) How about the other cases? |m| > 1 xend < x0?

Octant#2: xend>x0 and 1 < m < ∞
#3 #1 #4 m=0 #5 #8 #6 #7

Octant#2 and #3: reverse the role of x as iterator by y and increment x by 1/m
Octant#4: reverse the end points  octant#8 Octant#5: reverse the end points  octant#1 Octant#6: reverse the end points  octant#2 Octant#7: reverse the end points  octant#3 Octant#8: Just same DDA algorithm for octant#1

Has rounding operations the accumulation of error
Major deficiency in the above approach : Uses floats Has rounding operations the accumulation of error

According the position of M and Q, choose the next point Pt or Pb
Midpoint Algorithm Basic thought( 0 < m < 1) M PT PB P=(x,y) Q Pi(xi,yi) M(xi+1,yi+0.5) According the position of M and Q, choose the next point Pt or Pb

Line equation ( (x0,y0) , (xend,yend) )
Dari y=mx+k terus persamaan y-mx-k=f(x,y) di bawah negatif, di atas positif For any point (x, y): F(x,y) = 0  (x,y) is on the line F(x,y) > 0  (x,y) is above the line F(x,y) < 0  (x,y) is beneath the line

Discriminant Function d
The function is made by using the midpoint M: d < 0, M is beneath Q, P2 is next point; d > 0, M is above Q, P1 is the next point; d = 0, P1 or P2 is right, commonly P1 P2 Q P=(x,y) M Pi(xi,yi) P1

Is it (computing the d) costly. No
Is it (computing the d) costly? No! We can use the idea in the DDA: use previous d value to compute next one.

Incrementation thought
If d0，then choose the next point: P1 (xp+1, yp), In order to judge the next point successively，calculate increment of d is a If d<0，then choose the next point:P2 (xp+1, yp+1)。In order to judge the next point successively ,calculate increment of d is a+b

Initial value of d In each of iteration If d >= 0 Else if d < 0

Improve again: integer calculations?

Substitute 2d for d Initial value of d In each of iteration
Implementation issue: the quantities (2a) and (2a+2b) can be precomputed to be two constants. If d >= 0 Else if d<0

Example Drawing a line from (0,0) to (5.2) i xi yi d

void MidpointLine (int x0,int y0,int xend, int yend,int color) { int a, b, incre_d1, incre_d2, d, x, y; a=y0-yend, b=xend-x0, d=2*a+b; incre_d1=2*a, incre_d2=2* (a+b); x=x0, y=y0; drawpixel(x, y, color); while (x<x1) { if (d<0) {x++, y++, d+=incre_d2; } else {x++, d+=incre_d1;} drawpixel (x, y, color); } /* while */ } /* mid PointLine */