Presentation is loading. Please wait.

Presentation is loading. Please wait.

Michener’s Algorithm An efficient scheme for drawing circles (and filling circular disks) on a raster graphics display.

Similar presentations


Presentation on theme: "Michener’s Algorithm An efficient scheme for drawing circles (and filling circular disks) on a raster graphics display."— Presentation transcript:

1 Michener’s Algorithm An efficient scheme for drawing circles (and filling circular disks) on a raster graphics display

2 Scan 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 it’s called scan conversion Imperfections: unavoidable, but to be minimized

3 Graphics 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

4 Eight-fold symmetry (-x, y) (x, y) (-y, x) (y, x) (y, -x) (-y, -x)

5 Compute only one octant

6 Subroutine: 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 );

7 The “best” pixel to draw?
Blue pixel: too far from center ( E > 0 ) Red pixel: too near the center ( E < 0 ) Error-term: E = (x2 + y2) – R2

8 Decision at n-th stage Pn-1 An ? yn-1 Bn ? xn-1 xn
Algorithm: compute sum = error( An ) + error( Bn ); If ( sum < 0 ) choose A n; otherwise choose B n.

9 Formula: sum of error-terms
Assume circle has radius R, center (0,0) error( An) = (xn-1+1)2 + (yn-1)2 – R2 error( Bn) = (xn-1+1)2 + (yn-1 – 1)2 – R2 sumn = 2(xn-1+1)2 + 2(yn-1)2 –2(yn-1) + 1-2R2 Now, how is sumn different from sumn+1: If An is chosen at the n-th step? If Bn is chosen at the n-th step?

10 Difference Equation Observe that: sumn+1 – sumn = 4xn (yn2 – yn-12) – 2(yn – yn-1) When An is selected at n-th stage: we will have yn = yn-1 thus: sumn+1 = sumn + 4xn-1 + 6 When Bn is selected at n-th stage: we will have yn = yn-1 - 1 thus: sumn+1 = sumn + 4(xn-1 – yn-1) + 10

11 Algorithm 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 + R2–2R+1) – R2] = 3 – 2R

12 Michener’s Algorithm int x = 0, y = R, sum = 3 – 2*R;
while ( x <= y ) { draw_octant_points( x, y, xc, yc, color ); if ( sum < 0 ) sum += 4*x + 6; else { sum += 4*(x - y) + 10; --y; } ++x; }

13 Reference Francis S. Hill, jr., “Computer Graphics,” Macmillan (1990), pp NOTE: Michener’s 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 ).

14 Circle ‘fill’ also exploits symmetry
(-x, y) (x, y) (-y, x) (y, x) (y, -x) (-y, -x) (-x, -y) (x, -y)

15 Subroutine: 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 );

16 draw_horiz( int xlo, xhi, y, color );
Clipping to screen boundaries: If (( y < ymin )||( y > ymax )) return; if ( xlo < xmin ) xlo = xmin; if ( xhi > xmax ) xhi = xmax; Drawing the horizontal segment: for (x = xlo; x <= xhi; x++) draw_pixel( x, y, color );

17 Demo-program Try the ‘michener.cpp’ demo
It uses VESA graphics-mode 0x4101 Screen resolution is 640x480 Color depth is 8 bits-per-pixel (8bpp) SVGA’s Linear Frame Buffer is enabled

18 In-Class Exercise Modify the ‘michener.cpp’ demo:
Use the standard ‘rand()’ function Draw lots of color-filled circles Stop if user hits <ESCAPE> key NOTE: For the latter feature, we need to discuss setting up the terminal keyboard so it uses a ‘non-canonical’ input-mode

19 The ‘tty’ interface ‘tty’ is an acronyn for ‘TeleTYpe’ terminal
Such devices have a keyboard and screen Behavior emulates technology from 1950s Usually a tty operates in ‘canonical’ mode: Each user-keystroke is ‘echoed’ to screen Some editing is allowed (e.g., backspace) The keyboard-input is internally buffered The <ENTER>-key signals an ‘end-of-line’ Programs receive input one-line-at-a-time

20 ‘tty’ customization Sometimes canonical mode isn’t suitable (an example: animated computer games) The terminal’s behavior can be modified! UNIX provides a convenient interface: #include <termios.h> struct termios tty; int tcgetattr( int fd, struct termios *tty ); int tcsetattr( int fd, int flag, struct termios *tty );

21 TeleTYpe display device
How does the ‘tty’ work? application User space tty_driver c_lflag Kernel space input handling c_iflag c_cc output handling c_oflag SOFTWARE struct tty { c_iflag; c_oflag; c_cflag; c_lflag; c_line; c_cc[ ]; }; terminal_driver c_cflag HARDWARE TeleTYpe display device

22 The ‘c_lflag’ field This field is just an array of flag bits
Individual bits have symbolic names Names conform to a POSIX standard Linux names match other UNIX’s names Though actual symbol values may differ Your C/C++ program should use: #include <termios.h> for portability to other UNIX environments

23 ICANON and ECHO Normally the ‘c_lflag’ field has these set
They can be cleared using bitwise logic: tty.c_lflag &= ~ECHO; // inhibit echo tty.c_lflag &= ~ICANON; // no buffering

24 The ‘c_cc[ ]’ array ‘struct termios’ objects include an array
The array-indices have symbolic names Symbol-names are standardized in UNIX Array entries are ‘tty’ operating parameters Two useful ones for our purposes are: tty.c_cc[ VMIN ] and tty.c_cc[ VTIME ]

25 How to setup ‘raw’ terminal-mode
Step 1: Use ‘tcgetattr()’ to get a copy of the current tty’s ‘struct termios’ settings Step 2: Make a working copy of that object Step 3: Modify its flags and control-codes Step 4: Use ‘tcsetattr()’ to install changes Step 5: Perform desired ‘raw’ mode input Step 6: Use ‘tcsetattr()’ to restore the terminal to its original default settings

26 ‘raw’ mode needs four changes
tty.c_cc[ VMIN ] = 1; so the ‘read()’ function will return as soon as at least one new input-character is available tty.c_cc[ VTIME ] = 0; so there will be no time-delay after each new key pressed until the ‘read()’ function returns tty.c_lflag &= ~ECHO; // no echoing tty.c_lflag &= ~ICANON; // no buffering

27 Demo program: ‘rawtty.cpp’
This program may soon prove useful It shows the keyboard scancode values It demonstrates ‘noncanonical’ tty mode It clears the ISIG bit (in ‘c_lflags’ field) This prevents <CONTROL>-C from being used to abort the program: the user must ‘quit’ by hitting the <ESCAPE>-key; so default terminal-settings will get reinstalled

28 In-class Exercise Use the Linux ‘tty’ interface-functions to reprogram your terminal for ‘raw’ input Draw ramdom color-filled circles -- until your user hits the <ESCAPE> key Algorithm: int done = 0; do { draw_next_circle( x, y, r, color ); int inch = 0; read( 0, &inch, 4 ); if ( inch == 0x1B ) done = 1; } while ( !done );


Download ppt "Michener’s Algorithm An efficient scheme for drawing circles (and filling circular disks) on a raster graphics display."

Similar presentations


Ads by Google