Author Topic: Hypnotic polygon orbits  (Read 5751 times)

0 Members and 1 Guest are viewing this topic.

FellippeHeitor

  • Guest
Hypnotic polygon orbits
« on: February 25, 2020, 09:19:22 am »
Inspired by this post: https://www.reddit.com/r/gifs/comments/f91c99/every_addtional_shape_adds_one_more_corner_and/

Captura de Tela 2020-02-25 às 11.37.14.png

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(300, 300, 32)
  2. _TITLE "Polygon orbits"
  3. TYPE shapeType
  4.     n AS INTEGER
  5.     c AS _UNSIGNED LONG
  6.     x AS SINGLE
  7.     y AS SINGLE
  8.  
  9. DIM SHARED shape(1 TO 13, 1 TO 15) AS shapeType
  10.  
  11. 'draw shapes and fill shape() array with vertices
  12. FOR s = 3 TO 12
  13.     drawShape _WIDTH / 2, _HEIGHT / 2, s * 10, s, s - 2
  14.  
  15. 'save shapes image
  16. PCOPY 0, 1
  17.  
  18. 'have circles follow shapes' paths
  19.     FOR s = 1 TO 10
  20.         shape(s, 1).n = shape(s, 1).n + 1
  21.         IF shape(s, 1).n > s + 2 THEN
  22.             shape(s, 1).n = 1
  23.         END IF
  24.     NEXT
  25.     FOR i = 1 TO 100 STEP 5
  26.         PCOPY 1, 0 'restore background
  27.         DIM ret AS shapeType
  28.         FOR s = 1 TO 10
  29.             IF shape(s, 1).n < s + 2 THEN
  30.                 followPath shape(s, shape(s, 1).n).x, shape(s, shape(s, 1).n).y, shape(s, shape(s, 1).n + 1).x, shape(s, shape(s, 1).n + 1).y, i, ret
  31.             ELSE
  32.                 followPath shape(s, shape(s, 1).n).x, shape(s, shape(s, 1).n).y, shape(s, 1).x, shape(s, 1).y, i, ret
  33.             END IF
  34.             CircleFill ret.x, ret.y, 5, shape(s, 1).c
  35.         NEXT
  36.         _DISPLAY
  37.         _LIMIT 60
  38.     NEXT
  39.  
  40. SUB drawShape (x AS SINGLE, y AS SINGLE, size AS INTEGER, sides AS INTEGER, arrayIndex AS INTEGER)
  41.     'Thanks to Ashish for contributing to this sub
  42.     DIM i AS SINGLE, vertex AS INTEGER
  43.     DIM x0 AS SINGLE, y0 AS SINGLE, theta AS SINGLE
  44.     DIM thisColor AS _UNSIGNED LONG
  45.  
  46.     IF sides <> 4 THEN theta = -_PI(0.5) ELSE theta = _PI(0.25)
  47.  
  48.     thisColor = hsb(map(sides, 3, 12, 0, 360), 255, 127, 255)
  49.     shape(arrayIndex, 1).c = thisColor
  50.     FOR i = theta TO _PI(2) + theta STEP _PI(2 / sides)
  51.         x0 = x + size * COS(i)
  52.         y0 = y + size * SIN(i)
  53.         LINE (x0, y0)-(x + size * COS(i + _PI(2 / sides)), y + size * SIN(i + _PI(2 / sides))), thisColor
  54.  
  55.         vertex = vertex + 1
  56.         shape(arrayIndex, vertex).x = x0
  57.         shape(arrayIndex, vertex).y = y0
  58.     NEXT
  59.  
  60. SUB followPath (X AS INTEGER, Y AS INTEGER, X2 AS INTEGER, Y2 AS INTEGER, atStep AS INTEGER, position AS shapeType)
  61.     'This sub adapted from http://www.antonis.de/faq/progs/bline.bas
  62.     '---------
  63.     'This implementation returns position.x and position.y as coordinates
  64.     'to a point across the path between X,Y and X2,Y2
  65.     'Uses atStep to determine how far along the path the returned point stands
  66.     DIM I AS INTEGER
  67.     DIM Steep AS INTEGER
  68.     DIM E AS INTEGER
  69.     DIM SX AS INTEGER
  70.     DIM SY AS INTEGER
  71.     DIM DX AS INTEGER
  72.     DIM DY AS INTEGER
  73.     I = 0
  74.     Steep% = 0
  75.     E = 0
  76.     IF (X2 - X) > 0 THEN
  77.         SX = 1
  78.     ELSE
  79.         SX = -1
  80.     END IF
  81.     DX = ABS(X2 - X)
  82.     IF (Y2 - Y) > 0 THEN
  83.         SY = 1
  84.     ELSE
  85.         SY = -1
  86.     END IF
  87.     DY = ABS(Y2 - Y)
  88.     IF (DY > DX) THEN
  89.         Steep = 1
  90.         SWAP X, Y
  91.         SWAP DX, DY
  92.         SWAP SX, SY
  93.     END IF
  94.     E = 2 * DY - DX
  95.     FOR I = 0 TO (INT(map(atStep, 0, 100, 0, DX))) - 1
  96.         WHILE E >= 0
  97.             Y = Y + SY
  98.             E = E - 2 * DX
  99.         WEND
  100.         X = X + SX
  101.         E = E + 2 * DY
  102.     NEXT
  103.     IF Steep% = 1 THEN
  104.         position.x = Y
  105.         position.y = X
  106.     ELSE
  107.         position.x = X
  108.         position.y = Y
  109.     END IF
  110.  
  111. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  112.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  113.  
  114. SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  115.     'This sub from https://www.qb64.org/forum/index.php?topic=1069.0
  116.     ' CX = center x coordinate
  117.     ' CY = center y coordinate
  118.     '  R = radius
  119.     '  C = fill color
  120.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  121.     DIM X AS INTEGER, Y AS INTEGER
  122.     Radius = ABS(R)
  123.     RadiusError = -Radius
  124.     X = Radius
  125.     Y = 0
  126.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  127.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  128.     WHILE X > Y
  129.         RadiusError = RadiusError + Y * 2 + 1
  130.         IF RadiusError >= 0 THEN
  131.             IF X <> Y + 1 THEN
  132.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  133.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  134.             END IF
  135.             X = X - 1
  136.             RadiusError = RadiusError - X * 2
  137.         END IF
  138.         Y = Y + 1
  139.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  140.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  141.     WEND
  142.  
  143. FUNCTION hsb~& (__H AS _FLOAT, __S AS _FLOAT, __B AS _FLOAT, A AS _FLOAT)
  144.     DIM H AS _FLOAT, S AS _FLOAT, B AS _FLOAT
  145.  
  146.     H = __H
  147.     S = map(__S, 0, 255, 0, 1)
  148.     B = map(__B, 0, 255, 0, 1)
  149.  
  150.     IF S = 0 THEN
  151.         hsb~& = _RGBA32(B * 255, B * 255, B * 255, A)
  152.         EXIT FUNCTION
  153.     END IF
  154.  
  155.     DIM fmx AS _FLOAT, fmn AS _FLOAT
  156.     DIM fmd AS _FLOAT, iSextant AS INTEGER
  157.     DIM imx AS INTEGER, imd AS INTEGER, imn AS INTEGER
  158.  
  159.     IF B > .5 THEN
  160.         fmx = B - (B * S) + S
  161.         fmn = B + (B * S) - S
  162.     ELSE
  163.         fmx = B + (B * S)
  164.         fmn = B - (B * S)
  165.     END IF
  166.  
  167.     iSextant = INT(H / 60)
  168.  
  169.     IF H >= 300 THEN
  170.         H = H - 360
  171.     END IF
  172.  
  173.     H = H / 60
  174.     H = H - (2 * INT(((iSextant + 1) MOD 6) / 2))
  175.  
  176.     IF iSextant MOD 2 = 0 THEN
  177.         fmd = (H * (fmx - fmn)) + fmn
  178.     ELSE
  179.         fmd = fmn - (H * (fmx - fmn))
  180.     END IF
  181.  
  182.     imx = _ROUND(fmx * 255)
  183.     imd = _ROUND(fmd * 255)
  184.     imn = _ROUND(fmn * 255)
  185.  
  186.     SELECT CASE INT(iSextant)
  187.         CASE 1
  188.             hsb~& = _RGBA32(imd, imx, imn, A)
  189.         CASE 2
  190.             hsb~& = _RGBA32(imn, imx, imd, A)
  191.         CASE 3
  192.             hsb~& = _RGBA32(imn, imd, imx, A)
  193.         CASE 4
  194.             hsb~& = _RGBA32(imd, imn, imx, A)
  195.         CASE 5
  196.             hsb~& = _RGBA32(imx, imn, imd, A)
  197.         CASE ELSE
  198.             hsb~& = _RGBA32(imx, imd, imn, A)
  199.     END SELECT
  200.  
  201.  
