QB64.org Forum

Active Forums => Programs => Topic started by: bplus on March 09, 2020, 02:23:17 am

Title: Pushing circles around
Post by: bplus on March 09, 2020, 02:23:17 am
I just found this in collisions folder, kind of interesting:

Code: QB64: [Select]
  1. _TITLE "Ball Collision - use left mouse button to move red ball"
  2. ' by ED12345 copied from [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there] 2018-04-02
  3. SCREEN _NEWIMAGE(800, 600, 32)
  4.  
  5. TYPE BALL
  6.     x AS DOUBLE
  7.     y AS DOUBLE
  8.     radius AS DOUBLE
  9.  
  10. TYPE TARGET
  11.     x AS DOUBLE
  12.     y AS DOUBLE
  13.     radius AS DOUBLE
  14.  
  15. CONST RED = _RGB32(255, 0, 0)
  16. CONST BLUE = _RGB32(0, 0, 255)
  17. CONST leftMouseButton = 1
  18.  
  19. DIM SHARED ball AS BALL
  20. DIM SHARED target AS TARGET
  21.  
  22. ball.x = 200: ball.y = 200
  23. target.x = 600: target.y = 400
  24. ball.radius = 50
  25. target.radius = 50
  26.  
  27.  
  28.     mouse = _MOUSEINPUT
  29.  
  30.     IF _MOUSEBUTTON(leftMouseButton) THEN
  31.         ball.x = _MOUSEX
  32.         ball.y = _MOUSEY
  33.  
  34.         CALL Collision
  35.     END IF
  36.  
  37.     PCOPY _DISPLAY, 1
  38.     CIRCLE (ball.x, ball.y), ball.radius, RED
  39.     CIRCLE (target.x, target.y), target.radius, BLUE
  40.     _DISPLAY
  41.     PCOPY 1, _DISPLAY
  42.  
  43.  
  44. SUB Collision
  45.  
  46.     distance! = _HYPOT((ball.x - target.x), (ball.y - target.y))
  47.  
  48.     IF distance! <= ball.radius + target.radius THEN
  49.  
  50.         overlap! = (distance - (ball.radius + target.radius)) * 0.5
  51.  
  52.         ball.x = ball.x - overlap! * (ball.x - target.x) / distance!
  53.         ball.y = ball.y - overlap! * (ball.y - target.y) / distance!
  54.  
  55.         target.x = target.x - overlap! * (target.x - ball.x) / distance!
  56.         target.y = target.y - overlap! * (target.y - ball.y) / distance!
  57.  
  58.     END IF
  59.  
  60.  
  61.  

Works great!
Title: Re: Pushing circles around
Post by: OldMoses on March 09, 2020, 06:15:14 am
When I pushed the target ball too far off the screen, I felt like the kid who tossed his favorite toy out of the car window. :D
Title: Re: Pushing circles around
Post by: bplus on March 09, 2020, 10:34:34 am
Yeah, STxAxTIC ahead of us in wonderland shooting rocks with his catapult.

I wonder when he'll get to bow and arrow? ;)
Title: Re: Pushing circles around
Post by: Ashish on March 09, 2020, 11:15:19 am
This is nice! I would like to know math behind this... I thought for trigonometry, but you are using different approach I think so..
Title: Re: Pushing circles around
Post by: STxAxTIC on March 09, 2020, 06:42:46 pm
This one has pretty simple math in that this demo ignores momentum exchange - that is, speed is not defined at all here. The screenshots below show the derivation for when speed *is* involved, so to make my math match this demo, you have to limit u1 = u2 = 0.

Edit: This derivation of mine sucks. It's impenetrable.  Just use the "q" equation at the bottom of ss1 and call it done.
Title: Re: Pushing circles around
Post by: bplus on March 09, 2020, 09:14:48 pm
This is nice! I would like to know math behind this... I thought for trigonometry, but you are using different approach I think so..

Yeah, it's simpler than trig! I will comment.
Code: QB64: [Select]
  1. SUB Collision
  2.  
  3.     distance! = _HYPOT((ball.x - target.x), (ball.y - target.y)) ' <<<< the distance between the 2 circles as the crow flies,
  4. ' this distance has an x component and a y component that we deal with individually below for readjusting ball and target
  5.  
  6.     IF distance! <= ball.radius + target.radius THEN ' <<<< if distance < the sum of the 2 radii of the 2 circles then they must be overlapping
  7.         overlap! = (distance - (ball.radius + target.radius)) * 0.5  '<<< split the difference of overlap this should be labeled 1/2 the overlap!
  8.  
  9.         ball.x = ball.x - overlap! * (ball.x - target.x) / distance!  ' position ball.x according to difference in target.x  and ball.x as a fraction of their distance away
  10.         ball.y = ball.y - overlap! * (ball.y - target.y) / distance!  'like wise for ball.y
  11.  
  12.         target.x = target.x - overlap! * (target.x - ball.x) / distance! '  likewise and in reverse for target.x and y
  13.         target.y = target.y - overlap! * (target.y - ball.y) / distance!
  14.  
  15.     END IF
  16.  
  17.  
  18.  
While the mouse is down and it's circle is being constantly updated by mouse polling and relocating to that, we don't see the target pushing back on the mouse circle.