Document

Line Drawing
and Generalization
Outline
 overview
 line drawing
 circle drawing
 curve drawing
1. Overview
application data
structures/models
application
programs
graphics
primitives
graphics
systems
display
devices
OpenGL
pixel
information
Geometric Primitives
Building blocks for a 3D object
Application programs must describe their
service requests to a graphics system
using geometric primitives !!!
points, lines, polygons
Why not providing data structures directly to the
graphics system?
OpenGL Rendering Pipeline
geometric
data
evaluators
per-vertex operations &
primitive assembly
rasterization
display lists
pixel
data
pixel operations







display lists
evaluators
per-vertex operations & primitive assembly
pixel operations
rasterization
texture assembly
per-fragment operations
texture assembly
per-fragment
operations
frame buffer
Continuity
8-connectivity
(king – continuity)
4-connectivity
(rook – continuity)
2. Line Drawing
(x2, y2)
f
(x1, y1)
L1 {(x, y) | x1  x  x2, y1  y  y2,
L2  {(x i, yi) | i  1,2,..., n }
ax  by  c  0 }
| L1| 
f : L1 => L2
| L2 | 
quality degradation!!
Line drawing is at the heart of
many graphics programs.
Smooth, even, and continuous as much as possible !!!
Simple and fast !!!
Bresenham’s Line Drawing Algorithm
via
Pragram Transformation
 additions
/ subtractions only
 integer arithmetic
 not programmers’ point of view but system developers’ point of view
var yt : real; x, y, xi, yi : integer;
for xi := 0 to x do begin
yt := [y/x]*xi;
*
x
yi := trunc(yt+[1/2]);
display(xi,yi);
y
end;
(∆x, ∆y)
Eliminate multiplication !!!
(0,0)
var yt : real; x, y, xi, yi : integer;
yt := 0;
for xi := 0 to x do begin
yi := trunc(yt + [1/2]);
display(xi,yi);
yt := yt+[y/x]
end;
**
y = mx, m = [y/x]
x ≥ y ∴m ≤ 1
x, y: positive integers
var ys : real; x, y, xi, yi : integer;
Motivation(Cont’)
ys := 1/2;
for xi := 0 to dx do begin
yi := trunc(ys);
***
display(xi,yi);
ys := ys+[y/x]
ys  ysi  ysf
end;
var ysf : real; x, y, xi, ysi : integer;
ysi := 0;
ysf := 1/2;
integer part

for xi := 0 to x do begin
1 y
y 1
y sf   1

2 x
x 2
display(xi,ysi);
if ysf+[y/x] < 1 then begin
ysf := ysf + [y/x];
****
end else begin
ysi := ysi + 1;
ysf := ysf + [y/x-1];
end;
end;
y sf 
y
1  0
x
ysf  0
fractional part
2x  y  r
Motivation(Cont’)
sf
var x, y, xi, ysi, r : integer;
ysi := 0;
y sf 
y 1

x 2
2x  ysf  2y  x
for xi := 0 to x do begin
display(xi,ysi);
if ysf  0 then begin
y sf  y sf 
y
x
2x  ysf  0
2x  ysf  2x  ysf  2y
end else begin
ysi := ysi + 1;
 y 
y sf  y sf  
1
 x 
end;
end;
2x  ysf  2x  ysf  [2y  2x]
2x  y  r
Motivation(Cont’)
sf
var x, y, xi, ysi, r : integer;
ysi := 0;
r := 2*y - x;
for xi := 0 to x do begin
display(xi,ysi);
if r < 0 then begin
r := r + [2*y];
end else begin
ysi := ysi + 1;
r := r + [2*y -2*x ];
end;
end;
Bresenham’s Algorithm !!!
No multiplication/ division.
No floating point operations.
Line-Drawing Algorithms
(x 2 ,y 2 )
y2
y
y1
y  mx  b
b  y1  mx 1
y2  y1 y
m

