Line Drawing Version B SemiFormal Methods Derivation Anthony
Line Drawing Version B: Semi-Formal Methods Derivation ©Anthony Steed 1999 -2003 1
Overview Line drawing is hard! n Ideal lines and drawing them n Bresenham’s algorithm n • Stages of optimisation Going Faster Still n 2
Ideal Lines n From the equation of a line n Find a discretisation 3
Octants n We will choose one case (1 st octant) 1 st octant • Line gradient is > 0 and is < 1 n There are eight variations of the following algorithms (x 2, y 2) (x 1, y 1) • 4 iterate over X • 4 iterate over Y 4
In the 1 st Octant n n n We know that there is more than one pixel on every row (i. e. X increases faster than y) Also Y increase as X increases Note that horizontal, vertical and 45 degree lines usually treated as special cases 5
Naïve Algorithm dx = x 2 -x 1 dy = y 2 - y 1 for (x=x 1; x<=x 2; x++) { y = round(y 1+(dy/dx)*(x-x 1)) set. Pixel(x, y) } n Problems • one divide, one round, two adds, one multiply per pixel 6
What have we got Only integer arithmetic n One if, 1/2 adds per pixel n • One hidden if in the loop n Can we get faster than that • Well we can get rid of one loop if we are not afraid of programming assembler and using the jmp statement! 7
Step 0 Step 1: Convert to incremental algorithm dx = x 2 -x 1 dy = y 2 - y 1 y = y 1 for (x=x 1; x<=x 2; x++) { y = round(y 1+(dy/dx)* (x-x 1)) set. Pixel(x, y) } for (x=x 1; x<=x 2; x++) { y += dy/dx set. Pixel(x, round(y)) } 8
Step 1 Step 2: Replace round dx = x 2 -x 1 dy = y 2 - y 1 y = y 1 for (x=x 1; x<=x 2; x++) { y += dy/dx set. Pixel(x, round(y)) } for (x=x 1; x<=x 2; x++) { y += dy/dx set. Pixel(x, (int)(y+0. 5)) } 9
Step 3: Split y into an Step 2 integer and fraction part dx = x 2 -x 1 dy = y 2 - y 1 y = y 1 yi = y 1 yf = 0. 0 for (x=x 1; x<=x 2; x++) { y += dy/dx set. Pixel(x, (int)(y+0. 5)) } for (x=x 1; x<=x 2; x++) { yf+= dy/dx if (yf > 0. 5) { yi++ yf-} set. Pixel(x, yi) } Note yf is always in range – 0. 5 to 0. 5 10
Step 3 Step 4: Shift y by 0. 5 f dx = x 2 -x 1 dy = y 2 - y 1 yi = y 1 yf = 0. 0 yi = y 1 yf = -0. 5 for (x=x 1; x<=x 2; x++) { yf += dy/dx if (yf > 0. 5) { yi++ yf-} set. Pixel(x, yi) } for (x=x 1; x<=x 2; x++) { yf+= dy/dx if (yf > 0. 0) { yi++ yf-} set. Pixel(x, yi) } 11
Step 4 Step 5: Multiply y f through by 2 dx dx = x 2 -x 1 dy = y 2 - y 1 yi = y 1 yf = 0. 0 yi = y 1 yf = -dx for (x=x 1; x<=x 2; x++) { yf += dy/dx if (yf > 0. 0) { yi++ yf-} set. Pixel(x, yi) } for (x=x 1; x<=x 2; x++) { yf += 2 dy if (yf > 0. 0) { yi++ yf += -2 dx } set. Pixel(x, yi) } We now have all integer arithmetic 12
Step 5 Step 6: Re-arrange if dx = x 2 -x 1 dy = y 2 - y 1 yi = y 1 yf = -dx for (x=x 1; x<=x 2; x++) { if (yi > 0. 0) { yi++ yf += 2 dy -2 dx } else { yf += 2 dy } set. Pixel(x, yi) } for (x=x 1; x<=x 2; x++) { yf += 2 dy if (yf > 0. 0) { yi++ yf += -2 dx } set. Pixel(x, yi) } This has one less add statement 13
Step 6 Step 7: Make all constants dx = x 2 -x 1 dy = y 2 - y 1 yi = y 1 yf = -dx for (x=x 1; x<=x 2; x++) { if (yi > 0. 0) { yi++ yf += 2 dy -2 dx } else { yf += 2 dy } set. Pixel(x, yi) } yi = y 1 yf = -dx e = 2 dy – 2 dx f = 2 dy for (x=x 1; x<=x 2; x++) { if (yi > 0. 0) { yi++ yf +=e } else { yf += f } set. Pixel(x, yi) } Reduced to one if, 1 or 2 adds 14
What have we got Only integer arithmetic n One if, 1/2 adds per pixel n • One hidden if in the loop n Can we get faster than that • Well we can get rid of one loop if we are not afraid of programming assembler and using the jmp statement! 15
Faster - Mid-Point Drawing n n n Note that lines are symmetric (a, b) to (c, d) should generate the same pixels. Thus the lines are symmetric about the midpoint Implies. . . • draw outwards from mid-point in both directions n Is almost twice as fast (one extra add gives an extra pixel) 16
Faster - Two-Step n Note we considered whether to choose P or Q n What if we choose between the four cases n Almost twice the speed again 17
Summary n Bresenham’s algorithm uses only integer arithmetic and 2/3 ops per pixel • Ideal for hardware implementation n Can be improved almost four-fold in speed, with added complexity • Good for software implementations • Pixel scanning is usually not the bottleneck these days so wouldn’t be cast into hardware 18
- Slides: 18