Author Topic: Port Mitosis simulation demo following that fine and clever coder in Java and JS  (Read 4127 times)

0 Members and 1 Guest are viewing this topic.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Hi guys

following a video demo that explains some ideas in JAVA e Javascript I love to port this to QB64

here a first result
(PS I have build a different FUNCTION to get collision result between cell and mouse)

Code: QB64: [Select]
  1. ' a porting to QB64 of Mitosis simulation as showed in this video
  2. '[youtube]https://www.youtube.com/watch?v=jxGS3fKPKJA[/youtube]
  3. TYPE Cell
  4.     x AS INTEGER
  5.     y AS INTEGER
  6.     Radius AS INTEGER
  7.     Colors AS _UNSIGNED LONG
  8.  
  9. CONST Hscreen = 400, Wscreen = 400, StartRadius = 20, MaxCells = 1000
  10. CONST True = -1, False = NOT True, MinRadius = 5
  11. CONST Blu = _RGB32(0, 0, 255): CONST Black = _RGB32(0, 0, 0)
  12. CONST Red = _RGB32(255, 0, 0): CONST Green = _RGB32(0, 255, 0)
  13. CONST White = _RGB(255, 255, 255)
  14. DIM SHARED A AS LONG, Cells(1 TO MaxCells) AS Cell, NumActiveCell AS INTEGER
  15. DIM SHARED FNameOn AS INTEGER, KeyS AS INTEGER
  16.  
  17. IF NOT Setup THEN PRINT "Error in Setup"
  18.     IF NOT Draws THEN PRINT "Error in Draws"
  19.     IF NOT MoveCell THEN PRINT "Error in movecell"
  20.     IF MousePressed THEN
  21.         F = CellClicked
  22.         'clear buffer of mouse input
  23.         WHILE _MOUSEBUTTON(1)
  24.             IF _MOUSEINPUT THEN REM
  25.         WEND
  26.  
  27.         IF F <> False THEN
  28.             PRINT "LeftClick on cell "; F
  29.             IF NumActiveCell < MaxCells AND (NOT DuplicateCell(F)) THEN PRINT "Error in Duplicatecell"
  30.         ELSE
  31.             PRINT "LeftClick out of cells"
  32.         END IF
  33.     END IF
  34.     KeyS = _KEYHIT
  35.     IF KeyS = 78 OR KeyS = 110 THEN FNameOn = NOT FNameOn
  36.     _LIMIT 10
  37. LOOP UNTIL KeyS = 32
  38.  
  39.  
  40. FUNCTION Setup
  41.     Setup = False
  42.     DIM b AS INTEGER
  43.     A = _NEWIMAGE(Wscreen, Hscreen, 32)
  44.     IF A < -1 THEN SCREEN A ELSE PRINT "Image handle for Screen not valid"
  45.     _TITLE "Mitosis Simulation"
  46.     _SCREENMOVE 10, 10
  47.     NumActiveCell = 10
  48.     FNameOn = False
  49.     FOR b = 1 TO NumActiveCell
  50.         IF b < 11 THEN
  51.             Cells(b).x = MinMax(5, Wscreen - 5)
  52.             Cells(b).y = MinMax(5, Hscreen - 5)
  53.             Cells(b).Radius = StartRadius
  54.             Cells(b).Colors = NewColor
  55.         ELSE
  56.             Cells(b).x = 0
  57.             Cells(b).y = 0
  58.             Cells(b).Radius = 0
  59.             Cells(b).Colors = 0
  60.         END IF
  61.     NEXT b
  62.     Setup = True
  63.  
  64. FUNCTION DuplicateCell (Index AS INTEGER)
  65.     DuplicateCell = False
  66.     NumActiveCell = NumActiveCell + 1
  67.     Cells(NumActiveCell).y = Cells(Index).y
  68.     Cells(NumActiveCell).Colors = Cells(Index).Colors
  69.     IF INT(Cells(Index).Radius / 2) > MinRadius THEN Cells(NumActiveCell).Radius = INT(Cells(Index).Radius / 2) ELSE Cells(NumActiveCell).Radius = MinRadius
  70.     Cells(Index).Radius = Cells(NumActiveCell).Radius
  71.     Cells(NumActiveCell).x = Cells(Index).x + MinMax(-Cells(Index).Radius, Cells(Index).Radius)
  72.     Cells(Index).x = Cells(Index).x + MinMax(-Cells(Index).Radius, Cells(Index).Radius)
  73.     DuplicateCell = True
  74.  
  75. FUNCTION MousePressed
  76.     MousePressed = False
  77.         IF _MOUSEBUTTON(1) = True THEN MousePressed = True
  78.     WEND
  79.  
  80. FUNCTION IsInTheRange (What AS INTEGER, Min AS INTEGER, Max AS INTEGER)
  81.     IsInTheRange = False
  82.     IF What > Min AND What < Max THEN IsInTheRange = True
  83.  
  84. FUNCTION CellClicked
  85.     CellClicked = False
  86.     DIM b AS INTEGER
  87.     FOR b = 1 TO NumActiveCell STEP 1
  88.         IF IsInTheRange(_MOUSEX, Cells(b).x - Cells(b).Radius, Cells(b).x + Cells(b).Radius) THEN
  89.             IF IsInTheRange(_MOUSEY, Cells(b).y - Cells(b).Radius, Cells(b).y + Cells(b).Radius) THEN
  90.                 CellClicked = b
  91.                 EXIT FUNCTION
  92.             END IF
  93.         END IF
  94.     NEXT b
  95.  
  96. FUNCTION InTheRange (What AS INTEGER, Min AS INTEGER, Max AS INTEGER)
  97.     InTheRange = False
  98.     IF What < Min THEN What = Min
  99.     IF What > Max THEN What = Max
  100.     InTheRange = True
  101.  
  102. FUNCTION MinMax (Min AS INTEGER, Max AS INTEGER)
  103.     MinMax = False
  104.     IF Min < Max THEN SWAP Min, Max
  105.     MinMax = INT(RND * (Max - Min + 1)) + Min
  106.  
  107. FUNCTION Draws
  108.     Draws = False
  109.     DIM b AS INTEGER
  110.     CLS , Black
  111.     FOR b = 1 TO NumActiveCell
  112.         IF NOT ShowCell THEN PRINT "Error in Showcell with value "; Cells(b).x; " "; Cells(b).y
  113.     NEXT b
  114.     Draws = True
  115.  
  116. FUNCTION MoveCell
  117.     MoveCell = False
  118.     DIM b AS INTEGER
  119.     FOR b = 1 TO NumActiveCell STEP 1
  120.         Cells(b).x = Cells(b).x + MinMax(-2, 2)
  121.         Cells(b).y = Cells(b).y + MinMax(-2, 2)
  122.         IF NOT InTheRange(Cells(b).x, 5, Wscreen - 5) THEN PRINT "Error IntheRange X"
  123.         IF NOT InTheRange(Cells(b).y, 5, Hscreen - 5) THEN PRINT "Error IntheRange Y"
  124.     NEXT b
  125.     MoveCell = True
  126.  
  127. FUNCTION NewColor
  128.     NewColor = False
  129.     c = _RGB32(MinMax(1, 255), MinMax(1, 255), MinMax(1, 255))
  130.     IF c < 0 THEN
  131.         PRINT "Error in NewColor "; c: EXIT FUNCTION
  132.     ELSE
  133.         NewColor = c
  134.     END IF
  135.  
  136. FUNCTION ShowCell
  137.     ShowCell = False
  138.     DIM b AS INTEGER
  139.     FOR b = 1 TO NumActiveCell STEP 1
  140.         CIRCLE (Cells(b).x, Cells(b).y), Cells(b).Radius, Cells(b).Colors
  141.         PAINT STEP(0, 0), Cells(b).Colors, Cells(b).Colors
  142.         IF FNameOn THEN _PRINTSTRING (Cells(b).x, Cells(b).y), LTRIM$(STR$(b))
  143.     NEXT b
  144.     ShowCell = True