x2  x1 x
(x1 ,y1 )
x1 x
x2
Assumptions
x1  x2
m0
(x>0)
y  mx
DDA(Digital Differential Analyzer) Algorithm
y  mx
basic idea
x 
m0
1
y
m
Take unit steps with one coordinate and
calculate values for the other coordinate
i.e.
xi  1 : xi  1
yi  1 : yi  m
or
0  m 1
Why?
yi  1 : yi  1
xi  1 : xi 
1
m
1 m
discontinuity !!
DDA(Cont’)
Assumption : 0  m <1, x1<x2
procedure dda (x1, y1, x2, y2 : integer);
var
x, y, k : integer;
x, y : real
begin
x := x2 - x1;
y := y2 - y1;
x := x1; y := y1;
display(x,y);
for k := 1 to x do begin
x := x + 1;
y := y + [y/x];
display(round(x),round(y));
end { for k }
end; { dda }
no
*’s
expensive !!
Bresenham’s Line Algorithm

basic idea
− Find the closest integer coordinates to the actual line path using only
integer arithmetic
− Candidates for the next pixel position
Specified
Line Path
0  m 1
Specified
Line Path
yi  2
Bresenham’s Line algorithm(Cont’)
y 1
i
y
yi  1
d2
d1
y  mx  b
yi
0  m 1
x i xi  1 x i  2
xi  xi+1
yi
xi
xi  1
y i  mx i  b
 d1  y - y i  m(x i 1)  b - y i
d 2  y i 1- y  y i 1 m(x i 1)  b
d  d1  d 2  2m(x i 1)  2y i  2b 1
(where m  y/ x)
p i  x(d 1  d 2 )  2y(x i 1)  2xy i  x(2b 1)
 2yx i  2xy i  (2y  x(2b 1))
 2yx i  2xy i  c
p i  2yx i  2xy i  c
if p i  0 then (x i 1, y i )
if p i  0 then (x i 1, y i 1)
c
Bresenham’s Line algorithm(Cont’)
pi  2yxi  2xyi  c
pi  1  2yxi  1  2xyi  1  c
 pi 1  pi  2y(x i 1  x i )  2x(y i 1  y i )
=1
 pi 1  pi  2y  2x(y i 1  y i )
yi 1
 pi 1
if pi  0
 yi

otherwise
 yi  1
if pi  0
pi  2y

pi  2y  2x
otherwise
Now,
p1  2yx1  2xy1  c
 2y  x
 p1  2y  x
2y  x(2b  1)
y1 -(y/x)x1
Bresenham’s Line algorithm(Cont’)
procedure bres_line (x1, y1, x2, y2 : integer);
var
while x < x2 do begin
if p<0 then begin
x, y, x,y,p,incrE,incrNE : integer;
p := p + incrE;
begin
x := x + 1;
x := x2 – x1;
end; { then begin }
y := y2 – y1;
else begin
p := 2*y - x;
p := p + incrNE;
incrE := 2*y;
y := y + 1;
incrNE := 2*(y - x);
x := x + 1;
x := x1; y := y1;
display(x,y);
end; { else begin }
display (x, y);
end { while x < x2 }
end; { bres_line}
Homework #2 Extend this algorithm for general cases.
Midpoint Line Algorithm
y
x  B  y  x  x  y  x  B  0
x
F(x, y)  y  x  x  y  x  B
y
(xi  1, yi  1)
NE
Q
(xi, yi)
Current
pixel
M
(xi  1, yi  1/2)
E
(xi  1, yi)
Choices for
next pixel
F(x, y)  0
Letting a  y, b  x, and c  x  B,
F(x, y)  ax  by  c
F(x, y)  0 if (x, y) is on the line
1

E
if
F(x

1,
y

)0
i
i

2
Q is closer to 
1
 NE if F(x i  1, y i  )  0
2