« Last Edit: February 25, 2020, 09:37:59 am by FellippeHeitor »

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Hypnotic polygon orbits
« Reply #1 on: February 25, 2020, 09:34:05 am »
  • Best Answer
  • Hi.. here my version
    Code: QB64: [Select]
    1. SCREEN _NEWIMAGE(700, 700, 32)
    2.  
    3. TYPE vec2
    4.     x AS SINGLE
    5.     y AS SINGLE
    6.  
    7. TYPE part
    8.     pos AS vec2
    9.     src AS INTEGER
    10.     dest AS INTEGER
    11.  
    12. DIM SHARED particle_path(11, 13) AS vec2
    13. DIM SHARED particle(10) AS part
    14.  
    15. FOR i = 3 TO 13
    16.     COLOR hsb~&((i - 3) * 17, 255, 128, 255)
    17.     drawShape 350, 350, 60 + 25 * (i - 3), i
    18.     particle(i - 3).pos = particle_path(i - 3, 0)
    19.     particle(i - 3).src = 0
    20.     particle(i - 3).dest = 1
    21. pic& = _COPYIMAGE(0)
    22. speed = 0.04
    23. v = 0
    24. w~& = _RGB(255, 255, 255)
    25.     CLS
    26.     _PUTIMAGE , pic&
    27.     v = v + speed
    28.     FOR i = 0 TO UBOUND(particle)
    29.         CircleFill particle(i).pos.x, particle(i).pos.y, 5, w~&
    30.         particle(i).pos.x = map(v, 0, 1, particle_path(i, particle(i).src).x, particle_path(i, particle(i).dest).x)
    31.         particle(i).pos.y = map(v, 0, 1, particle_path(i, particle(i).src).y, particle_path(i, particle(i).dest).y)
    32.         IF v >= 1 THEN
    33.             particle(i).src = particle(i).dest
    34.             IF particle(i).dest = (i + 3) - 1 THEN
    35.                 particle(i).dest = 0
    36.             ELSE
    37.                 particle(i).dest = particle(i).dest + 1
    38.             END IF
    39.         END IF
    40.     NEXT
    41.     IF v >= 1 THEN v = 0
    42.     _LIMIT 60
    43.     _DISPLAY
    44.  
    45. SUB drawShape (x, y, s, n)
    46.     IF n <> 4 THEN theta = -_PI(0.5) ELSE theta = _PI(0.25)
    47.     c = 0
    48.     FOR i = theta TO _PI(2) + theta STEP _PI(2 / n)
    49.         x0 = x + s * COS(i)
    50.         y0 = y + s * SIN(i)
    51.         particle_path((n - 3), c).x = x0
    52.         particle_path((n - 3), c).y = y0
    53.         LINE (x0, y0)-(x + s * COS(i + _PI(2 / n)), y + s * SIN(i + _PI(2 / n)))
    54.         c = c + 1
    55.     NEXT
    56.  
    57.  
    58. 'method adapted form http://stackoverflow.com/questions/4106363/converting-rgb-to-hsb-colors
    59. FUNCTION hsb~& (__H AS _FLOAT, __S AS _FLOAT, __B AS _FLOAT, A AS _FLOAT)
    60.     DIM H AS _FLOAT, S AS _FLOAT, B AS _FLOAT
    61.  
    62.     H = map(__H, 0, 255, 0, 360)
    63.     S = map(__S, 0, 255, 0, 1)
    64.     B = map(__B, 0, 255, 0, 1)
    65.  
    66.     IF S = 0 THEN
    67.         hsb~& = _RGBA32(B * 255, B * 255, B * 255, A)
    68.         EXIT FUNCTION
    69.     END IF
    70.  
    71.     DIM fmx AS _FLOAT, fmn AS _FLOAT
    72.     DIM fmd AS _FLOAT, iSextant AS INTEGER
    73.     DIM imx AS INTEGER, imd AS INTEGER, imn AS INTEGER
    74.  
    75.     IF B > .5 THEN
    76.         fmx = B - (B * S) + S
    77.         fmn = B + (B * S) - S
    78.     ELSE
    79.         fmx = B + (B * S)
    80.         fmn = B - (B * S)
    81.     END IF
    82.  
    83.     iSextant = INT(H / 60)
    84.  
    85.     IF H >= 300 THEN
    86.         H = H - 360
    87.     END IF
    88.  
    89.     H = H / 60
    90.     H = H - (2 * INT(((iSextant + 1) MOD 6) / 2))
    91.  
    92.     IF iSextant MOD 2 = 0 THEN
    93.         fmd = (H * (fmx - fmn)) + fmn
    94.     ELSE
    95.         fmd = fmn - (H * (fmx - fmn))
    96.     END IF
    97.  
    98.     imx = _ROUND(fmx * 255)
    99.     imd = _ROUND(fmd * 255)
    100.     imn = _ROUND(fmn * 255)
    101.  
    102.     SELECT CASE INT(iSextant)
    103.         CASE 1
    104.             hsb~& = _RGBA32(imd, imx, imn, A)
    105.         CASE 2
    106.             hsb~& = _RGBA32(imn, imx, imd, A)
    107.         CASE 3
    108.             hsb~& = _RGBA32(imn, imd, imx, A)
    109.         CASE 4
    110.             hsb~& = _RGBA32(imd, imn, imx, A)
    111.         CASE 5
    112.             hsb~& = _RGBA32(imx, imn, imd, A)
    113.         CASE ELSE
    114.             hsb~& = _RGBA32(imx, imd, imn, A)
    115.     END SELECT
    116.  
    117.  
    118.  
    119. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
    120.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
    121.  
    122. SUB CircleFill (x AS LONG, y AS LONG, R AS LONG, C AS _UNSIGNED LONG)
    123.     DIM x0 AS SINGLE, y0 AS SINGLE
    124.     DIM e AS SINGLE
    125.  
    126.     x0 = R
    127.     y0 = 0
    128.     e = -R
    129.     DO WHILE y0 < x0
    130.         IF e <= 0 THEN
    131.             y0 = y0 + 1
    132.             LINE (x - x0, y + y0)-(x + x0, y + y0), C, BF
    133.             LINE (x - x0, y - y0)-(x + x0, y - y0), C, BF
    134.             e = e + 2 * y0
    135.         ELSE
    136.             LINE (x - y0, y - x0)-(x + y0, y - x0), C, BF
    137.             LINE (x - y0, y + x0)-(x + y0, y + x0), C, BF
    138.             x0 = x0 - 1
    139.             e = e - 2 * x0
    140.         END IF
    141.     LOOP
    142.     LINE (x - R, y)-(x + R, y), C, BF
    143.  
    144.  
    if (Me.success) {Me.improve()} else {Me.tryAgain()}


    My Projects - https://github.com/AshishKingdom?tab=repositories
    OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

    Offline bplus

    • Global Moderator
    • Forum Resident
    • Posts: 8053
    • b = b + ...
      • View Profile
    Re: Hypnotic polygon orbits
    « Reply #2 on: February 25, 2020, 09:37:18 am »
  • Best Answer
  • Wow! They are also spiral and turn into n-perpeller like, oh that's only in the link to video.

    Fellippe your lineup of regular polys is off, yours too neat ;-) in link notice how all polys lineup at the bottom segment and the triangle overlaps the square at top point... that might help keep colored disks in pattern. They also start lineup straight down.

    Still pretty cool.

    FellippeHeitor

    • Guest
    Re: Hypnotic polygon orbits
    « Reply #3 on: February 25, 2020, 09:39:34 am »
  • Best Answer
  • Just "fixed" the square to be hacky too.

    To fix the rest I'd probably need an adaptive theta in drawShape() for each number of sides.
    « Last Edit: February 25, 2020, 09:41:52 am by FellippeHeitor »

    Offline bplus

    • Global Moderator
    • Forum Resident
    • Posts: 8053
    • b = b + ...
      • View Profile
    Re: Hypnotic polygon orbits
    « Reply #4 on: February 25, 2020, 03:31:54 pm »
  • Best Answer
  • This might help get your alignment started on the right foot.
    Code: QB64: [Select]
    1. _TITLE "Polygon Orbits" 'b+ 2020-02-25
    2. ' Fellippe's post 2020-02-25 https://www.qb64.org/forum/index.php?topic=2234.msg114766#msg114766
    3. ' Inspired by this post: https://www.reddit.com/r/gifs/comments/f91c99/every_addtional_shape_adds_one_more_corner_and/
    4.  
    5. CONST xmax = 700, ymax = 700, side = 100, center = 350, P1 = _PI: P2 = _PI(2): PD2 = _PI(.5)
    6.  
    7. SCREEN _NEWIMAGE(xmax, ymax, 32)
    8. _SCREENMOVE 300, 20
    9. PSET (center, center)
    10. FOR n = 3 TO 12
    11.     a = P2 / n
    12.     ' 1/2 *side = r*sin(1/2*a)
    13.     r = .5 * side / SIN(a / 2)
    14.     x1 = center + r * COS(a / 2 + PD2)
    15.     y1 = center + r * SIN(a / 2 + PD2)
    16.     'PSET (x1, y1)   'OK ?
    17.     x2 = x1 + side * COS(0)
    18.     y2 = y1 + side * SIN(0)
    19.     'PSET (x2, y2) ' OK?
    20.     LINE (x1, y1)-(x2, y2) 'OK!
    21.  

    The bottom segments are all aligned and parallel to bottom of screen.

    Offline bplus

    • Global Moderator
    • Forum Resident
    • Posts: 8053
    • b = b + ...
      • View Profile
    Re: Hypnotic polygon orbits
    « Reply #5 on: February 25, 2020, 04:49:38 pm »
  • Best Answer
  • Use turtle drawing to finish the polys and save the point positions:
    Code: QB64: [Select]
    1. 'OPTION _EXPLICIT
    2. _TITLE "Polygon Orbits" 'b+ 2020-02-25
    3. ' Fellippe's post 2020-02-25 https://www.qb64.org/forum/index.php?topic=2234.msg114766#msg114766
    4. ' Inspired by this post: https://www.reddit.com/r/gifs/comments/f91c99/every_addtional_shape_adds_one_more_corner_and/
    5.  
    6. CONST xmax = 700, ymax = 700, side = 170, center = 350, P1 = _PI: P2 = _PI(2): PD2 = _PI(.5)
    7.  
    8. SCREEN _NEWIMAGE(xmax, ymax, 32)
    9. _SCREENMOVE 300, 20
    10.  
    11. DIM SHARED poly$(3 TO 12) 'point strings we will turn into arrays as needed
    12. PSET (center, center)
    13. FOR n = 3 TO 12
    14.     a = P2 / n
    15.     isoA = (P1 - a) / 2
    16.     isoA2 = isoA * 2
    17.     turn = P1 - isoA2 'for turtle drawing
    18.  
    19.     ' 1/2 *side = r*sin(1/2*a)
    20.     r = .5 * side / SIN(a / 2)
    21.     x1 = center + r * COS(a / 2 + PD2)
    22.     y1 = center + r * SIN(a / 2 + PD2)
    23.     'PSET (x1, y1)   'OK ?
    24.     'x2 = x1 + side * COS(0)
    25.     'y2 = y1 + side * SIN(0)
    26.     'PSET (x2, y2) ' OK?
    27.     'LINE (x1, y1)-(x2, y2) 'OK!
    28.     poly$(n) = STR$(x1) + "," + STR$(y1) 'our first point for polygon
    29.     currA = P1 'turtle draw the rest of the poly and save the points
    30.     FOR ring = 2 TO n + 1
    31.         currA = currA + turn
    32.         x2 = x1 + side * COS(currA)
    33.         y2 = y1 + side * SIN(currA)
    34.         LINE (x1, y1)-(x2, y2)
    35.         x1 = x2: y1 = y2
    36.         poly$(n) = poly$(n) + STR$(x1) + "," + STR$(y1)
    37.     NEXT
    38.  

    Offline bplus

    • Global Moderator
    • Forum Resident
    • Posts: 8053
    • b = b + ...
      • View Profile
    Re: Hypnotic polygon orbits
    « Reply #6 on: February 25, 2020, 05:58:22 pm »
  • Best Answer
  • OK, just need to add the circles
    Code: QB64: [Select]
    1. _TITLE "Polygon Orbits" 'b+ 2020-02-25
    2. ' Fellippe's post 2020-02-25 https://www.qb64.org/forum/index.php?topic=2234.msg114766#msg114766
    3. ' Inspired by this post: https://www.reddit.com/r/gifs/comments/f91c99/every_addtional_shape_adds_one_more_corner_and/
    4.  
    5. CONST xmax = 700, ymax = 700, side = 170, center = 350, P1 = _PI, P2 = P1 * 2, PD2 = P1 * .5
    6. DIM SHARED poly$(3 TO 12) 'point strings we will turn into arrays as needed
    7. DIM SHARED c(3 TO 12) AS _UNSIGNED LONG 'colors
    8. c(3) = Red: c(4) = CrayolaOrange: c(5) = LaserLemon: c(6) = Lime: c(7) = MediumSpringGreen
    9. c(8) = Aqua: c(9) = Periwinkle: c(10) = NavyBlue: c(11) = MediumBlue: c(12) = RedViolet
    10.  
    11. SCREEN _NEWIMAGE(xmax, ymax, 32)
    12. _SCREENMOVE 300, 20
    13. DIM n, a, isoA, isoA2, turn, r, x1, y1, currA, ring, x2, y2
    14.  
    15. 'PSET (center, center)
    16. FOR n = 3 TO 12
    17.     a = P2 / n
    18.     isoA = (P1 - a) / 2
    19.     isoA2 = isoA * 2
    20.     turn = P1 - isoA2 'for turtle drawing
    21.  
    22.     ' 1/2 *side = r*sin(1/2*a)
    23.     r = .5 * side / SIN(a / 2)
    24.     x1 = center + r * COS(a / 2 + PD2)
    25.     y1 = center + r * SIN(a / 2 + PD2)
    26.     'PSET (x1, y1)   'OK ?
    27.     'x2 = x1 + side * COS(0)
    28.     'y2 = y1 + side * SIN(0)
    29.     'PSET (x2, y2) ' OK?
    30.     'LINE (x1, y1)-(x2, y2) 'OK!
    31.     poly$(n) = STR$(x1) + "," + STR$(y1) 'our first point for polygon
    32.     currA = P1 'turtle draw the rest of the poly and save the points
    33.     FOR ring = 2 TO n + 1
    34.         currA = currA + turn
    35.         x2 = x1 + side * COS(currA)
    36.         y2 = y1 + side * SIN(currA)
    37.         LINE (x1, y1)-(x2, y2)
    38.         x1 = x2: y1 = y2
    39.         poly$(n) = poly$(n) + "," + STR$(x1) + "," + STR$(y1)
    40.     NEXT
    41. drawPolys
    42.  
    43. SUB drawPolys
    44.     DIM n, i, x1, y1, x2, y2, w$
    45.     FOR n = 3 TO 12
    46.         REDIM pts$(0)
    47.         Split poly$(n), ",", pts$()
    48.         'FOR i = 0 TO UBOUND(pts$) - 1 STEP 2
    49.         '    PRINT pts$(i), pts$(i + 1)
    50.         'NEXT
    51.         PSET (VAL(pts$(0)), VAL(pts$(1))), c(n)
    52.         FOR i = 2 TO UBOUND(pts$) STEP 2
    53.             x1 = VAL(pts$(i)): y1 = VAL(pts$((i + 1)))
    54.             LINE -(x1, y1), c(n)
    55.         NEXT
    56.     NEXT
    57.  
    58. SUB Split (SplitMeString AS STRING, delim AS STRING, loadMeArray() AS STRING)
    59.     DIM curpos AS LONG, arrpos AS LONG, LD AS LONG, dpos AS LONG 'fix use the Lbound the array already has
    60.     curpos = 1: arrpos = LBOUND(loadMeArray): LD = LEN(delim)
    61.     dpos = INSTR(curpos, SplitMeString, delim)
    62.     DO UNTIL dpos = 0
    63.         loadMeArray(arrpos) = MID$(SplitMeString, curpos, dpos - curpos)
    64.         arrpos = arrpos + 1
    65.         IF arrpos > UBOUND(loadMeArray) THEN REDIM _PRESERVE loadMeArray(LBOUND(loadMeArray) TO UBOUND(loadMeArray) + 1000) AS STRING
    66.         curpos = dpos + LD
    67.         dpos = INSTR(curpos, SplitMeString, delim)
    68.     LOOP
    69.     loadMeArray(arrpos) = MID$(SplitMeString, curpos)
    70.     REDIM _PRESERVE loadMeArray(LBOUND(loadMeArray) TO arrpos) AS STRING 'get the ubound correct
    71.  
    72.  
    73. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
    74.     DIM Radius AS INTEGER, RadiusError AS INTEGER
    75.     DIM X AS INTEGER, Y AS INTEGER
    76.     Radius = ABS(R): RadiusError = -Radius: X = Radius: Y = 0
    77.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
    78.     LINE (CX - X, CY)-(CX + X, CY), C, BF
    79.     WHILE X > Y
    80.         RadiusError = RadiusError + Y * 2 + 1
    81.         IF RadiusError >= 0 THEN
    82.             IF X <> Y + 1 THEN
    83.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
    84.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
    85.             END IF
    86.             X = X - 1
    87.             RadiusError = RadiusError - X * 2
    88.         END IF
    89.         Y = Y + 1
    90.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
    91.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
    92.     WEND
    93.  
    94.  
    95.  

    Offline bplus

    • Global Moderator
    • Forum Resident
    • Posts: 8053
    • b = b + ...
      • View Profile
    Re: Hypnotic polygon orbits
    « Reply #7 on: February 25, 2020, 08:54:39 pm »
  • Best Answer
  • Piss, I get the same misalignment you guys got:
    Code: QB64: [Select]
    1. _TITLE "Polygon Orbits" 'b+ 2020-02-25
    2. ' Fellippe's post 2020-02-25 https://www.qb64.org/forum/index.php?topic=2234.msg114766#msg114766
    3. ' Inspired by this post: https://www.reddit.com/r/gifs/comments/f91c99/every_addtional_shape_adds_one_more_corner_and/
    4.  
    5. CONST xmax = 700, ymax = 700, side = 130, center = 350, P1 = _PI, P2 = P1 * 2, PD2 = P1 * .5
    6. DIM SHARED poly$(3 TO 15) 'point strings we will turn into arrays as needed
    7. DIM SHARED c(3 TO 15) AS _UNSIGNED LONG 'colors
    8. c(3) = &HFF550000: c(4) = &HFFAA0000: c(5) = &HFFFF0000: c(6) = &HFFDD4400: c(7) = &HFF888800: c(8) = &HFFFF8800
    9. c(9) = &HFF00FF00: c(10) = &HFF00FF88: c(11) = &HFF00FFFF: c(12) = &HFF0088FF: c(13) = &HFF0000FF: c(14) = &HF88F0088: c(15) = &HFF330033
    10. DIM SHARED node, frac 'frac for moving disks between nodes
    11. SCREEN _NEWIMAGE(xmax, ymax, 32)
    12. _SCREENMOVE 300, 20
    13. DIM n, a, isoA, isoA2, turn, r, x1, y1, currA, ring, x2, y2
    14. FOR n = 3 TO 15
    15.     a = P2 / n '                  central angle
    16.     isoA = (P1 - a) / 2 '         angle of one iso triangle at base
    17.     isoA2 = isoA * 2 '            2 iso's is interior angle at each node
    18.     turn = P1 - isoA2 '           for turtle drawing, turn this much at each point
    19.     r = .5 * side / SIN(a / 2) ' << so  << 1/2 * side = r * sin(1/2 * a)
    20.     x1 = center + r * COS(a / 2 + PD2): y1 = center + r * SIN(a / 2 + PD2)
    21.     poly$(n) = STR$(x1) + "," + STR$(y1) 'our first point for polygon
    22.     currA = P1 'turtle draw the rest of the poly and save the points
    23.     FOR ring = 2 TO n + 1
    24.         currA = currA + turn
    25.         x2 = x1 + side * COS(currA): y2 = y1 + side * SIN(currA)
    26.         LINE (x1, y1)-(x2, y2)
    27.         x1 = x2: y1 = y2
    28.         poly$(n) = poly$(n) + "," + STR$(x1) + "," + STR$(y1)
    29.     NEXT
    30. frac = 4
    31. WHILE _KEYDOWN(27) = 0
    32.     CLS
    33.     frac = frac + 1
    34.     IF frac = 10 THEN frac = 0: node = node + 1
    35.     drawPolys
    36.     _DISPLAY
    37.     _LIMIT 30
    38.  
    39. SUB drawPolys
    40.     DIM n, i, x1, y1, x2, y2, target, lastNode, midx, midy
    41.     FOR n = 3 TO 15
    42.         REDIM pts$(0)
    43.         Split poly$(n), ",", pts$()
    44.         PSET (VAL(pts$(0)), VAL(pts$(1))), c(n)
    45.         FOR i = 2 TO UBOUND(pts$) STEP 2
    46.             x1 = VAL(pts$(i)): y1 = VAL(pts$((i + 1)))
    47.             LINE -(x1, y1), c(n)
    48.         NEXT
    49.         target = node MOD n: lastNode = target - 1
    50.         IF lastNode < 0 THEN lastNode = n - 1
    51.         x1 = VAL(pts$(2 * lastNode)): y1 = VAL(pts$(2 * lastNode + 1))
    52.         x2 = VAL(pts$(2 * target)): y2 = VAL(pts$(2 * target + 1))
    53.         midx = x1 + (x2 - x1) * frac / 10: midy = y1 + (y2 - y1) * frac / 10
    54.         fcirc midx, midy, 9, c(n)
    55.     NEXT
    56.  
    57. SUB Split (SplitMeString AS STRING, delim AS STRING, loadMeArray() AS STRING)
    58.     DIM curpos AS LONG, arrpos AS LONG, LD AS LONG, dpos AS LONG 'fix use the Lbound the array already has
    59.     curpos = 1: arrpos = LBOUND(loadMeArray): LD = LEN(delim)
    60.     dpos = INSTR(curpos, SplitMeString, delim)
    61.     DO UNTIL dpos = 0
    62.         loadMeArray(arrpos) = MID$(SplitMeString, curpos, dpos - curpos)
    63.         arrpos = arrpos + 1
    64.         IF arrpos > UBOUND(loadMeArray) THEN REDIM _PRESERVE loadMeArray(LBOUND(loadMeArray) TO UBOUND(loadMeArray) + 1000) AS STRING
    65.         curpos = dpos + LD
    66.         dpos = INSTR(curpos, SplitMeString, delim)
    67.     LOOP
    68.     loadMeArray(arrpos) = MID$(SplitMeString, curpos)
    69.     REDIM _PRESERVE loadMeArray(LBOUND(loadMeArray) TO arrpos) AS STRING 'get the ubound correct
    70.  
    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.     Radius = ABS(R): RadiusError = -Radius: X = Radius: Y = 0
    75.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
    76.     LINE (CX - X, CY)-(CX + X, CY), C, BF
    77.     WHILE X > Y
    78.         RadiusError = RadiusError + Y * 2 + 1
    79.         IF RadiusError >= 0 THEN
    80.             IF X <> Y + 1 THEN
    81.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
    82.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
    83.             END IF
    84.             X = X - 1
    85.             RadiusError = RadiusError - X * 2
    86.         END IF
    87.         Y = Y + 1
    88.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
    89.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
    90.     WEND
    91.  

    And do you know why?

    WE are going down each line segment at the same rate, stop the motion at any time and every dot is the same distance between the nodes:
     
    Polygon Orbit.PNG
     

    But that's not how the code from the link is drawing the disks, stop the motion there and the disks are anywhere along each line segment between nodes:
     
    OK these disc aren't at the same place on the line segments.PNG


    We've been lied to my friends, the title in the link says the dots move at the same speed. They don't! Just watch the outside dot and the next one in and compare their speeds going round.

    So... how do we change our code to have the disks move in the way to form the cool patterns that are found in the link?
    « Last Edit: February 25, 2020, 09:00:38 pm by bplus »

    FellippeHeitor

    • Guest
    Re: Hypnotic polygon orbits
    « Reply #8 on: February 25, 2020, 08:58:23 pm »
  • Best Answer
  • Lol, great investigative work, bplus. Kudos for the xtra attention to detail!

    Offline bplus

    • Global Moderator
    • Forum Resident
    • Posts: 8053
    • b = b + ...
      • View Profile
    Re: Hypnotic polygon orbits
    « Reply #9 on: February 25, 2020, 09:01:42 pm »
  • Best Answer
  • Thanks Fellippe, but now I want that cool pattern maker found in the link. ;-)

    FellippeHeitor

    • Guest
    Re: Hypnotic polygon orbits
    « Reply #10 on: February 25, 2020, 09:03:44 pm »
  • Best Answer
  • Something tells me you’re not one to rest until it looks closer...

    Offline bplus

    • Global Moderator
    • Forum Resident
    • Posts: 8053
    • b = b + ...
      • View Profile
    Re: Hypnotic polygon orbits
    « Reply #11 on: February 25, 2020, 09:19:27 pm »
  • Best Answer
  • Well it shouldn't take more than the rest of the night, maybe less?


    Update:
    Ha! I am just now reading the comments,

    Quote
    Well there's definitely something fucky going on with the gif to make it look like this.

    I got 27729 nodes before complete alignment again at the start line pointing down. But then I recounted the number of concentric polygons, oh 13 not 10, I had to insert 3 more rings and find 3 more colors, that's when I switched color systems from $color:32 names to hexadecimal, easier to make rainbow set. So 13 X 27720 = 360,360 nodes to cross before alignment as it starts what this guy calculates in first comment posted there.

    All those comments were great!

    « Last Edit: February 25, 2020, 09:37:40 pm by bplus »

    FellippeHeitor

    • Guest
    Re: Hypnotic polygon orbits
    « Reply #12 on: February 25, 2020, 09:26:47 pm »
  • Best Answer
  • ❤️

    Offline bplus

    • Global Moderator
    • Forum Resident
    • Posts: 8053
    • b = b + ...
      • View Profile
    Re: Hypnotic polygon orbits
    « Reply #13 on: February 25, 2020, 11:04:53 pm »
  • Best Answer
  • Look familiar?
    Code: QB64: [Select]
    1. _TITLE "Orbit Patterns" 'b+ started 2020-02-25
    2. 'can we find speeds for disks going in  orbits around center st they form patterns
    3.  
    4. CONST xmax = 700, ymax = 700, center = 350, P1 = _PI, P2 = P1 * 2, PD2 = P1 * .5
    5. SCREEN _NEWIMAGE(xmax, ymax, 32)
    6. _SCREENMOVE 300, 20
    7. DIM rate(1 TO 20)
    8. FOR i = 1 TO 20
    9.     rate(i) = (21 - i) / 12
    10. WHILE _KEYDOWN(27) = 0
    11.     CLS
    12.     FOR r = 10 TO 200 STEP 10
    13.         i = INT(r / 10)
    14.         x = center + r * COS(rate(i) * a)
    15.         y = center + r * SIN(rate(i) * a)
    16.         CIRCLE (x, y), 5
    17.     NEXT
    18.     a = a + _PI(2 / 120)
    19.     _DISPLAY
    20.     _LIMIT 30
    21.  
    22.  

    Offline STxAxTIC

    • Library Staff
    • Forum Resident
    • Posts: 1091
    • he lives
      • View Profile
    Re: Hypnotic polygon orbits
    « Reply #14 on: February 25, 2020, 11:32:19 pm »
  • Best Answer
  • Phew, I was busting at the seams to just shut up for once about a math problem... But this reminds me of a riddle - lemme go from memory:

    Suppose you're house-sitting for some up-tight rich people. You just go there to feed the fish, and that's it. They even turned the main circuit breaker off (fuse panel if you like), and locked the box. One day, you walk in to perform your duties, and absentmindedly pull the chain down on the ceiling fan. Oops, when the owners come back, the house power comes on, and so does the fan! But... based on your knowledge of fans, the pull-switch can change the speed of the motor a few times before turning it off. Taking it for certain that either three total pulls of the chain or four total pulls of the chain will leave it in the off-position, what do you do? Pull it 3 total times or 4 total times?

    And as a bonus - how does that apply to this problem?
    You're not done when it works, you're done when it's right.