Author Topic: Circle Packing  (Read 4586 times)

0 Members and 1 Guest are viewing this topic.

Offline Prithak

  • Newbie
  • Posts: 56
  • Life itself is a Programming Language!
    • View Profile
    • My Programming Language
Re: Circle Packing
« Reply #15 on: April 10, 2019, 12:00:07 am »
Another idea from Shiffman, Circle Packing.

Basic random fill:
Code: QB64: [Select]
  1. _TITLE "Circle Packing 1 fill" 'B+ started 2019-04-07  just basic random fill space
  2. CONST xmax = 800
  3. CONST ymax = 600
  4. SCREEN _NEWIMAGE(xmax, ymax, 32)
  5.  
  6. TYPE CircleType
  7.     x AS SINGLE
  8.     y AS SINGLE
  9.     r AS SINGLE
  10.     c AS _UNSIGNED LONG
  11.     growing AS INTEGER
  12. REDIM SHARED circles(1 TO 1) AS CircleType
  13. DIM SHARED flagDone AS INTEGER
  14.  
  15. WHILE _KEYDOWN(27) = 0 AND flagDone = 0
  16.     CLS
  17.     newCircle 1
  18.     drawCircles
  19.     _DISPLAY
  20.     _LIMIT 60
  21. PRINT "done"
  22.  
  23. SUB drawCircles
  24.     FOR i = 1 TO UBOUND(circles)
  25.         IF circles(i).growing THEN 'check new r
  26.             testr = circles(i).r + 2
  27.             IF circles(i).x - testr < 0 OR circles(i).x + testr > xmax OR circles(i).y - testr < 0 OR circles(i).y + testr > ymax THEN
  28.                 circles(i).growing = 0
  29.             ELSE
  30.                 'check if run into another circle
  31.                 FOR j = 1 TO UBOUND(circles)
  32.                     IF j <> i THEN
  33.                         IF SQR((circles(j).x - circles(i).x) ^ 2 + (circles(j).y - circles(i).y) ^ 2) <= testr + circles(j).r THEN
  34.                             circles(i).growing = 0: circles(j).growing = 0
  35.                             EXIT FOR
  36.                         END IF
  37.                     END IF
  38.                 NEXT
  39.             END IF
  40.         END IF
  41.         IF circles(i).growing THEN circles(i).r = testr
  42.         fcirc circles(i).x, circles(i).y, circles(i).r, circles(i).c
  43.     NEXT
  44.     PRINT UBOUND(circles)
  45.  
  46. SUB newCircle (n)
  47.     FOR i = 1 TO n
  48.         attempts = 0
  49.         retry:
  50.         testX = RND * xmax: testY = RND * ymax
  51.         OK = -1
  52.         FOR j = 1 TO UBOUND(circles)
  53.             IF SQR((testX - circles(j).x) ^ 2 + (testY - circles(j).y) ^ 2) < circles(j).r + 2 THEN OK = 0: EXIT FOR
  54.         NEXT
  55.         IF OK THEN
  56.             new = UBOUND(circles) + 1
  57.             REDIM _PRESERVE circles(1 TO new) AS CircleType
  58.             circles(new).x = testX
  59.             circles(new).y = testY
  60.             circles(new).r = 1
  61.             circles(new).growing = -1
  62.             circles(new).c = _RGB32(RND * 155 + 100, RND * 155 + 100, RND * 155 + 100)
  63.         ELSE
  64.             attempts = attempts + 1
  65.             IF attempts > 3000 THEN flagDone = -1: EXIT SUB
  66.             GOTO retry
  67.         END IF
  68.     NEXT
  69.  
  70. 'from Steve Gold standard
  71. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  72.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  73.     DIM X AS INTEGER, Y AS INTEGER
  74.  
  75.     Radius = ABS(R)
  76.     RadiusError = -Radius
  77.     X = Radius
  78.     Y = 0
  79.  
  80.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  81.  
  82.     ' Draw the middle span here so we don't draw it twice in the main loop,
  83.     ' which would be a problem with blending turned on.
  84.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  85.  
  86.     WHILE X > Y
  87.         RadiusError = RadiusError + Y * 2 + 1
  88.         IF RadiusError >= 0 THEN
  89.             IF X <> Y + 1 THEN
  90.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  91.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  92.             END IF
  93.             X = X - 1
  94.             RadiusError = RadiusError - X * 2
  95.         END IF
  96.         Y = Y + 1
  97.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  98.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  99.     WEND
  100.  
  101.  
It's more fun with images:
I've seen that video!
CLS
IF computer$ = "ON" THEN
me$ = "Happy!"
ELSE
me$ = "Time To Draw!"
END IF
END