Author Topic: Fidget Spinner  (Read 3612 times)

0 Members and 1 Guest are viewing this topic.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Fidget Spinner
« on: February 16, 2020, 09:10:48 am »
My two-hour coding blitz of the morning led to this:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 480, 32)
  2.  
  3. TYPE Vector
  4.     x AS DOUBLE
  5.     y AS DOUBLE
  6.  
  7. TYPE Object
  8.     Index AS INTEGER
  9.     CtrMass AS Vector
  10.     CtrRot AS Vector
  11.     MOI AS DOUBLE
  12.     Length AS INTEGER
  13.     Shade AS _UNSIGNED LONG
  14.     Omega AS DOUBLE
  15.  
  16. REDIM SHARED Shape(10) AS Object
  17. REDIM SHARED PointChain(10, 1000) AS Vector
  18.  
  19. DIM gravity AS Vector
  20. DIM vtemp AS Vector
  21.  
  22. k = 1
  23. Shape(k).Index = 1
  24. Shape(k).CtrRot.x = 130
  25. Shape(k).CtrRot.y = 130
  26. i = 0
  27. FOR j = 0 TO 6.28 STEP .01
  28.     i = i + 1
  29.     r = 100 + 40 * COS(3 * j)
  30.     PointChain(k, i).x = 0 + r * COS(j)
  31.     PointChain(k, i).y = 0 + r * SIN(j)
  32. Shape(k).Length = i
  33. Shape(k).Omega = 0
  34. Shape(k).Shade = _RGB(255, 255, 255)
  35. CALL CalculateCtrMass(k)
  36. CALL CalculateMOI(k)
  37.  
  38. 'k = 2
  39. 'Shape(k).Index = 1
  40. 'Shape(k).CtrRot.x = 130
  41. 'Shape(k).CtrRot.y = 130
  42. 'i = 0
  43. 'FOR j = 0 TO 6.28 STEP .01
  44. '    i = i + 1
  45. '    r = 30
  46. '    PointChain(k, i).x = 200 + r * COS(j)
  47. '    PointChain(k, i).y = 200 + r * SIN(j)
  48. 'NEXT
  49. 'Shape(k).Length = i
  50. 'Shape(k).Omega = 0
  51. 'Shape(k).Shade = _RGB(0, 255, 255)
  52. 'CALL CalculateCtrMass(k)
  53. 'CALL CalculateMOI(k)
  54.  
  55. gravity.x = 0
  56. gravity.y = -.4
  57.  
  58.         x = _MOUSEX
  59.         y = _MOUSEY
  60.         IF ((x > 0) AND (x < _WIDTH) AND (y > 0) AND (y < _HEIGHT)) THEN
  61.             IF (_MOUSEBUTTON(1)) THEN
  62.                 x = _MOUSEX - _WIDTH / 2
  63.                 y = -_MOUSEY + _HEIGHT / 2
  64.                 Shape(1).CtrRot.x = x
  65.                 Shape(1).CtrRot.y = y
  66.                 CALL CalculateMOI(1)
  67.                 Shape(1).Omega = 0
  68.             END IF
  69.             IF (_MOUSEBUTTON(2)) THEN
  70.                 x = _MOUSEX - _WIDTH / 2
  71.                 y = -_MOUSEY + _HEIGHT / 2
  72.                 vtemp.x = x - Shape(1).CtrMass.x
  73.                 vtemp.y = y - Shape(1).CtrMass.y
  74.                 CALL TranslateShape(1, vtemp)
  75.                 CALL CalculateMOI(1)
  76.                 Shape(1).Omega = 0
  77.             END IF
  78.         END IF
  79.     LOOP
  80.  
  81.     IF (_KEYHIT = 32) THEN
  82.         Shape(1).CtrRot.x = 0
  83.         Shape(1).CtrRot.y = 0
  84.         vtemp.x = 0 - Shape(1).CtrMass.x
  85.         vtemp.y = 0 - Shape(1).CtrMass.y
  86.         CALL TranslateShape(1, vtemp)
  87.         CALL CalculateMOI(1)
  88.         Shape(1).Omega = 0
  89.         _KEYCLEAR
  90.     END IF
  91.  
  92.     FOR ShapeIndex = 1 TO 2
  93.  
  94.         dx = Shape(ShapeIndex).CtrMass.x - Shape(ShapeIndex).CtrRot.x
  95.         dy = Shape(ShapeIndex).CtrMass.y - Shape(ShapeIndex).CtrRot.y
  96.         torque = dx * gravity.y - dy * gravity.x
  97.         Shape(ShapeIndex).Omega = Shape(ShapeIndex).Omega + torque / Shape(ShapeIndex).MOI
  98.         CALL RotShape(ShapeIndex, Shape(ShapeIndex).CtrRot, Shape(ShapeIndex).Omega)
  99.  
  100.         LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, 100), BF
  101.         LOCATE 1, 1: PRINT "Mouse1 = Change axis  --  Mouse2 = Change position  --  Space = Reset"
  102.         FOR i = 1 TO Shape(ShapeIndex).Length
  103.             CALL cpset(PointChain(ShapeIndex, i).x, PointChain(ShapeIndex, i).y, Shape(ShapeIndex).Shade)
  104.         NEXT
  105.         CALL ccircle(Shape(ShapeIndex).CtrMass.x, Shape(ShapeIndex).CtrMass.y, 3, Shape(ShapeIndex).Shade)
  106.         CALL ccircle(Shape(ShapeIndex).CtrRot.x, Shape(ShapeIndex).CtrRot.y, 3, Shape(ShapeIndex).Shade)
  107.         CALL cline(Shape(ShapeIndex).CtrMass.x, Shape(ShapeIndex).CtrMass.y, Shape(ShapeIndex).CtrRot.x, Shape(ShapeIndex).CtrRot.y, Shape(ShapeIndex).Shade)
  108.  
  109.     NEXT
  110.  
  111.     _DISPLAY
  112.     _LIMIT 120
  113.  
  114.  
  115. SUB CalculateCtrMass (k AS INTEGER)
  116.     xx = 0
  117.     yy = 0
  118.     FOR i = 1 TO Shape(k).Length
  119.         xx = xx + PointChain(k, i).x
  120.         yy = yy + PointChain(k, i).y
  121.     NEXT
  122.     Shape(k).CtrMass.x = xx / Shape(k).Length
  123.     Shape(k).CtrMass.y = yy / Shape(k).Length
  124.  
  125. SUB CalculateMOI (k AS INTEGER)
  126.     xx = 0
  127.     yy = 0
  128.     FOR i = 1 TO Shape(k).Length
  129.         xx = xx + (Shape(k).CtrRot.x - PointChain(k, i).x) ^ 2
  130.         yy = yy + (Shape(k).CtrRot.y - PointChain(k, i).y) ^ 2
  131.     NEXT
  132.     Shape(k).MOI = (xx + yy) / Shape(k).Length
  133.  
  134. SUB TranslateShape (k AS INTEGER, c AS Vector)
  135.     FOR i = 1 TO Shape(k).Length
  136.         PointChain(k, i).x = PointChain(k, i).x + c.x
  137.         PointChain(k, i).y = PointChain(k, i).y + c.y
  138.     NEXT
  139.     ' Move center of mass.
  140.     Shape(k).CtrMass.x = Shape(k).CtrMass.x + c.x
  141.     Shape(k).CtrMass.y = Shape(k).CtrMass.y + c.y
  142.  
  143. SUB RotShape (k AS INTEGER, c AS Vector, da AS DOUBLE)
  144.     FOR i = 1 TO Shape(k).Length
  145.         xx = PointChain(k, i).x - c.x
  146.         yy = PointChain(k, i).y - c.y
  147.         PointChain(k, i).x = c.x + xx * COS(da) - yy * SIN(da)
  148.         PointChain(k, i).y = c.y + yy * COS(da) + xx * SIN(da)
  149.     NEXT
  150.     ' Move center of mass.
  151.     xx = Shape(k).CtrMass.x - c.x
  152.     yy = Shape(k).CtrMass.y - c.y
  153.     Shape(k).CtrMass.x = c.x + xx * COS(da) - yy * SIN(da)
  154.     Shape(k).CtrMass.y = c.y + yy * COS(da) + xx * SIN(da)
  155.  
  156. SUB cline (x1, y1, x2, y2, col AS _UNSIGNED LONG)
  157.     LINE (_WIDTH / 2 + x1, -y1 + _HEIGHT / 2)-(_WIDTH / 2 + x2, -y2 + _HEIGHT / 2), col
  158.  
  159. SUB ccircle (x1, y1, rad, col AS _UNSIGNED LONG)
  160.     CIRCLE (_WIDTH / 2 + x1, -y1 + _HEIGHT / 2), rad, col
  161.  
  162. SUB cpset (x1, y1, col AS _UNSIGNED LONG)
  163.     PSET (_WIDTH / 2 + x1, -y1 + _HEIGHT / 2), col
« Last Edit: February 16, 2020, 10:25:13 am by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Fidget Spinner
« Reply #1 on: February 16, 2020, 01:46:43 pm »
Hi Stac,

When are you going to change center of balance to effectively make this a double pendulum? eg make one lobe giantic (sic, I can makeup words too).