Little Help
run the code
click on a cell to duplicate it with mitosis (it divides volume of cell parent)
if you want to recognize the cell press N or n to switch to vision of number name of each cell.
Good Luck with your colture of bacterias
Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
If you click a cell overlapping another, should both cells divide?

I tried to split just one but sometimes...
Code: QB64: [Select]
  1. _TITLE "Click cell for two smaller"
  2. CONST xmax = 800, ymax = 600
  3. TYPE cellType
  4.     x AS SINGLE
  5.     y AS SINGLE
  6.     r AS SINGLE
  7.     c AS _UNSIGNED LONG
  8. DIM cellIndex AS INTEGER
  9. DIM cells(1000) AS cellType
  10. SCREEN _NEWIMAGE(xmax, ymax, 32)
  11. 'get some cells started
  12. FOR i = 1 TO 10
  13.     cells(i).x = RND * (xmax - 80) + 40
  14.     cells(i).y = RND * (ymax - 80) + 40
  15.     cells(i).r = 80
  16.     cells(i).c = _RGB32(100 + RND * 155, 100 + RND * 155, 100 + RND * 155)
  17. cellIndex = 10
  18. WHILE _KEYDOWN(27) = 0
  19.     CLS
  20.     FOR i = 1 TO cellIndex
  21.         CIRCLE (cells(i).x, cells(i).y), cells(i).r, cells(i).c
  22.     NEXT
  23.     mb = _MOUSEBUTTON(1): mx = _MOUSEX: my = _MOUSEY
  24.     IF mb THEN
  25.         'clear mb or get multiple click results
  26.         WHILE _MOUSEINPUT AND mb: mb = _MOUSEBUTTON(1): WEND
  27.         FOR i = cellIndex TO 1 STEP -1
  28.             IF (((mx - cells(i).x) ^ 2 + (my - cells(i).y) ^ 2) ^ .5 <= cells(i).r) THEN
  29.                 'divide cell if big enough
  30.                 IF cells(i).r > 5 THEN
  31.                     cells(i).x = cells(i).x - cells(i).r / 2: cells(i).r = cells(i).r / 2
  32.                     'new cell
  33.                     cellIndex = cellIndex + 1
  34.                     IF cellIndex > UBOUND(cells) THEN REDIM _PRESERVE cells(UBOUND(cells) + 1000) AS cellType
  35.                     cells(cellIndex).x = cells(i).x + 2 * cells(i).r: cells(cellIndex).y = cells(i).y
  36.                     cells(cellIndex).r = cells(i).r: cells(cellIndex).c = cells(i).c
  37.                     EXIT FOR
  38.                 END IF
  39.             END IF
  40.         NEXT
  41.     END IF
  42.     'jiggle cells but keep them on the slide
  43.     FOR i = 1 TO cellIndex
  44.         cells(i).x = cells(i).x + RND * 7 - 3.5
  45.         IF cells(i).x < 10 THEN cells(i).x = 10
  46.         IF cells(i).x > xmax - 10 THEN cells(i).x = xmax - 10
  47.         cells(i).y = cells(i).y + RND * 7 - 3.5
  48.         IF cells(i).y < 10 THEN cells(i).y = 10
  49.         IF cells(i).y > ymax - 10 THEN cells(i).y = ymax - 10
  50.     NEXT
  51.     _DISPLAY
  52.     _LIMIT 10
  53.  
