December 04, 2020, 10:55:37 AM

Author Topic: [bmx] Draw Filled Circle Row by Row with Integer Math by ImaginaryHuman [ 1+ years ago ]  (Read 394 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
Title : Draw Filled Circle Row
Author : Row with Integer Math by ImaginaryHuman
Posted : 1+ years ago

Description : This draws a filled circle row by row and does not use any floating point math or trigonometry - it is entirely integer based. The rows are filled using calls to DrawRect and each is drawn separately. This example actually draws a filled circle and a hollow circle at the same time. You can comment out the Plot commands to see only the filled circle, or comment out the DrawRect commands to see only the hollow circle. By both drawing at once in the same loop, they somewhat overwrite each other.

Code :
Code: BlitzMax
  1. 'Midpoint Circle algorithm
  2.  
  3. Strict
  4. Graphics 640,480,0
  5.  
  6. Local xCenter:Int=320
  7. Local yCenter:Int=240
  8. Local radius:Int
  9. Local p,x,y,prevy:Int
  10. Repeat
  11.         Cls
  12.         If MouseDown(1)
  13.                 xCenter=MouseX()
  14.                 yCenter=MouseY()
  15.         EndIf
  16.         radius=Abs(xCenter-MouseX())
  17.         x=0
  18.         y=radius
  19.         SetColor $FF,$88,$00
  20.         DrawRect xCenter-y,yCenter+x,y Shl 1,1
  21.         SetColor $FF,$FF,$FF
  22.         Plot xCenter+x,yCenter+y
  23.         Plot xCenter-x,yCenter+y
  24.         Plot xCenter+x,yCenter-y
  25.         Plot xCenter-x,yCenter-y
  26.         Plot xCenter+y,yCenter+x
  27.         Plot xCenter-y,yCenter+x
  28.         Plot xCenter+y,yCenter-x
  29.         Plot xCenter-y,yCenter-x
  30.         p=1-radius
  31.         While x<y-1
  32.                 prevy=y
  33.                 If p<0
  34.                         x:+1
  35.                 Else
  36.                         x:+1
  37.                         y:-1
  38.                 EndIf
  39.                 If p<0
  40.                         p=p+(x Shl 1)+1
  41.                 Else
  42.                         p=p+((x-y) Shl 1)+1
  43.                 EndIf
  44.                 If y<prevy And x<y
  45.                         SetColor $FF,$88,$00
  46.                         DrawRect xCenter-x,yCenter+y,x Shl 1,1
  47.                         DrawRect xCenter-x,yCenter-y,x Shl 1,1
  48.                         SetColor $FF,$FF,$FF
  49.                         Plot xCenter+x,yCenter+y
  50.                         Plot xCenter-x,yCenter+y
  51.                         Plot xCenter+x,yCenter-y
  52.                         Plot xCenter-x,yCenter-y
  53.                 EndIf
  54.                 SetColor $FF,$88,$00
  55.                 DrawRect xCenter-y,yCenter+x,y Shl 1,1
  56.                 DrawRect xCenter-y,yCenter-x,y Shl 1,1
  57.                 SetColor $FF,$FF,$FF
  58.                 Plot xCenter+y,yCenter+x
  59.                 Plot xCenter-y,yCenter+x
  60.                 Plot xCenter+y,yCenter-x
  61.                 Plot xCenter-y,yCenter-x
  62.         Wend
  63.         Flip
  64. Until KeyHit(KEY_ESCAPE)
  65. End


Comments :


ImaginaryHuman(Posted 1+ years ago)

 The previous code was inefficient in that it drew some of the rows more than once. I've now edited and uploaded modified code which makes sure to only draw each row once. It therefore works better with modes like LIGHTBLEND and is faster.This is meant to be in the BlitzMax code archives. You also don't have to use Plot or DrawRect - those are just a way of outputting the circle `data` to show that it works. You could write to memory pointers, to an array, whatever.


Rck(Posted 1+ years ago)

 
Code: [Select]
;Midpoint Circle algorithm

Graphics 640,480,0,2

Local xCenter% = 320
Local yCenter% = 240
Local radius%
Local p%, x%, y%, prevy%

Repeat
WaitEvent()
Cls
If MouseDown(1)
xCenter = MouseX()
yCenter = MouseY()
EndIf

radius = Abs(xCenter - MouseX())
x = 0
y = radius

msStart = MilliSecs()

Color $FF,$88,$00
Rect xCenter - y, yCenter + x, y Shl 1,1
Color $FF,$FF,$FF

Plot xCenter + x, yCenter + y
Plot xCenter - x, yCenter + y
Plot xCenter + x, yCenter - y
Plot xCenter - x, yCenter - y
Plot xCenter + y, yCenter + x
Plot xCenter - y, yCenter + x
Plot xCenter + y, yCenter - x
Plot xCenter - y, yCenter - x

p = 1 - radius

While x < y - 1

prevy = y

If p < 0
x = x + 1
Else
x = x + 1
y = y - 1
EndIf

If p < 0
p = p + (x Shl 1) + 1
Else
p = p + ((x - y) Shl 1) + 1
EndIf

If y < prevy And x < y Then
Color $FF,$88,$00
Rect xCenter - x, yCenter + y, x Shl 1,1
Rect xCenter - x, yCenter - y, x Shl 1,1
Color $FF,$FF,$FF
Plot xCenter + x, yCenter + y
Plot xCenter - x, yCenter + y
Plot xCenter + x, yCenter - y
Plot xCenter - x, yCenter - y
EndIf

Color $FF,$88,$00
Rect xCenter - y, yCenter + x, y Shl 1, 1
Rect xCenter - y, yCenter - x, y Shl 1, 1
Color $FF,$FF,$FF

Plot xCenter + y, yCenter + x
Plot xCenter - y, yCenter + x
Plot xCenter + y, yCenter - x
Plot xCenter - y, yCenter - x
Wend

drawTime = MilliSecs() - msStart
Text 20, 20, "Radius " + radius
Text 20, 30, "Draw time " + drawTime + " ms"

Flip(False)
Until KeyHit(1)
Port to BlitzPlus


ImaginaryHuman(Posted 1+ years ago)

 Cool! [/i]

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal