Title: Michener
1Micheners Algorithm
- An efficient scheme for drawing circles (and
filling circular disks) on a raster graphics
display
2Scan conversion
- Geometric objects possess implicit parameters
- Example A circle has a center and a radius
- Its equation is (x xc)2 (y - yc)2 R2
- x and y are from the continuum of real numbers
- CRT display is a discrete 2D array of pixels
- So drawing a circle requires a conversion, from
something continuous into something discrete - In computer graphics its called scan conversion
- Imperfections unavoidable, but to be minimized
3Graphics Animations
- Fast drawing is essential for animations
- Some guidelines for speed
- eliminate all redundant computations
- prefer integer arithmetic to floating-point
- prefer add and subtract to multiply or divide
- Famous example Michener Algorithm
- We can use it later with our pong game
4Eight-fold symmetry
(x, y)
(-x, y)
(y, x)
(-y, x)
(y, -x)
(-y, -x)
(-x, -y)
(x, -y)
5Compute only one octant
6Subroutine draw_octant_points
- Arguments int x, y, xcent, ycent, color
- draw_pixel( xcent x, ycent y, color )
- draw_pixel( xcent y, ycent x, color )
- draw_pixel( xcent - x, ycent y, color )
- draw_pixel( xcent - y, ycent x, color )
- draw_pixel( xcent x, ycent - y, color )
- draw_pixel( xcent y, ycent - x, color )
- draw_pixel( xcent - x, ycent - y, color )
- draw_pixel( xcent - y, ycent - x, color )
7The best pixel to draw?
Blue pixel too far from center
( E gt 0 )
Red pixel too near the center (
E lt 0 )
Error-term E (x2 y2) R2
8Decision at n-th stage
Pn-1
An ?
yn-1
Bn ?
xn-1
xn
Algorithm compute sum error( An ) error(
Bn ) If ( sum lt 0 ) choose A n otherwise
choose B n.
9Formula sum of error-terms
- Assume circle has radius R, center (0,0)
- error( An) (xn-11)2 (yn-1)2 R2
- error( Bn) (xn-11)2 (yn-1 1)2 R2
- sumn 2(xn-11)2 2(yn-1)2 2(yn-1) 1-2R2
- Now, how is sumn different from sumn1
- If An is chosen at the n-th step?
- If Bn is chosen at the n-th step?
10Difference Equation
- Observe that sumn1 sumn 4xn-1 6
2(yn2 yn-12) 2(yn yn-1) - When An is selected at n-th stage
- we will have yn yn-1
- thus sumn1 sumn 4xn-1 6
- When Bn is selected at n-th stage
- we will have yn yn-1 - 1
- thus sumn1 sumn 4(xn-1 yn-1) 10
11Algorithm initialization
- We start with the point P0 (x0,y0), where x0
0 and y0 R - In this case A1 (1, R) and B1 (1, R-1)
- So the initial sum-of-errors term will be
- sum1 error(A1) error(B1)
- (12 R2) R2 (12 R22R1) R2
- 3 2R
12Micheners Algorithm
- int x 0, y R, sum 3 2R
- while ( x lt y )
-
- draw_octant_points( x, y, xc, yc, color )
- if ( sum lt 0 ) sum 4x 6
- else sum 4(x - y) 10 --y
- x
-
13Reference
- Francis S. Hill, jr., Computer Graphics,
Macmillan (1990), pp. 433-435. - NOTE Micheners circle-drawing method owes its
inspiration to a famous algorithm for efficient
line-drawing, devised in 1965 by J. E. Bresenham
(see the IBM Systems Journal, vol 4, pp. 305-311).
14Circle fill also exploits symmetry
(x, y)
(-x, y)
(y, x)
(-y, x)
(y, -x)
(-y, -x)
(-x, -y)
(x, -y)
15Subroutine draw_segments
- Arguments int x, y, xc, yc, color
- draw_horiz( xc x, xc x, yc y, color )
- draw_horiz( xc x, xc x, yc - y, color )
- draw_horiz( xc y, xc y, yc x, color )
- draw_horiz( xc y, xc y, yc - x, color )
16draw_horiz( int xlo, xhi, y, color )
- Clipping to screen boundaries
- If (( y lt ymin )( y gt ymax )) return
- if ( xlo lt xmin ) xlo xmin
- if ( xhi gt xmax ) xhi xmax
- Drawing the horizontal segment
- for (x xlo x lt xhi x)
- draw_pixel( x, y, color )
17Demo-program
- Try the michener.cpp demo
- It uses VESA graphics-mode 0x0103
- Screen resolution is 800x600
- Color depth is 8 bits-per-pixel (8bpp)
- SVGAs Linear Frame Buffer is enabled by calling
VESAs Set Display Mode service with bit 14 of
the mode ID-number set
18In-Class Exercise 1
- Modify the michener.cpp demo
- Use the standard rand() function
- Draw lots of color-filled circles
- Stop if user hits ltESCAPEgt key
- NOTE For this latter feature, we need to recall
how to set up the terminal keyboard so it uses a
non-canonical input-mode
19Animation with image tearing
- We used Michners Algorithm in a graphics
animation demo (named bouncing.cpp) - But you will see undesirable tearing of the
bouncing balls image because we drew a large
number of pixels, and computed a large number of
pixel-locations twice for each displayed frame
(erase, then redraw) - Not enough drawing time during retrace!
20What can we do about it?
- One idea is to draw a smaller-sized ball
- Another idea is to draw only once i.e. include
enough extra pixels around the new balls
perimeter to hide the old one - Also we could pre-compute coordinates
- An important general technique is to use
off-screen display memory to prepare a new
screen-image, and then do a bitblit
21SuperVGAs hardware
- The graphics processor has the capability to
switch the CRTCs start_address, so we see a
new full-screen image displayed almost instantly
(i.e., just one or two CPU instructions), instead
of a copying a screen - But doing this for higher-resolution SVGA
display-modes requires accessing one or more of
the nonstandard VGA extensions
22VESAs BIOS-Extensions
- Video Electronics Standards Association defines a
ROM-BIOS service that can be invoked to reprogram
CRT Start_Address in a standard way for compliant
systems - For a particular vendors graphics card, we can
discover how to directly reprogram the CRTs
Start-Address, by trapping the I/O instructions
used in the ROM-BIOS routine
23Using off-screen video memory
Visible screen
CRT Controllers Start-Address (default0)
The currently displayed image is defined in
this region of VRAM
while an alternative image is prepared for
display in this region of VRAM
Alternate screen
When the alternate memory region is ready to
be displayed, the CRT Start-Address register is
rewritten, instantaneously changing what the
user sees on the display monitor
The technique is called page flipping
VRAM
24VBE service 0x07
- This ROM-BIOS service can be called to obtain or
modify the CRT Start-Address - It isnt instantaneous because of all the
parameter-passing and changing of CPU
execution-mode and transitions back and forth
from user-space to kernel-space - But it might be fast enough to cure the
image-tearing we saw in bouncing demo
25In-class exercise 2
- Look at documentation for VESA service 7
- See if you can modify the main animation loop in
our bouncing.cpp program so the image-frames
are alternately drawn in two different pages of
the video memory (i.e., implement the
page-flipping idea) while one frame is being
viewed by the user, the next frame is being
readied out-of-sight