« Last Edit: May 14, 2019, 07:19:20 am by bplus »

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Hi Bplus

1.
Quote
If you click a cell overlapping another, should both cells divide?

about your question I must admit that in the original video it will duplicate only a cell.
What is the criteria to choose the cell that goes to duplication and the cell that is not, it is not clear for me.

In my demo I use a numeric ascendent criteria, so if there are the cells named 3 and 13 overlapping when the user click on the overlapping area he will get the duplication of cell named 3. But, as you already know, it is possible to get double duplications, programming this kind of feature.
From a point of view logic and structural I don't know what is correct criteria, also because IMHO the contact between/among cells result in an inibition of duplication for our human type of cell.
Moreover there is no 3D space in this demo so Zorder is not useful to solve the issue.

2.
Fine your demo and fine your shrinking of features in one third of lines of code.

3.
A point to thinking:
in the original demo if the two cells are not totally overlapped  they are fullfilled by inner color. To get this in BASIC I must workaround  with the localization of the point (pixel) where to PAINT. But also so I can see only the exposed part of cell, while in the original video you can see the whole cell, in other words you can see also the covered part of cell.
I'm thinking that to get this in BASIC I must do more work like 1. make the circle (border of cell) 2. fill the cell with its color using an ALPHA channel not so opaque 3. GET or COPY the image on the canvas showed to user for all cells--> but how many lines of code must I  add?  :-(
Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
How many lines to allow Circle fills and have transparent cells?

Here only lines to do the Circle Fill were added and 2 lines to color and draw cells were changed:
Code: QB64: [Select]
  1. _TITLE "Click cell for two smaller" 'B+ 2019-05-14 with cell fill
  2. CONST xmax = 800, ymax = 600
  3. TYPE cellType
  4.     x AS SINGLE
  5.     y AS SINGLE
  6.     r AS SINGLE
  7.     c AS _UNSIGNED LONG
  8. DIM cellIndex AS INTEGER
  9. DIM cells(1000) AS cellType
  10. SCREEN _NEWIMAGE(xmax, ymax, 32)
  11. 'get some cells started
  12. FOR i = 1 TO 10
  13.     cells(i).x = RND * (xmax - 80) + 40
  14.     cells(i).y = RND * (ymax - 80) + 40
  15.     cells(i).r = 80
  16.     cells(i).c = _RGB32(100 + RND * 155, 100 + RND * 155, 100 + RND * 155, 80) '<< change for circle fill
  17. cellIndex = 10
  18. WHILE _KEYDOWN(27) = 0
  19.     CLS
  20.     FOR i = 1 TO cellIndex
  21.         fcirc cells(i).x, cells(i).y, cells(i).r, cells(i).c '<< chamge for circle fill
  22.     NEXT
  23.     mb = _MOUSEBUTTON(1): mx = _MOUSEX: my = _MOUSEY
  24.     IF mb THEN
  25.         'clear mb or get multiple click results
  26.         WHILE _MOUSEINPUT AND mb: mb = _MOUSEBUTTON(1): WEND
  27.         FOR i = cellIndex TO 1 STEP -1
  28.             IF (((mx - cells(i).x) ^ 2 + (my - cells(i).y) ^ 2) ^ .5 <= cells(i).r) THEN
  29.                 'divide cell if big enough
  30.                 IF cells(i).r > 5 THEN
  31.                     cells(i).x = cells(i).x - cells(i).r / 2: cells(i).r = cells(i).r / 2
  32.                     'new cell
  33.                     cellIndex = cellIndex + 1
  34.                     IF cellIndex > UBOUND(cells) THEN REDIM _PRESERVE cells(UBOUND(cells) + 1000) AS cellType
  35.                     cells(cellIndex).x = cells(i).x + 2 * cells(i).r: cells(cellIndex).y = cells(i).y
  36.                     cells(cellIndex).r = cells(i).r: cells(cellIndex).c = cells(i).c
  37.                     EXIT FOR
  38.                 END IF
  39.             END IF
  40.         NEXT
  41.     END IF
  42.     'jiggle cells but keep them on the slide
  43.     FOR i = 1 TO cellIndex
  44.         cells(i).x = cells(i).x + RND * 7 - 3.5
  45.         IF cells(i).x < 10 THEN cells(i).x = 10
  46.         IF cells(i).x > xmax - 10 THEN cells(i).x = xmax - 10
  47.         cells(i).y = cells(i).y + RND * 7 - 3.5
  48.         IF cells(i).y < 10 THEN cells(i).y = 10
  49.         IF cells(i).y > ymax - 10 THEN cells(i).y = ymax - 10
  50.     NEXT
  51.     _DISPLAY
  52.     _LIMIT 10
  53.  
  54. 'from Steve Gold standard, >>> add for Circle Fills
  55. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  56.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  57.     DIM X AS INTEGER, Y AS INTEGER
  58.  
  59.     Radius = ABS(R)
  60.     RadiusError = -Radius
  61.     X = Radius
  62.     Y = 0
  63.  
  64.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  65.  
  66.     ' Draw the middle span here so we don't draw it twice in the main loop,
  67.     ' which would be a problem with blending turned on.
  68.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  69.  
  70.     WHILE X > Y
  71.         RadiusError = RadiusError + Y * 2 + 1
  72.         IF RadiusError >= 0 THEN
  73.             IF X <> Y + 1 THEN
  74.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  75.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  76.             END IF
  77.             X = X - 1
  78.             RadiusError = RadiusError - X * 2
  79.         END IF
  80.         Y = Y + 1
  81.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  82.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  83.     WEND
  84.  
  85.  