Van Aken, “An Efficient Ellipse - Drawing Algorithm”
IEEE CG & A, 4(9), 24-35, 1984.
Midpoint Line Algorithm (Cont’)
1
1
F(x i  1, y i  )  a(x i  1)  b(y i  )  c
2
2
1
Let Pi  2F(x i  1, y i  )  2a(x i  1)  b(2y i  1)  c
2
Since a  y and b  x,
Pi  2y(x i  1)  x(2y i  1)  2c
Pi 1  2y(x i 1  1)  x(2y i 1  1)  2c
 Pi 1  Pi  2y(x i 1  x i )  2x(y i 1  y i )
x i 1  x i  1
if Pi  0
yi
y i 1  
 y i  1 otherwise
if Pi  0
P  2y
 Pi 1   i
Pi  2y - 2x otherwise
1
P1  2F(x1  1, y1  )  2(yx 1  xy 1  c)  2y  x  2y  x
2
Midpoint Line Alg. (Cont’)
y
(x2, y2)
x
(x1, y1)
y
x
if Pi  0
P  2y
 Pi 1   i
Pi  2y  2x otherwise
P1  2y - x
if Pi  0
(x  1, y i )
(x i 1 , y i 1 )   i
(x i  1, y i  1) otherwise
Midpoint
Midpoint
Line
Line
Algorithm(Cont’)
Alg. (Cont’)
procedure mid_point (x1, y1, x2, y2,value : integer);
while x  x2 do begin
if p < 0 then begin
var
x, y,incrE,incrNE,p,x,y : integer;
p := p + incrE;
begin
x := x + 1;
x := x2 – x1;
end; { then begin }
y := y2 – y1;
else begin
p := 2*y - x;
p := p + incrNE;
incrE := 2*y;
y := y + 1;
incrNE := 2*(y-x);
x := x + 1;
x := x1; y := y1;
end; { else begin }
display(x,y);
display(x,y);
end; { while x  x2 }
end; { mid_point }
Geometric Interpretation
slope : x  y
slope : x  y
any slope
Bresenhams’s algorithm
Geometric Interpretation(Cont’)
y
x
Aliasing Effects
 line drawing
staircases (or jaggies)
intensity variation
animation
texturing
popping-up
Anti-aliasing Lines

Removing the staircase appearance of a line
 Why staircases?
raster effect !!!
need some compensation in line-drawing algorithms for this raster
effect?
How to anti-alias?
well, …
increasing resolution.
However, ...
Increasing resolution
memory cost
memory bandwidth
scan conversion time
display device cost
Anti-aliasing
(Cont’)
Anti-aliasingLine
Techniques
 super sampling
(postfiltering)
 area sampling
(prefiltering)
 stochastic sampling
Cook, ACM Trans. CG, 5(1),
307-316, 1986.
Area Sampling (Prefiltering)
Filters
unweighted area sampling
box filter
weighted area sampling
cone filter
Table look-up for f(D, t)
D
The table is invariant of the slope of line!
Why?
The search key for the table is D!
Why?
Intensity Functions f(D, t)
(assumption : t=1)
v0
cos 
D  v cos 
vdx
dx 2  dy 2
dx
dx 2  dy 2
How to compute D
(assumption : t=1)
D  v cos  
vdx
dx  dy
2
where v  y  y i 1
2
,
 y  yi

 y  (y i  1)
1
Pi =2F(M)=2F(x i +1,yi + ),
2
where F(x,y)=ax+by+c
if Pi  0
otherwise.
How to compute D, incrementally
Let dx  x and dy  y.
y
y
x  B  yx  xy  x  B  0
x
ax  by  c  0
F(x, y)  ax  by  c
Pi  0:
a(x i  1)  c
v  y  yi 
 yi
b
  bv  a(x i  1)  byi  c
vdx = F(x i +1,yi )
2vx  2F(x i  1,yi )
 2a(x i  1)  2byi  2c
