circle drawing
play

Circle Drawing Parametric equation radius R , center at origin is a - PowerPoint PPT Presentation

Circle Drawing Parametric equation radius R , center at origin is a parameter in [0..2) x = R*cos y = R*sin Algorithm based on the parametric equation: def drawCircleParam(radius, color): step = ??? for alpha in [0 : 2*M_PI] by


  1. Circle Drawing Parametric equation – radius R , center at origin α is a parameter in [0..2π) x = R*cos α y = R*sin α Algorithm based on the parametric equation: def drawCircleParam(radius, color): step = ??? for alpha in [0 : 2*M_PI] by step: x = radius*cos(alpha) y = radius*sin(alpha) setPixel(x, y, color) What step to choose for the angle – small for big radius, big for small radius? Uses double and expensive operations cos , sin

  2. Results Parametric Eq.

  3. Circle Drawing Implicit equation – radius R , center at origin x 2 + y 2 - R 2 = 0 Explicit equation – solve for y : y = ±√ (R 2 - x 2 ) Algorithm based on the explicit equation: def drawCircleExpl (radius, color): for x in [-radius : radius]: y = sqrt(radius*radius - x*x) setPixel(x, y, color) setPixel(x, -y, color) Draws points densely around origin, leaves gaps farther away Uses double and expensive operation sqrt

  4. Results Explicit Eq.

  5. Midpoint Algorithm for Circles Use similar idea as in the line drawing algorithm midpoint determines which pixel to intensify Again will use the explicit equation: F(x, y) = x 2 + y 2 - R 2 point is on the circle F(x, y) = 0 point inside circle F(x, y) < 0 point outside circle F(x, y) > 0 Will also use the fact that there is 8-point symmetry: (-x ,y) (x,y) (y,x) (-y,x) (-y,-x) (y,-x) (x,-y) (-x,-y)

  6. Midpoint Algorithm for Circles Use similar idea as in the line drawing algorithm midpoint determines which pixel to intensify M M M E M SE midpoint M outside circle – intensify pixel below M , consider point M SE next midpoint M inside circle – intensify pixel above M , consider point M E next

  7. Circle Drawing (Midpoint) If we know the value at F(M) can we calculate efficiently F(M E ) and F(M SE ) Calculating the value F(M E ) Coordinates: M(x m ,y m ) M E (x m +1,y m ) M E M F(M E ) = (x m +1) 2 + y m 2 - R 2 = ? Calculating the value F(M SE ) Coordinates: M(x m ,y m ) M E (x m +1,y m -1) M F(M SE ) = (x m +1) 2 + (y m -1) 2 - R 2 = ? M SE

  8. Circle Drawing (Midpoint) If we know the value at F(M) can we calculate efficiently F(M E ) and F(M SE ) Calculating the value F(M E ) Coordinates: M(x m ,y m ) M E (x m +1,y m ) M E M F(M E ) = (x m +1) 2 + y m 2 - R 2 = = x m 2 + 2x m + 1 + y m 2 - R 2 = = x m 2 + y m 2 - R 2 + 2x m + 1 = = F(M) + 2x m + 1 Calculating the value F(M SE ) Coordinates: M(x m ,y m ) M E (x m +1,y m -1) M F(M SE ) = (x m +1) 2 + (y m -1) 2 - R 2 = = x m 2 + 2x m + 1 + y m 2 - 2y m + 1 - R 2 = M SE = x m 2 + y m 2 - R 2 + 2x m - 2y m + 2 = = F(M) + 2x m - 2y m + 2

  9. Circle Drawing (Midpoint) Need initial value of F(M) to start the algorithm P 0 P 0 M M Coordinates of M = ? F(M) = ?

  10. Circle Drawing (Midpoint) Need initial value of F(M) to start the algorithm P 0 P 0 M M Coordinates of M = (1, R – ½) F(M) = 1 2 + (R – ½) 2 - R 2 = 5/4 - R

  11. The Algorithm Inefficient version as first attempt: always computes F(M) = d = xm 2 + ym 2 - R 2 def drawCircle(R, c): xp, yp = 0, R xm, ym = 1, R-0.5 circlePoints(xp, yp, c) while x > y: d = xm 2 + ym 2 - R 2 # F(M) if d < 0: # going E xp, yp = xp+1, yp xm, ym = xm+1, ym else: # going SE xp, yp = xp+1, yp+1 xm, ym = xm+1, ym+1 circlePoints(x, y, c)

  12. The Algorithm Inefficient version as first attempt: Better version: incrementally updates F(M) always computes F(M) = d = xm 2 + ym 2 - R 2 def drawCircle(R, c): def drawCircle(R, c): xp, yp = 0, R xp, yp = 0, R xm, ym = 1, R-0.5 xm, ym = 1, R-0.5 d = 5/4 – R # F(M0) circlePoints(xp, yp, c) circlePoints(xp, yp, c) while x > y: while x > y: d = xm 2 + ym 2 - R 2 # F(M) d = xm 2 + ym 2 - R 2 # F(M) if d < 0: if d < 0: # going E # going E xp, yp = xp+1, yp d += 2*xm + 1 xm, ym = xm+1, ym xp, yp = xp+1, yp else: xm, ym = xm+1, ym # going SE else: xp, yp = xp+1, yp+1 # going SE xm, ym = xm+1, ym+1 d = 2*xm – 2*ym + 2 xp, yp = xp+1, yp+1 circlePoints(x, y, c) xm, ym = xm+1, ym+1 circlePoints(x, y, c)

  13. The Algorithm Since xp,yp and xm,ym move together in the same way can derive xm,ym from xp,yp xm = xp + 1 ym = yp – 0.5 def drawCircle(R, c): xp, yp = 0, R xm, ym = 1, R-0.5 d = 5/4 – R # F(M0) circlePoints(xp, yp, c) while x > y: if d < 0: # going E d += 2*xm + 1 = 2*(xp+1) + 1 xp, yp = xp+1, yp xm, ym = xm+1, ym else: # going SE d = 2*xm – 2*ym + 2 = 2*(xp+1) – 2*(yp-.5) + 2 xp, yp = xp+1, yp+1 xm, ym = xm+1, ym+1 circlePoints(x, y, c)

  14. The Algorithm Getting rid of the fraction 5/4 def drawCircle(R, c): xp, yp = 0, R d = 5/4 – R circlePoints(xp, yp, c) while x > y: if d < 0: # going E d += 2*xp + 3 xp, yp = xp+1, yp else: # going SE d = 2*xp – 2*yp + 5 xp, yp = xp+1, yp+1 circlePoints(x, y, c)

  15. The Algorithm Getting rid of the fraction 5/4 def drawCircle(R, c): xp, yp = 0, R d = 5/4 – R – 1/4 = 1 – R # start d ¼ less than what it should be, # which makes d an integer value circlePoints(xp, yp, c); # # then the condition becomes: while x > y: # # if d < 0: # if d < -1/4: # going E # d += 2*xp + 3 # but since d is an integer and always xp, yp = xp+1, yp # updates by integers, it stays integer, else: # so to be < -1/4, it must be < 0 # going SE # d = 2*xp – 2*yp + 5 # thus, the conditions is unchanged xp, yp = xp+1, yp+1 circlePoints(x, y, c)

  16. Antialiasing for Circles Use similar idea as in the line drawing algorithm intensify the selected vertex and its neighbors based on distance to circle P N M P P S Exact distance D P is harder to compute efficiently. Use the approximation F(P) ~ 2*D P *R Keep track of F(P) – same as F(M) i.e. same increments, different initial value Compute F(P N ) , F(P S ) as we did for F(M E ) , F(M SE ) and compute D P , D P N , D P S

Recommend


More recommend