Notice I use the newer way with _RGB32() that allows Alpha without need of saying _RGBA32().

Also notice I am getting 16 cells for each original cell but some of TempodiBasic's cells refuse to divide (exactly half of them) after first division.

Also notice, if I hold the mouse button down and drag it all around the screen, I get all the cells divided to their smallest size very quickly which I can't do with TempodiBasic code.
     Is it a feature or a bug?
This is odd because I was expecting nothing to happen until _MOUSEBUTTON(1) was released???
So I guess I still misunderstand how the mouse works. :P
« Last Edit: May 14, 2019, 07:50:29 am by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
OK I compared TempodiBasic's Mouser with my own and trained the rodent to do as I had expected:
Code: QB64: [Select]
  1. _TITLE "Click cell for two smaller" 'B+ 2019-05-14 with cell fill and MousePressed Function
  2. CONST xmax = 800, ymax = 600
  3. TYPE cellType
  4.     x AS SINGLE
  5.     y AS SINGLE
  6.     r AS SINGLE
  7.     c AS _UNSIGNED LONG
  8. DIM SHARED mx, my '<<<<<<<<<<<<<<<<<<<<<<<< changed
  9. DIM cellIndex AS INTEGER
  10. DIM cells(1000) AS cellType
  11. SCREEN _NEWIMAGE(xmax, ymax, 32)
  12. 'get some cells started
  13. FOR i = 1 TO 10
  14.     cells(i).x = RND * (xmax - 80) + 40
  15.     cells(i).y = RND * (ymax - 80) + 40
  16.     cells(i).r = 80
  17.     cells(i).c = _RGB32(100 + RND * 155, 100 + RND * 155, 100 + RND * 155, 80) '<< change for circle fill
  18. cellIndex = 10
  19. WHILE _KEYDOWN(27) = 0
  20.     CLS
  21.     FOR i = 1 TO cellIndex
  22.         fcirc cells(i).x, cells(i).y, cells(i).r, cells(i).c '<< chamge for circle fill
  23.     NEXT
  24.     'WHILE _MOUSEINPUT: WEND
  25.     mb = MousePressed '<<<<<<<<<<<<<<<<<<<<<<<<<<<< TempodiBasic's method
  26.     IF mb THEN
  27.         'mx = _MOUSEX: my = _MOUSEY
  28.         'clear mb or get multiple click results
  29.         'WHILE (_MOUSEINPUT AND mb = -1): mb = _MOUSEBUTTON(1): WEND
  30.         FOR i = cellIndex TO 1 STEP -1
  31.             IF (((mx - cells(i).x) ^ 2 + (my - cells(i).y) ^ 2) ^ .5 <= cells(i).r) THEN
  32.                 'divide cell if big enough
  33.                 IF cells(i).r > 5 THEN
  34.                     cells(i).x = cells(i).x - cells(i).r / 2: cells(i).r = cells(i).r / 2
  35.                     'new cell
  36.                     cellIndex = cellIndex + 1
  37.                     IF cellIndex > UBOUND(cells) THEN REDIM _PRESERVE cells(UBOUND(cells) + 1000) AS cellType
  38.                     cells(cellIndex).x = cells(i).x + 2 * cells(i).r: cells(cellIndex).y = cells(i).y
  39.                     cells(cellIndex).r = cells(i).r: cells(cellIndex).c = cells(i).c
  40.                     EXIT FOR
  41.                 END IF
  42.             END IF
  43.         NEXT
  44.     END IF
  45.     'jiggle cells but keep them on the slide
  46.     FOR i = 1 TO cellIndex
  47.         cells(i).x = cells(i).x + RND * 7 - 3.5
  48.         IF cells(i).x < 10 THEN cells(i).x = 10
  49.         IF cells(i).x > xmax - 10 THEN cells(i).x = xmax - 10
  50.         cells(i).y = cells(i).y + RND * 7 - 3.5
  51.         IF cells(i).y < 10 THEN cells(i).y = 10
  52.         IF cells(i).y > ymax - 10 THEN cells(i).y = ymax - 10
  53.     NEXT
  54.     _DISPLAY
  55.     _LIMIT 10
  56.  
  57. 'from Steve Gold standard, add for Circle Fills
  58. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  59.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  60.     DIM X AS INTEGER, Y AS INTEGER
  61.  
  62.     Radius = ABS(R)
  63.     RadiusError = -Radius
  64.     X = Radius
  65.     Y = 0
  66.  
  67.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  68.  
  69.     ' Draw the middle span here so we don't draw it twice in the main loop,
  70.     ' which would be a problem with blending turned on.
  71.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  72.  
  73.     WHILE X > Y
  74.         RadiusError = RadiusError + Y * 2 + 1
  75.         IF RadiusError >= 0 THEN
  76.             IF X <> Y + 1 THEN
  77.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  78.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  79.             END IF
  80.             X = X - 1
  81.             RadiusError = RadiusError - X * 2
  82.         END IF
  83.         Y = Y + 1
  84.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  85.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  86.     WEND
  87.  
  88. 'I modified TempodiBasic MousePressed to wait until the _MOUSEBUTTON(1) is released before acting
  89. 'Note: DIM SHARED mx, my
  90. FUNCTION MousePressed
  91.         IF _MOUSEBUTTON(1) THEN
  92.             MousePressed = -1: mx = _MOUSEX: my = _MOUSEY: mb = -1
  93.             WHILE mb
  94.                 WHILE _MOUSEINPUT AND mb: mb = _MOUSEBUTTON(1): WEND
  95.             WEND
  96.         END IF
  97.     WEND
  98.  
  99.  

