Author Topic: How to properly move stuff  (Read 3097 times)

0 Members and 1 Guest are viewing this topic.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
How to properly move stuff
« on: November 24, 2020, 08:38:40 pm »
Hi folks.

I keep teasing this concept, and occasionally quietly solve this-or-that problem using these methods without really explaining things, so it's finally time for a bare-bones demo of... drum roll please... parameterized motion.

Punchline first: If you see what's going on here, you will know how to move anything on screen, to anywhere, in any way you want, in full generality. This code ignores rotations, there is plenty to study with just translations.

When you run the code below, what you see, simply, is a circle moving from a beginning point A to an ending point B. The motion is of course not linear. The moving ball is doing two things:
(i) Trying to move straight in a straight line from A to B, using a speed function governed by the hyperbolic tangent. It starts slow, gets quick, and ends slow.
(ii) Trying to wiggle in a direction perpendicular to the motion, using wacky sine function stuff.

The combination of (i) and (ii) is what you see on screen. While it's running, even right in the middle of the motion, click+drag to move the target point around, and all of the motion adjusts seamlessly. Once you see the power and ease of this, you can imagine that literally *any* kind of motion can be tuned into this thing.

Play with some numbers and see how it applies to your projects:

Code: QB64: [Select]
  1.  
  2. SCREEN _NEWIMAGE(800, 600, 32)
  3.  
  4. pi = 4 * ATN(1)
  5.  
  6. TYPE Vector
  7.     x AS DOUBLE
  8.     y AS DOUBLE
  9.  
  10. DIM SHARED PointA AS Vector
  11. DIM SHARED PointB AS Vector
  12. PointA.x = -200
  13. PointA.y = -100
  14. PointB.x = 200
  15. PointB.y = 100
  16.  
  17. DIM SHARED Displacement AS Vector
  18. DIM SHARED Tangential AS Vector
  19. DIM SHARED Player AS Vector
  20.  
  21. CALL SetMotion
  22.  
  23. ' Main loop
  24.     FOR t = 0 TO 1 STEP .01
  25.         q = -4 * (1 - 2 * t)
  26.         p = .5 * (1 + tanh(q)) ' Goes from 0 to 1.
  27.  
  28.         DO WHILE _MOUSEINPUT
  29.             IF (_MOUSEBUTTON(1)) THEN
  30.                 PointB.x = -_WIDTH / 2 + _MOUSEX
  31.                 PointB.y = _HEIGHT / 2 - _MOUSEY
  32.                 CALL SetMotion
  33.             END IF
  34.         LOOP
  35.  
  36.         Player.x = PointA.x + Displacement.x * (p) + Tangential.x * (40 * SIN(2 * pi * p))
  37.         Player.y = PointA.y + Displacement.y * (p) + Tangential.y * (40 * SIN(5 * pi * p))
  38.  
  39.         'CLS
  40.         LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, 30), BF
  41.         LOCATE 1, 1: PRINT "Left-Click+Drag to move target point."
  42.         CALL ccircle(PointA.x, PointA.y, 20, _RGBA(255, 0, 0, 255))
  43.         CALL ccircle(Player.x, Player.y, 20, _RGBA(0, 255, 0, 255))
  44.         CALL ccircle(PointB.x, PointB.y, 20, _RGBA(0, 0, 255, 255))
  45.         _DISPLAY
  46.         _LIMIT 30
  47.     NEXT
  48.  
  49.  
  50. SUB SetMotion
  51.     DIM mag AS DOUBLE
  52.     Displacement.x = PointB.x - PointA.x
  53.     Displacement.y = PointB.y - PointA.y
  54.     Tangential.x = -Displacement.y
  55.     Tangential.y = Displacement.x
  56.     mag = SQR(Tangential.x ^ 2 + Tangential.y ^ 2)
  57.     Tangential.x = Tangential.x / mag
  58.     Tangential.y = Tangential.y / mag
  59.  
  60. SUB ccircle (x1 AS DOUBLE, y1 AS DOUBLE, rad AS DOUBLE, col AS _UNSIGNED LONG)
  61.     CIRCLE (_WIDTH / 2 + x1, -y1 + _HEIGHT / 2), rad, col
  62.  
  63. FUNCTION tanh (x AS DOUBLE)
  64.     tanh = (EXP(2 * x) - 1) / (EXP(2 * x) + 1)
motion.png
* motion.png (Filesize: 39.25 KB, Dimensions: 800x600, Views: 194)
« Last Edit: November 25, 2020, 08:01:26 am by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: How to properly move stuff
« Reply #1 on: November 25, 2020, 07:44:26 pm »
Nice, welcome to the "I've used tanh not for the sake of using tanh" club!

Also, people may want things moving at a constant velocity magnitude
« Last Edit: November 25, 2020, 07:49:08 pm by _vince »

Offline OldMoses

  • Seasoned Forum Regular
  • Posts: 469
    • View Profile
Re: How to properly move stuff
« Reply #2 on: November 25, 2020, 09:13:26 pm »
I would dearly love to get my head wrapped around parametrics, as it looks like something I'm desperately trying to do, but my Algebra I teacher spent most of his time throwing erasers at me. ;)
« Last Edit: November 25, 2020, 09:14:27 pm by OldMoses »