1
 2a(x i  1)  2b(yi  )  2c  b
2
1
 2F(x i  1,yi  )  x
2
 Pi  x
1
 vx  (Pi  x)
2
(x i  1,yi )
D 
vx
x  y
2
2

2vx
2 x  y
2
2

(Pi  x)
2 x   y
2
2
(x i  1,yi  1):
2(1  v)x  2x  2vx
2x-2vx
2x
2vx
D 


2
2
2
2
2 x  y
2 x  y
2 x 2  y 2
(x i  1,yi  1):
2(1  v)x  2x  2vx
D 
2x
2 x 2  y 2

2 vx
2 x 2  y 2
,
IF (Cont’)v  0
Similarly,
Pi  0: (x i  1,yi  1)
2vx  Pi  x
D
1-v
2vx
2 x 2  y 2
v
 D
M
1+v
(x i  1,yi  2):
2x  2vx
D
2x
2 x 2  y 2
P  (x p , y p )

2vx
2 x 2  y 2
(x i  1,yi ):
2x  2vx
D
2x
2 x 2  y 2

2vx
2 x 2  y 2
x := x2 - x1;
y := y2 - y1;
p := 2 *y - x;
{Initial value p1 as before}
incrE := 2 * y;
{Increment used for move to E}
incrNE := 2 * (y - x);
{Increment used for move to NE}
two_v_x := 0;
{Numerator; v = 0 for start pixel}
invDenom := 1 / (2 * Sqrt(x * x + y * y));
{Precomputed inverse denominator}
two_x_invDenom := 2 * x * invDenom;
{Precomputed constant}
1
x := x1;
2 x 2  y 2
y := y1;
IntensifyPixel (x, y, 0);
{Start pixel}
IntensifyPixel(x, y + 1, two_x_invDenom);
{Neighbor}
IntensifyPixel(x, y - 1, two_x_invDenom);
{Neighbor}
while x < x2 do
begin
if p < 0 then
begin
{Choose E}
two_v_x := p + x;
p := p + incrE;
x := x + 1
end
else
begin
{Choose NE}
two_v_x := p - x;
p := p + incrNE;
x := x + 1;
y := y + 1;
end;
{Now set chosen pixel and its neighbors}
IntensifyPixel (x, y, two_v_x * invDenom);
IntensifyPixel (x, y + 1, two_x_invDenom - two_v_x * invDenom);
IntensifyPixel (x, y - 1, two_x_invDenom + two_v_x * invDenom)
end {while}
IF (Cont’)
2vx •
D •
•
initially,
v0
2vx  0
•
•
•
•
•
•
•
•
3. Circle Drawing
(x  xc) 2  (y  yc) 2  r 2
r
y  yc  r 2  (x  xc) 2
yc
xc
r
yc
θ
x  xc  rcosθ
y  yc  rsin θ
xc
symmetry
(0,r)
(y, x)
( y, x)
r
( x, y)
45
o
(  x,  y)
(x, y)
(x, y)
(  y,  x)
(y, x)
using symmetry
Midpoint Circle Algorithm
(xi, yi)
(xi  1, yi)
E
1
(xi  1, yi  )
2
M
x 2  y2  R 2
ME
SE
(xi  1, yi  1)
MSE
Current Choices for
pixel
next pixel
Let F(x, y)  x 2  y 2  R 2
if F(M)  0
(x i  1, y i )
(x i 1 , y i 1 )  
(x i  1, y i  1) otherwise
MCA (Cont’)
(0, R)
1
1
Let Pi  F(x i  1,yi  )  (x i  1) 2  (yi  ) 2  R 2
2
2
1
1
Pi 1  F(x i 1  1,yi 1  )  (x i  2) 2  (yi 1  ) 2  R 2 , where
2
2
x i 1  x i  1
if Pi  0
y
yi 1   i
 yi  1 otherwise