Now if you click overlapping cells only one or the other will divide until the generation can not divide anymore then the other cell divides. (And now, the whole thing freezes until you do release the mouse button!) Note: this is setup so that the last created cells are checked first when there is a click ie, so checks the new smaller cells first, then the cells made smaller by previous clicks then finally the original cells still whole.
« Last Edit: May 14, 2019, 08:38:25 am by bplus »

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Hi Bplus
about indivisible cells here my findings:


well now we must understand why it happens in my code?
:-(
indivisible cells bug.jpg
* indivisible cells bug.jpg (Filesize: 176.1 KB, Dimensions: 1254x534, Views: 166)
Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Quote
well now we must understand why it happens in my code?

Aha! This was wrong!
Code: QB64: [Select]
  1. FUNCTION MinMax (Min AS INTEGER, Max AS INTEGER)
  2.     MinMax = False
  3.     IF Min < Max THEN SWAP Min, Max
  4.     MinMax = INT(RND * (Max - Min + 1)) + Min
  5.  

Should be IF Min > Max THEN SWAP Min, Max

I can't believe that caused the problem with one cell dividing but the other wouldn't divide, but it did!

BTW, your cells keep dividing on and on creating mass out of nothing. They should not be allowed to divide unless they are big enough.
Code: QB64: [Select]
  1. FUNCTION DuplicateCell (Index AS INTEGER)
  2.     DuplicateCell = False
  3.     IF INT(Cells(Index).Radius / 2) > MinRadius THEN
  4.         NumActiveCell = NumActiveCell + 1
  5.         Cells(NumActiveCell).y = Cells(Index).y
  6.         Cells(NumActiveCell).Colors = Cells(Index).Colors
  7.         Cells(NumActiveCell).Radius = INT(Cells(Index).Radius / 2)
  8.         Cells(Index).Radius = Cells(NumActiveCell).Radius
  9.         Cells(NumActiveCell).x = Cells(Index).x + MinMax(-Cells(Index).Radius, Cells(Index).Radius)
  10.         Cells(Index).x = Cells(Index).x + MinMax(-Cells(Index).Radius, Cells(Index).Radius)
  11.     END IF
  12.     DuplicateCell = True
  13.  

This doesn't hurt much but still incorrect:
Code: [Select]
' This is checking the whole square region around cell x, y you can click outside cell in square corner and cell will divide
        'IF IsInTheRange(_MOUSEX, Cells(b).x - Cells(b).Radius, Cells(b).x + Cells(b).Radius) THEN
        '    IF IsInTheRange(_MOUSEY, Cells(b).y - Cells(b).Radius, Cells(b).y + Cells(b).Radius) THEN
        '        CellClicked = b
        '        EXIT FUNCTION
        '    END IF
        'END IF
'this checks the distance between mouse x, y and cell x, y against the radius of the cell
        IF ((_MOUSEX - Cells(b).x) ^ 2 + (_MOUSEY - Cells(b).y) ^ 2) ^ .5 <= Cells(b).Radius THEN CellClicked = b: EXIT FUNCTION

Wonder why no blue? because NewColor is not returning _UNSIGNED LONG
Code: QB64: [Select]
  1. FUNCTION NewColor~&
  2.     'NewColor~& = False
  3.     c = _RGB32(MinMax(100, 255), MinMax(100, 255), MinMax(100, 255), 20)
  4.     IF c < 0 THEN
  5.         PRINT "Error in NewColor "; c: EXIT FUNCTION
  6.     ELSE
  7.         NewColor~& = c
  8.     END IF
  9.  

Lets see what's going on behind cells, no PAINT but Circle Fill
Code: QB64: [Select]
  1. FUNCTION ShowCell
  2.     'ShowCell = False
  3.     DIM b AS INTEGER
  4.     FOR b = 1 TO NumActiveCell STEP 1
  5.         fcirc Cells(b).x, Cells(b).y, Cells(b).Radius, Cells(b).Colors
  6.         'PAINT STEP(0, 0), Cells(b).Colors, Cells(b).Colors
  7.         IF FNameOn THEN _PRINTSTRING (Cells(b).x, Cells(b).y), LTRIM$(STR$(b))
  8.     NEXT b
  9.     ShowCell = True
  10.  
  11.  
  12. 'from Steve Gold standard, >>> add for Circle Fills
  13. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  14.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  15.     DIM X AS INTEGER, Y AS INTEGER
  16.  
  17.     Radius = ABS(R)
  18.     RadiusError = -Radius
  19.     X = Radius
  20.     Y = 0
  21.  
  22.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  23.  
  24.     ' Draw the middle span here so we don't draw it twice in the main loop,
  25.     ' which would be a problem with blending turned on.
  26.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  27.  
  28.     WHILE X > Y
  29.         RadiusError = RadiusError + Y * 2 + 1
  30.         IF RadiusError >= 0 THEN
  31.             IF X <> Y + 1 THEN
  32.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  33.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  34.             END IF
  35.             X = X - 1
  36.             RadiusError = RadiusError - X * 2
  37.         END IF
  38.         Y = Y + 1
  39.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  40.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  41.     WEND
  42.  

Bigger screen and startRadius:
Code: QB64: [Select]
  1. CONST Hscreen = 700, Wscreen = 800, StartRadius = 60, MaxCells = 1000  
  2.  

No Flickering:
Code: QB64: [Select]
  1. ...
  2.     KeyS = _KEYHIT
  3.     IF KeyS = 78 OR KeyS = 110 THEN FNameOn = NOT FNameOn
  4.     _DISPLAY '<<<<<<<<<<<< prevent flicker
  5.     _LIMIT 10
  6. LOOP UNTIL KeyS = 32
  7.  

What ever I missed:
Code: QB64: [Select]
  1. ' a porting to QB64 of Mitosis simulation as showed in this video
  2. '[youtube]https://www.youtube.com/watch?v=jxGS3fKPKJA[/youtube]
  3. TYPE Cell
  4.     x AS INTEGER
  5.     y AS INTEGER
  6.     Radius AS INTEGER
  7.     Colors AS _UNSIGNED LONG
  8.  
  9. CONST Hscreen = 700, Wscreen = 800, StartRadius = 60, MaxCells = 1000
  10. CONST True = -1, False = NOT True, MinRadius = 3
  11. 'CONST Blu = _RGB32(0, 0, 255): CONST Black = _RGB32(0, 0, 0)
  12. 'CONST Red = _RGB32(255, 0, 0): CONST Green = _RGB32(0, 255, 0)
  13. 'CONST White = _RGB(255, 255, 255)
  14. DIM SHARED A AS LONG, Cells(1 TO MaxCells) AS Cell, NumActiveCell AS INTEGER
  15. DIM SHARED FNameOn AS INTEGER, KeyS AS INTEGER
  16.  
  17. IF NOT Setup THEN PRINT "Error in Setup"
  18.     IF NOT Draws THEN PRINT "Error in Draws"
  19.     IF NOT MoveCell THEN PRINT "Error in movecell"
  20.     IF MousePressed THEN
  21.         F = CellClicked
  22.         'clear buffer of mouse input
  23.         WHILE _MOUSEBUTTON(1)
  24.             IF _MOUSEINPUT THEN REM
  25.         WEND
  26.  
  27.         IF F <> False THEN
  28.             PRINT "LeftClick on cell "; F
  29.             IF NumActiveCell < MaxCells AND (NOT DuplicateCell(F)) THEN PRINT "Error in Duplicatecell"
  30.         ELSE
  31.             PRINT "LeftClick out of cells"
  32.         END IF
  33.     END IF
  34.     KeyS = _KEYHIT
  35.     IF KeyS = 78 OR KeyS = 110 THEN FNameOn = NOT FNameOn
  36.     _DISPLAY '<<<<<<<<<<<< prevent flicker
  37.     _LIMIT 10
  38. LOOP UNTIL KeyS = 32
  39.  
  40.  
  41. FUNCTION Setup
  42.     'Setup = False
  43.     DIM b AS INTEGER
  44.     A = _NEWIMAGE(Wscreen, Hscreen, 32)
  45.     IF A < -1 THEN SCREEN A ELSE PRINT "Image handle for Screen not valid"
  46.     _TITLE "Mitosis Simulation"
  47.     NumActiveCell = 10
  48.     FNameOn = False
  49.     FOR b = 1 TO NumActiveCell
  50.         IF b < 11 THEN
  51.             Cells(b).x = MinMax(5, Wscreen - 5)
  52.             Cells(b).y = MinMax(5, Hscreen - 5)
  53.             Cells(b).Radius = StartRadius
  54.             Cells(b).Colors = NewColor
  55.             'ELSE
  56.             '    Cells(b).x = 0
  57.             '    Cells(b).y = 0
  58.             '    Cells(b).Radius = 0
  59.             '    Cells(b).Colors = 0
  60.         END IF
  61.     NEXT b
  62.     Setup = True
  63.  
  64. FUNCTION DuplicateCell (Index AS INTEGER)
  65.     'DuplicateCell = False
  66.     IF INT(Cells(Index).Radius / 2) > MinRadius THEN
  67.         NumActiveCell = NumActiveCell + 1
  68.         Cells(NumActiveCell).y = Cells(Index).y
  69.         Cells(NumActiveCell).Colors = Cells(Index).Colors
  70.         Cells(NumActiveCell).Radius = INT(Cells(Index).Radius / 2)
  71.         Cells(Index).Radius = Cells(NumActiveCell).Radius
  72.         Cells(NumActiveCell).x = Cells(Index).x + MinMax(-Cells(Index).Radius, Cells(Index).Radius)
  73.         Cells(Index).x = Cells(Index).x + MinMax(-Cells(Index).Radius, Cells(Index).Radius)
  74.     END IF
  75.     DuplicateCell = True
  76.  
  77. FUNCTION MousePressed
  78.     'MousePressed = False
  79.         IF _MOUSEBUTTON(1) = True THEN MousePressed = True
  80.     WEND
  81.  
  82. FUNCTION IsInTheRange (What AS INTEGER, Min AS INTEGER, Max AS INTEGER)
  83.     'IsInTheRange = False
  84.     IF What > Min AND What < Max THEN IsInTheRange = True
  85.  
  86. FUNCTION CellClicked
  87.     'CellClicked = False
  88.     DIM b AS INTEGER
  89.     FOR b = 1 TO NumActiveCell STEP 1
  90.         'IF IsInTheRange(_MOUSEX, Cells(b).x - Cells(b).Radius, Cells(b).x + Cells(b).Radius) THEN
  91.         '    IF IsInTheRange(_MOUSEY, Cells(b).y - Cells(b).Radius, Cells(b).y + Cells(b).Radius) THEN
  92.         '        CellClicked = b
  93.         '        EXIT FUNCTION
  94.         '    END IF
  95.         'END IF
  96.         IF ((_MOUSEX - Cells(b).x) ^ 2 + (_MOUSEY - Cells(b).y) ^ 2) ^ .5 <= Cells(b).Radius THEN CellClicked = b: EXIT FUNCTION
  97.     NEXT b
  98.  
  99. FUNCTION InTheRange (What AS INTEGER, Min AS INTEGER, Max AS INTEGER)
  100.     'InTheRange = False
  101.     IF What < Min THEN What = Min
  102.     IF What > Max THEN What = Max
  103.     IF What >= Min AND What <= Max THEN InTheRange = True
  104.  
  105. FUNCTION MinMax (Min AS INTEGER, Max AS INTEGER)
  106.     'MinMax = False
  107.     IF Min > Max THEN SWAP Min, Max
  108.     MinMax = INT(RND * (Max - Min + 1)) + Min
  109.  
  110. FUNCTION Draws
  111.     'Draws = False
  112.     DIM b AS INTEGER
  113.     CLS , Black
  114.     FOR b = 1 TO NumActiveCell
  115.         IF NOT ShowCell THEN PRINT "Error in Showcell with value "; Cells(b).x; " "; Cells(b).y
  116.     NEXT b
  117.     Draws = True
  118.  
  119. FUNCTION MoveCell
  120.     'MoveCell = False
  121.     DIM b AS INTEGER
  122.     FOR b = 1 TO NumActiveCell STEP 1
  123.         Cells(b).x = Cells(b).x + MinMax(-3, 3)
  124.         Cells(b).y = Cells(b).y + MinMax(-3, 3)
  125.         IF NOT InTheRange(Cells(b).x, 5, Wscreen - 5) THEN PRINT "Error IntheRange X"
  126.         IF NOT InTheRange(Cells(b).y, 5, Hscreen - 5) THEN PRINT "Error IntheRange Y"
  127.     NEXT b
  128.     MoveCell = True
  129.  
  130. FUNCTION NewColor~&
  131.     'NewColor~& = False
  132.     c = _RGB32(MinMax(100, 255), MinMax(100, 255), MinMax(100, 255), 20)
  133.     IF c < 0 THEN
  134.         PRINT "Error in NewColor "; c: EXIT FUNCTION
  135.     ELSE
  136.         NewColor~& = c
  137.     END IF
  138.  
  139. FUNCTION ShowCell
  140.     'ShowCell = False
  141.     DIM b AS INTEGER
  142.     FOR b = 1 TO NumActiveCell STEP 1
  143.         fcirc Cells(b).x, Cells(b).y, Cells(b).Radius, Cells(b).Colors
  144.         'PAINT STEP(0, 0), Cells(b).Colors, Cells(b).Colors
  145.         IF FNameOn THEN _PRINTSTRING (Cells(b).x, Cells(b).y), LTRIM$(STR$(b))
  146.     NEXT b
  147.     ShowCell = True
  148.  
  149.  
  150. 'from Steve Gold standard, >>> add for Circle Fills
  151. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  152.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  153.     DIM X AS INTEGER, Y AS INTEGER
  154.  
  155.     Radius = ABS(R)
  156.     RadiusError = -Radius
  157.     X = Radius
  158.     Y = 0
  159.  
  160.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  161.  
  162.     ' Draw the middle span here so we don't draw it twice in the main loop,
  163.     ' which would be a problem with blending turned on.
  164.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  165.  
  166.     WHILE X > Y
  167.         RadiusError = RadiusError + Y * 2 + 1
  168.         IF RadiusError >= 0 THEN
  169.             IF X <> Y + 1 THEN
  170.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  171.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  172.             END IF
  173.             X = X - 1
  174.             RadiusError = RadiusError - X * 2
  175.         END IF
  176.         Y = Y + 1
  177.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  178.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  179.     WEND
  180.  
  181.  
  182.  
« Last Edit: May 14, 2019, 11:07:53 pm by bplus »

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Hi Bplus
WOW I like all these feedbacks!
Thanks



Errors:
Why do you think that it is a very showed mistake only after the mistake is pointed out?
:-((

1. NewColor~&
all that time spent on the _RGB  &co and then I cut off value with a function that return a single value and not a _Unsigned Long....
LOL

2. Min>Max
A mistype (< at place of >) that covers itself in a very original bug

3. area of the circle is not the whole area of the square with side the diameter of the circle
I know this bit mistake...but I hate too many math so at start time I use the simple area of the square. ( odi et amo te oh mia Matematica just to remember Catullo)

4. no flickering
Yes I must remember that it is possible that the screen shows flickering and not that my eyes are too tired

my habit in coding:

1. bad CONST color not used
Ok remmed

2. initialization to False at start of a FUNCTION
do you find it bad or verbose?

3. initialization of void variables
do you find it bad or verbose?

4. STEP 1 in the NEXT
do you find it bad or verbose?

5. NEXT nameVariable in a single FOR NEXT
do you find it bad or verbose?


Feature and goals behind the actual demo:
1.
Quote
your cells keep dividing on and on creating mass out of nothing. They should not be allowed to divide unless they are big enough
in the original demo the division of cells is infinite... I find it so bad that I put a lower cutoff to divide cell volume. This cutoff is the point of ready to duplicate for the cell, putting out the cicle of gain energy and volume to duplicate again that I would develope after this actual point.





Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Hi TempodiBasic,

In your habit of coding, the points you bring up are verbose, not bad as far as communication goes because adds to clarity but NOT really necessary.

What I do find bad is making a natural SUB an unnatural FUNCTION.

Look at your main loop:
Code: QB64: [Select]
  1. IF NOT Setup THEN PRINT "Error in Setup"
  2.     IF NOT Draws THEN PRINT "Error in Draws"
  3.     IF NOT MoveCell THEN PRINT "Error in movecell"
  4.     IF MousePressed THEN
  5.         F = CellClicked
  6.         'clear buffer of mouse input
  7.         WHILE _MOUSEBUTTON(1)
  8.             IF _MOUSEINPUT THEN REM
  9.         WEND
  10.  
  11.         IF F <> False THEN
  12.             PRINT "LeftClick on cell "; F
  13.             IF NumActiveCell < MaxCells AND (NOT DuplicateCell(F)) THEN PRINT "Error in Duplicatecell"
  14.         ELSE
  15.             PRINT "LeftClick out of cells"
  16.         END IF
  17.     END IF
  18.     KeyS = _KEYHIT
  19.     IF KeyS = 78 OR KeyS = 110 THEN FNameOn = NOT FNameOn
  20.     _LIMIT 10
  21. LOOP UNTIL KeyS = 32
  22.  

Wouldn't it be clearer to just do this:
Code: QB64: [Select]
  1. Setup
  2.     Draws
  3.     MoveCell
  4.     IF MousePressed THEN  '<< clear the mouse button in the MousePressed code
  5.         DuplicateCell CellClicked
  6.     END IF
  7.     KeyS = _KEYHIT
  8.     IF KeyS = 78 OR KeyS = 110 THEN FNameOn = NOT FNameOn
  9.     _LIMIT 10
  10. LOOP UNTIL KeyS = 32
  11.  

Here is a natural SUB turned into an unnatural FUNCTION:
Code: QB64: [Select]
  1. FUNCTION ShowCell
  2.     'ShowCell = False '<<<<<<<<<< ShowCell as a function will automatically return 0.0000 unless otherwise reset
  3.     DIM b AS INTEGER
  4.     FOR b = 1 TO NumActiveCell STEP 1
  5.         fcirc Cells(b).x, Cells(b).y, Cells(b).Radius, Cells(b).Colors
  6.         'PAINT STEP(0, 0), Cells(b).Colors, Cells(b).Colors
  7.         IF FNameOn THEN _PRINTSTRING (Cells(b).x, Cells(b).y), LTRIM$(STR$(b))
  8.     NEXT b
  9.     ShowCell = True  
  10.  

Setting ShowCell = False at start and then to True at end of "function" adds no useful information to code and is just clutter. This example code is never going to catch a useful error to report.

BTW ShowCell is default Type Single unless you change name to ShowCell%.
« Last Edit: May 15, 2019, 08:43:26 am by bplus »

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Hi Bplus

Thanks
I can only be totally agreed with your suggestions

the unnatural FUNCTION
Initialization Verbose not adding value

I must admit that I have bad translated in QB64 style the Java demo...
BASIC is more free and less restrictive!
Free Spirit in digit world.
Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Hi TempodiBasic,

Thanks back to you! The mystery of why one divided cell was dividing and the other was not was a real stumper!

It was fun tracking down the culprit and what a surprise when found.