Path: utzoo!mnetor!uunet!husc6!bloom-beacon!gatech!purdue!i.cc.purdue.edu!j.cc.purdue.edu!pur-ee!uiucdcs!uxc.cso.uiuc.edu!uxe.cso.uiuc.edu!mcdonald From: mcdonald@uxe.cso.uiuc.edu Newsgroups: comp.graphics Subject: Re: circles with non-unity aspect ratio Message-ID: <46900007@uxe.cso.uiuc.edu> Date: 6 Jan 88 17:31:00 GMT References: <807@hsi.UUCP> Lines: 120 Nf-ID: #R:hsi.UUCP:807:uxe.cso.uiuc.edu:46900007:000:3894 Nf-From: uxe.cso.uiuc.edu!mcdonald Jan 6 11:31:00 1988 >I am trying to draw "good" circles on an AT&T 3b1 (aka, UNIX PC). >The problem is the aspect ratio - it is nowhere near unity. >I have gone through McIlroy's paper ("Best Approximate Circles on >Integer Grids") and Foley & Van Dam. I see two ways to draw the circle: >(1) Utilize "user coordinates" (in this case a 4096 by 4096 square) Bad idea. >(2) Utilize "device coordinates" (430 by 288, in this case). The correct way. >Am I missing something simple that would make it easy to draw my >circles ?? Can anyone point me to another reference that adequately >covers the drawing of a circle on a screen with a non-unity aspect >ratio (F & VD mention a few, but before I go digging up the articles, >does anyone know if these are what I should be looking at) ?? It's not really easy to generate good looking circles on a pixel grid. After trying lots of different things, I have adopted the following ellipse drawer. It draws ellipses in pixel space; to get circles you feed it the proper height and width in pixels. This thine works really well for circles with a radius greater than 4. For smaller circles, it pays in terms of looking nice to draw each size as a special case. The enclosed program uses the standard Bresnahan algorithm for the best approximation of a curve. It is optimized for speed. There was a good reference to this an article in Dr. Dobbs Journal in 1987, but for circles only, not ellipses. I hope that this can help you. Doug McDonald Department of Chemistry University of Illinois /* Draw an ellipse with width irx and height iry */ /* from a routine by Tim Hogan in Dr. Dobb's Journal May '85 p.40 */ /* Improved by calculating increments incrementally, thus removing all */ /* multiplies from the loops. These multiplies were very bad since they */ /* were (long)*(long). */ /* Written Sept. 7, 1987 by J.D. McDonald (public domain) */ static long alpha, beta, alpha2, alpha4, beta2, beta4, d; static long ddx, ddy, alphadx, betady; static int dy, dx; extern void e_start(int, int, int ,int); extern void e_xd(); extern void e_xdyu(); extern void e_yu(); ellipse(x, y, irx, iry, c) int x, y, irx, iry; unsigned c; { beta = (long) irx *(long) irx; alpha = (long) iry *(long) iry; if (alpha == 0L) alpha = 1L; if (beta == 0L) beta = 1L; dy = 0; dx = irx; alpha2 = alpha << 1; alpha4 = alpha2 << 1; beta2 = beta << 1; beta4 = beta2 << 1; alphadx = alpha * dx; betady = 0; ddx = alpha4 * (1 - dx); ddy = beta2 * 3; d = alpha2 * ((long) (dx - 1) * dx) + alpha + beta2 * (1 - alpha); e_start(x - dx, x + dx, y, c); /* e_start draws left and rightmost pixels on vertical centerline */ /* e_yu draws a pixel in right top quadrant one up from previous */ /* e_xd draws a pixel in right top quadrant one left from previous*/ /* e_xdyu draws a pixel in right top quadrant up and left from */ /* previous. e_yu, e_xd, and e_xdyu also draw the corresponding */ /* pixels in the other three quadrants. */ /* c is the color */ do { if (d >= 0) { d += ddx; dx--; alphadx -= alpha; ddx += alpha4; e_xdyu(); } else e_yu(); d += ddy; dy++; betady += beta; ddy += beta4; } while (alphadx > betady); d = beta2 * ((long) dy * (dy + 1)) + alpha2 * ((long) dx * (dx - 2) + 1) + beta * (1 - alpha2); ddx = alpha2 * (3 - (dx << 1)); ddy = beta4 * (1 + dy); do { if (d <= 0) { d += ddy; ddy += beta4; dy++; e_xdyu(); } else e_xd(); d += ddx; ddx += alpha4; dx--; } while (dx > 0); }