if Pi  0
 Pi  2x i  3
 Pi 1  
 Pi  2(x i  yi )  5 otherwise
5
1
1
P1  F(x1  1,y1  )  (0  1) 2  (R  ) 2  R 2   R since (x1 ,y1 )  (0,R)
4
2
2
MCA (Cont’)
In summary,
if Pi  0
(x i  1,yi )
(x i 1 ,y i 1 )  
(x i  1,yi  1) otherwise
if Pi  0
 Pi  (2x i  3)
 Pi 1  
 Pi  (2x i  2yi  5) otherwise
5
P1  -R
4
procedure MidpointCircle (radius,value : integer);
(0, R)
MCA (Cont’)
var
x,y : integer; P: real;
y=x
begin
x := 0;
{ initialization }
y := radius;
*
P := 5/4 - radius;
CirclePoints(x,y,value);
d = P - 1/4
P = d + 1/4
while y > x do begin
if P < 0 then
{ select E }
P : = P + 2*x + 3;
**
***
*
d = 1 - radius
**
d < -1/4  d < 0
x := x + 1;
why?
end
else begin
{ select SE }
P := P + 2*(x - y) + 5;
x := x + 1;
y := y - 1;
end
CirclePoints(x,y,value)
end { while }
end; { MidpointCircle }
****
*** d := d + 2*x + 3
**** d := d + 2(x-y) + 5
procedure MidpointCircle (radius,value : integer);
{ Assumes center of circle is at origin. Integer arithmetic only }
MCA (Cont’)
var
x,y,d : integer;
begin
x := 0;
{ initialization }
y := radius;
d := 1 - radius;
CirclePoints(x,y,value);
while y > x do begin
if d < 0 then
{ select E }
Can you go further?
d := d + 2*x + 3;
x := x + 1;
end
else begin
{ select SE }
d := d+2*(x - y) + 5;
x := x + 1;
y := y - 1;
end
CirclePoints(x,y,value)
end { while }
end; { MidpointCircle }
MCA (Cont’)
Pi 1  Pi  Pi

if Pi  0
 2x i  3
Pi  Pi 1  Pi  

 2(x i  yi )  5 otherwise
(x i ,yi )  (x i  1,yi )
PiE1  2(x i  1)  3  PiE  2
SE
PiSE
2
1  2(x i  1  y i )  5  Pi
(x i ,yi )  (x i  1,yi  1)
PiE1  2(x i  1)  3  PiE  2
SE
PiSE
4
1  2(x i  1  y i  1)  5  Pi
At (x1 ,y1 )

if P1  0
3
P1  

 2R  5 otherwise
(P1E )
(P1SE )
(PiE )
(PiSE )
MCA (Cont’)
procedure MidpointCircle (radius,value : integer);
{ This procedure uses second-order partial differences to compute
increments in the decision variable. Assumes center of circle is origin. }
var
x,y,d,deltaE,deltaSE : integer;
begin
x := 0;
{ initialization }
y := radius;
d := 1 - radius;
else begin
deltaE := 3;
{ select SE }
deltaSE := -2*radius + 5;
d := d + deltaSE;
CirclePoints(x,y,value);
deltaE := deltaE + 2;
while y > x do begin
deltaSE := deltaSE + 4;
if d < 0 then
x := x + 1;
{ select E }
y := y - 1
d := d + deltaE;
deltaE := deltaE + 2;
end
deltaSE := deltaSE + 2;
CirclePoints(x,y,value)
x := x + 1;
end
end { while }
end; { MidpointCircle }
Drawing Ellipse
x 2 y2
 2 1
2
r1
r2
r2
r1
yc
xc
x2
y  r (1  2 )
r1
2
2
2
Homework #3
Modify the midpoint circle drawing
algorithm to draw ellipses.
4. Curve Drawing
 y  f(x)
 parametric equation
y  g(t)
x  h(t)
 discrete data set
− curve fitting
− piecewise linear