Author Topic: Angle Pong  (Read 3389 times)

0 Members and 1 Guest are viewing this topic.

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
Angle Pong
« on: March 07, 2020, 02:01:44 am »
Move the mouse left right up down to change position and angle, self explanatory

Code: [Select]
deflng a-z
const sw = 640
const sh = 480
dim shared pi as double
pi = 4*atn(1)

declare sub circlef(x, y, r, c)

dim a as double
dim b as double, d as double
dim p as double, q as double
dim cx as double, cy as double
dim vx as double, vy as double
dim vxx as double, vyy as double
cx = sw/2
cy = sh/4
vx = 0
vy = 1
r = 15

rebound = -1
ball = 0

screen 12
do

        if cx < r then
                vx = -vx
                rebound = -1
        end if
        if cx > sw - r then
                vx = -vx
                rebound = -1
        end if
        if cy < r then
                vy = -vy
                rebound = -1
        end if
        if cy > sh - r then
                cx = sw/2
                cy = sh/4
                vx = 0
                vy = 1
                rebound = -1
                ball = ball + 1
        end if

        cx = cx + vx
        cy = cy + vy

        do
                mx = _mousex
                my = _mousey
        loop while _mouseinput

        line (0,0)-(sw,sh),0,bf

        x = mx
        y = 395
        if mx < 80 then x = 80
        if mx > sw - 80 then x = sw - 80
        a = (my - sh/2)/(1.1*sh/2)*(pi/2)
        line (x, y)-step(80*cos(a), 80*sin(a))
        line (x, y)-step(-80*cos(a), -80*sin(a))

        if rebound then
        'if a >= 0 and vx <=0 or a < 0 and vx >= 0 then
                q = sin(a)*cos(a + pi/2) - cos(a)*sin(a + pi/2)
                if q <> 0 then
                        p = cy*cos(a) - cx*sin(a) - y*cos(a) + x*sin(a)
                        d = p/q
                        b = (cx + d*cos(a + pi/2) - x)/cos(a)
                        if abs(b) < 80 then
                                'line (cx, cy)- step(d*cos(a + pi/2), d*sin(a + pi/2)), 12
                                if d < r then
                                        vxx = vx*cos(2*a) + vy*sin(2*a)
                                        vyy = vx*sin(2*a) - vy*cos(2*a)
                                        vx = vxx
                                        vy = vyy
                                        rebound = 0
                                end if
                        end if
                end if
        'end if
        end if

        circlef cx, cy, r, 15

        locate 1,1: ? ball
        'locate 1,1: ? a*180/pi
        _display
        _limit 200
loop until _keyhit = 27
sleep
system

sub circlef(x, y, r, c)
        x0 = r
        y0 = 0
        e = -r

        do while y0 < x0
                if e <=0 then
                        y0 = y0 + 1
                        line (x - x0, y + y0)-(x + x0, y + y0), c, bf
                        line (x - x0, y - y0)-(x + x0, y - y0), c, bf
                        e = e + 2*y0
                else
                        line (x - y0, y - x0)-(x + y0, y - x0), c, bf
                        line (x - y0, y + x0)-(x + y0, y + x0), c, bf
                        x0 = x0 - 1
                        e = e - 2*x0
                end if
        loop
        line (x - r, y)-(x + r, y), c, bf
end sub
« Last Edit: March 08, 2020, 10:15:22 pm by _vince »

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
Re: Angle Pong
« Reply #1 on: March 07, 2020, 04:15:54 am »
Just a few things:

1. What, no aliens? lol
2. Cool concept.
3. If the "bat" is perfectly horizontal the "ball" passes through it.... I know, it's early days...
Logic is the beginning of wisdom.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Angle Pong
« Reply #2 on: March 07, 2020, 11:00:09 am »
It doesn't have to be perfectly horizontal for pass through, nor perfectly in middle of paddle what I thought next. I doubt this is random there is something amiss but it is nice to have control of ball return which is why I like a circular paddle in Air Hockey and an oblong bread like bun (ellipse) in my version of Breakout.

Is this a bug or a feature? ;-))

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
Re: Angle Pong
« Reply #3 on: March 08, 2020, 10:51:06 pm »
I've noticed it too, occasionally, but it seemed playable, proof of concept at least, oh well.

There's two ways for the paddle to be come 'invisible', either it detects a backwards paddle which otherwise messes with the geometry calculations, or it has already bounced the ball and will be invisible until the ball hits a wall again.  I've commented out the former in original post, might be more reliable, just dont turn the paddle backwards. Either those things are buggy or something else is fundamentally wrong, not sure if I will bother to look into it.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Angle Pong
« Reply #4 on: March 08, 2020, 11:06:48 pm »
Maybe if paddle swung its angle from mouse wheel instead of whatever you are doing with position.

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
Re: Angle Pong
« Reply #5 on: March 08, 2020, 11:35:22 pm »
Oh dear... Taking it too seriously... I knew it was a P.O.C demo... Just 'poking a stick at the sleeping bear' to get a reaction.... lol

(just in case: I am not implying that anyone is a 'sleeping bear'... just coining a phrase... lol)

I would be interested to see if this demo will develop into anything of note... Looks cool. Perhaps a circular ping pong. Ball would move slightly quicker with each 'bounce' off the 'bat'... First thing I thought of... lol
Logic is the beginning of wisdom.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Angle Pong
« Reply #6 on: March 08, 2020, 11:47:26 pm »
Ball versus ball collision piece of cake, ball versus angled rectangle kind tricky as we have seen here.

Try Circle Intersect Line or Ellipse Intersect Line
« Last Edit: March 09, 2020, 12:05:34 am by bplus »

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
Re: Angle Pong
« Reply #7 on: March 09, 2020, 12:47:35 am »
If you uncomment line 74, the red LINE, you can see how the calculation works, should be robust, so i wonder if it's the 'backwards paddle' detection hack. You can see the mess of trig around it, i've derived it with pure trig and it wasn't the most trivial derivation. Given all the sines and cosines of arctans, there should definitely be a pythagorean theorem variant path for the equivalent or perhaps more robust geometry.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Angle Pong
« Reply #8 on: March 09, 2020, 02:01:50 am »
I don't like wading deep into other's code system which is why I don't attempt to fix _vince version.

Circle intersect line, my version had to be reworked into useful function, I did that here:
Code: QB64: [Select]
  1. _TITLE "Line Intersect Circle Function" ' b+ 2020-03-09 develop
  2.  
  3. CONST xmax = 800, ymax = 600
  4. SCREEN _NEWIMAGE(xmax, ymax, 32)
  5. _DELAY .25
  6.  
  7.     CLS
  8.     IF testTangent = 0 THEN 'test plug in set of border conditions not easy to click
  9.         PRINT "First set here is a plug in test set for vertical lines."
  10.         mx(1) = 200: my(1) = 100: mx(2) = 200: my(2) = 400 'line  x = 200
  11.         mx(3) = 400: my(3) = 300: mx(4) = 150: my(4) = 300 ' circle origin (center 400, 300) then radius test 200 tangent, 150 more than tangent, 250 short
  12.         FOR i = 1 TO 4
  13.             CIRCLE (mx(i), my(i)), 2
  14.         NEXT
  15.         IF mx(1) <> mx(2) THEN
  16.             slopeYintersect mx(1), my(1), mx(2), my(2), m, Y0 ' Y0 otherwise know as y Intersect
  17.             LINE (0, Y0)-(xmax, m * xmax + Y0), &HFF0000FF
  18.             LINE (mx(1), my(1))-(mx(2), my(2))
  19.         ELSE
  20.             LINE (mx(1), 0)-(mx(1), ymax), &HFF0000FF
  21.             LINE (mx(1), my(1))-(mx(2), my(2))
  22.         END IF
  23.         testTangent = 1
  24.     ELSE
  25.         PRINT "First 2 clicks will form a line, 3rd the circle origin and 4th the circle radius:"
  26.         WHILE pi < 4 'get 4 mouse clicks
  27.             _PRINTSTRING (20, 20), SPACE$(20)
  28.             _PRINTSTRING (20, 20), "Need 4 clicks, have" + STR$(pi)
  29.             WHILE _MOUSEINPUT: WEND
  30.             IF _MOUSEBUTTON(1) AND oldMouse = 0 THEN 'new mouse down
  31.                 pi = pi + 1
  32.                 mx(pi) = _MOUSEX: my(pi) = _MOUSEY
  33.                 CIRCLE (mx(pi), my(pi)), 2
  34.                 IF pi = 2 THEN 'draw first line segment then line
  35.                     IF mx(1) <> mx(2) THEN
  36.                         slopeYintersect mx(1), my(1), mx(2), my(2), m, Y0 ' Y0 otherwise know as y Intersect
  37.                         LINE (0, Y0)-(xmax, m * xmax + Y0), &HFF0000FF
  38.                         LINE (mx(1), my(1))-(mx(2), my(2))
  39.                     ELSE
  40.                         LINE (mx(1), 0)-(mx(1), ymax), &HFF0000FF
  41.                         LINE (mx(1), my(1))-(mx(2), my(2))
  42.                     END IF
  43.                 END IF
  44.             END IF
  45.             oldMouse = _MOUSEBUTTON(1)
  46.             _DISPLAY
  47.             _LIMIT 60
  48.         WEND
  49.     END IF
  50.  
  51.     p = mx(3): q = my(3) 'draw circle
  52.     r = SQR((mx(3) - mx(4)) ^ 2 + (my(3) - my(4)) ^ 2)
  53.     CIRCLE (p, q), r, &HFFFF0000
  54.  
  55.     intersect = lineIntersectCircle%(mx(1), my(1), mx(2), my(2), mx(3), my(3), r, ix1, iy1, ix2, iy2)
  56.     IF intersect = 0 THEN
  57.         PRINT "No intersect"
  58.     ELSEIF intersect = 1 THEN
  59.         PRINT "Intersect at tangent point ("; TS$(ix1); ", "; TS$(iy1); ")"
  60.         CIRCLE (ix1, iy1), 2, &HFFFFFF00
  61.     ELSEIF intersect = 2 THEN
  62.         PRINT "2 point intersect ("; TS$(ix1); ", "; TS$(iy1); ") and ("; TS$(ix2); ", "; TS$(iy2); ")"
  63.         CIRCLE (ix1, iy1), 2, &HFFFFFF00
  64.         CIRCLE (ix2, iy2), 2, &HFFFFFF00
  65.     END IF
  66.  
  67.     'IF mx(1) = mx(2) THEN 'line is vertical so if r =
  68.     '    IF r = ABS(mx(1) - mx(3)) THEN ' one point tangent intersect
  69.     '        PRINT "Tangent point is "; TS$(mx(1)); ", "; TS$(my(3))
  70.     '        CIRCLE (mx(1), my(3)), 2, &HFFFFFF00
  71.     '        CIRCLE (mx(1), my(3)), 4, &HFFFFFF00
  72.     '    ELSEIF r < ABS(mx(1) - mx(3)) THEN 'no intersect
  73.     '        PRINT "No intersect, radius too small."
  74.     '    ELSE '2 point intersect
  75.     '        ydist = SQR(r ^ 2 - (mx(1) - mx(3)) ^ 2)
  76.     '        y1 = my(3) + ydist
  77.     '        y2 = my(3) - ydist
  78.     '        PRINT "2 Point intersect (x1, y1) = "; TS$(mx(1)); ", "; TS$(y1); "  (x2, y2) = "; TS$(mx(1)); ", "; TS$(y2)
  79.     '        CIRCLE (mx(1), y1), 2, &HFFFFFF00 'marking intersect points yellow
  80.     '        CIRCLE (mx(1), y2), 2, &HFFFFFF00
  81.     '        CIRCLE (mx(1), y1), 4, &HFFFFFF00 'marking intersect points yellow
  82.     '        CIRCLE (mx(1), y2), 4, &HFFFFFF00
  83.  
  84.     '    END IF
  85.     'ELSE
  86.     '    'OK the calculations!
  87.     '    'from inserting eq ofline into eq of circle where line intersects circle see reference
  88.     '    ' https://math.stackexchange.com/questions/228841/how-do-i-calculate-the-intersections-of-a-straight-line-and-a-circle
  89.     '    A = m ^ 2 + 1
  90.     '    B = 2 * (m * Y0 - m * q - p)
  91.     '    C = q ^ 2 - r ^ 2 + p ^ 2 - 2 * Y0 * q + Y0 ^ 2
  92.     '    D = B ^ 2 - 4 * A * C 'telling part of Quadratic formula = 0 then circle is tangent  or > 0 then 2 intersect points
  93.     '    IF D < 0 THEN ' no intersection
  94.     '        PRINT "m, y0 "; TS$(m); ", "; TS$(Y0)
  95.     '        PRINT "(p, q) "; TS$(p); ", "; TS$(q)
  96.     '        PRINT "A: "; TS$(A)
  97.     '        PRINT "B: "; TS$(B)
  98.     '        PRINT "C: "; TS$(C)
  99.     '        PRINT "D: "; TS$(D); " negative so no intersect."
  100.     '    ELSEIF D = 0 THEN ' one point tangent
  101.     '        x1 = (-B + SQR(D)) / (2 * A)
  102.     '        y1 = m * x1 + Y0
  103.     '        PRINT "Tangent Point Intersect (x1, y1) = "; TS$(x1); ", "; TS$(y1)
  104.     '        CIRCLE (x1, y1), 2, &HFFFFFF00 'yellow circle should be on line perprendicular to 3rd click point
  105.     '        CIRCLE (x1, y1), 4, &HFFFFFF00 'yellow circle should be on line perprendicular to 3rd click point
  106.     '    ELSE
  107.     '        '2 points
  108.     '        x1 = (-B + SQR(D)) / (2 * A): y1 = m * x1 + Y0
  109.     '        x2 = (-B - SQR(D)) / (2 * A): y2 = m * x2 + Y0
  110.     '        PRINT "2 Point intersect (x1, y1) = "; TS$(x1); ", "; TS$(y1); "  (x2, y2) = "; TS$(x2); ", "; TS$(y2)
  111.     '        CIRCLE (x1, y1), 2, &HFFFFFF00 'marking intersect points yellow
  112.     '        CIRCLE (x2, y2), 2, &HFFFFFF00
  113.     '        CIRCLE (x1, y1), 4, &HFFFFFF00 'marking intersect points yellow
  114.     '        CIRCLE (x2, y2), 4, &HFFFFFF00
  115.     '    END IF
  116.     'END IF
  117.     _DISPLAY
  118.     INPUT "press enter to continue, any + enter to quit "; q$
  119.     IF LEN(q$) THEN SYSTEM
  120.     pi = 0 'point index
  121.  
  122. ' return 0 no Intersect, 1 = tangent 1 point touch, 2 = 2 point intersect
  123. FUNCTION lineIntersectCircle% (lx1, ly1, lx2, ly2, cx, cy, r, ix1, iy1, ix2, iy2)
  124.     IF lx1 <> lx2 THEN
  125.         slopeYintersect lx1, ly1, lx2, ly2, m, Y0 ' Y0 otherwise know as y Intersect
  126.  
  127.         ' https://math.stackexchange.com/questions/228841/how-do-i-calculate-the-intersections-of-a-straight-line-and-a-circle
  128.         A = m ^ 2 + 1
  129.         B = 2 * (m * Y0 - m * cy - cx)
  130.         C = cy ^ 2 - r ^ 2 + cx ^ 2 - 2 * Y0 * cy + Y0 ^ 2
  131.         D = B ^ 2 - 4 * A * C 'telling part of Quadratic formula = 0 then circle is tangent  or > 0 then 2 intersect points
  132.         IF D < 0 THEN ' no intersection
  133.             ix1 = -999: iy1 = -999: ix2 = -999: iy2 = -999: lineIntersectCircle% = 0
  134.         ELSEIF D = 0 THEN ' one point tangent
  135.             x1 = (-B + SQR(D)) / (2 * A)
  136.             y1 = m * x1 + Y0
  137.             ix1 = x1: iy1 = y1: ix2 = -999: iy2 = -999: lineIntersectCircle% = 1
  138.         ELSE '2 points
  139.             x1 = (-B + SQR(D)) / (2 * A): y1 = m * x1 + Y0
  140.             x2 = (-B - SQR(D)) / (2 * A): y2 = m * x2 + Y0
  141.             ix1 = x1: iy1 = y1: ix2 = x2: iy2 = y2: lineIntersectCircle% = 2
  142.         END IF
  143.     ELSE 'vertical line
  144.         IF r = ABS(lx1 - cx) THEN ' tangent
  145.             ix1 = lx1: iy1 = cy: ix2 = -999: iy2 = -999: lineIntersectCircle% = 1
  146.         ELSEIF r < ABS(lx1 - cx) THEN 'no intersect
  147.             ix1 = -999: iy1 = -999: ix2 = -999: iy2 = -999: lineIntersectCircle% = 0
  148.         ELSE '2 point intersect
  149.             ydist = SQR(r ^ 2 - (lx1 - cx) ^ 2)
  150.             ix1 = lx1: iy1 = cy + ydist: ix2 = lx1: iy2 = cy - ydist: lineIntersectCircle% = 2
  151.         END IF
  152.     END IF
  153.  
  154. SUB slopeYintersect (X1, Y1, X2, Y2, slope, Yintercept) ' fix for when x1 = x2
  155.     slope = (Y2 - Y1) / (X2 - X1)
  156.     Yintercept = slope * (0 - X1) + Y1
  157.  
  158. FUNCTION TS$ (n)
  159.     TS$ = _TRIM$(STR$(n \ 1))
  160.  
  161.  

I looked at STxAxTIC's Ellipse Intersect Line and that look like complex translation job too, so I fixed up Circle Intersect line because I wanted a useful Function anyway.

Given two points that make a like, the circle's center and radius the above function will tell you if there is an intersection by returning 0, 1 or 2 the number of points:
0 no intersect
1 one intersect at Tangent and the point location
2 ywo point intersect and their locations.

Next to test with paddle = line and ball = circle intersect?
« Last Edit: March 09, 2020, 02:03:55 am by bplus »

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
Re: Angle Pong
« Reply #9 on: March 09, 2020, 02:11:55 am »
One thing I've learned from the superficial method is that with random angles and precision errors, there's going to be instances where you will not get a single point, but it will instantly go from no points to two points. I guess you could look at the distances between the two points and if it's short enough, do the bounce, and that's a fair and acceptable solution. What if one point is on paddle and the other is off? IDK, but should be doable. Then your axis of reflection for the ball is the line crossing between the two points and normal to the paddle. Easier? IDK, but it's all yours if you want to show me up. I went with finding the incident vector from ball to paddle and seeing if it's within the paddle bounds and whether it's shorter than ball radius.
« Last Edit: March 09, 2020, 02:13:57 am by _vince »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Angle Pong
« Reply #10 on: March 09, 2020, 02:19:31 am »
Quote
What if one point is on paddle and the other is off?

What if both points are? good question!!!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Angle Pong
« Reply #11 on: March 10, 2020, 12:52:42 am »
Hey I made some progress, I can tell when contact is made and which side of the paddle the ball is on. I can draw the paddle handle on the opposite side of the ball, woohoo!

Ball rebound absolutely stinks but I know it can be worked out now that I have a handle on things, ha, ha!

Code: QB64: [Select]
  1. _TITLE "Angle Paddle Test, mouse wheel down is clockwise" 'b+ started 2020-03-08  from _vince idea
  2. CONST xmax = 800, ymax = 600, xc = 400, yc = 300
  3. DIM SHARED P, P2, Pd2
  4. P = _PI: P2 = 2 * P: Pd2 = P / 2
  5. SCREEN _NEWIMAGE(xmax, ymax, 32)
  6. _DELAY .2 'need time for screen to load before attempting to move it.
  7.  
  8. bx = xc: by = yc: bdx = -1: bdy = 3: br = 20
  9. mr = 50: ma = 0
  10. WHILE _KEYDOWN(27) = 0
  11.     CLS
  12.     ba = _ATAN2(bdy, bdx)
  13.     IF ba < 0 THEN ba = ba + P2
  14.     PRINT "ma"; _R2D(ma) \ 1; "  ba"; _R2D(ba) \ 1
  15.  
  16.     bx = bx + bdx
  17.     IF bx < br THEN bx = br: bdx = -bdx
  18.     IF bx > xmax - br THEN bx = xmax - br: bdx = -bdx
  19.  
  20.     by = by + bdy
  21.     IF by < br THEN by = br: bdy = -bdy
  22.     IF by > ymax - br THEN by = ymax - br: bdy = -bdy
  23.  
  24.     WHILE _MOUSEINPUT '                                            paddle
  25.         ma = ma + _MOUSEWHEEL * P2 / 72 '5 degrees change
  26.     WEND
  27.     mx = _MOUSEX: my = _MOUSEY
  28.     mx1 = mx + mr * COS(ma)
  29.     my1 = my + mr * SIN(ma)
  30.     mx2 = mx + mr * COS(ma + P)
  31.     my2 = my + mr * SIN(ma + P)
  32.     LINE (mx1, my1)-(mx2, my2), &HFFFF8800
  33.     'draw a handle to track the side the ball is on
  34.     hx1 = mx + br * COS(ma + Pd2): hy1 = my + br * SIN(ma + Pd2)
  35.     hx2 = mx + br * COS(ma - Pd2): hy2 = my + br * SIN(ma - Pd2)
  36.     d1 = _HYPOT(hx1 - bx, hy1 - by): d2 = _HYPOT(hx2 - bx, hy2 - by)
  37.     IF d1 < d2 THEN LINE (hx2, hy2)-(mx, my), &HFFFF8800 ELSE LINE (hx1, hy1)-(mx, my), &HFFFF8800
  38.  
  39.     tx = -99: ty = -99
  40.     dist = _HYPOT(bx - mx, by - my) '                             collision?
  41.     IF dist < br + mr THEN '                                     centers close enough
  42.         contacts = lineIntersectCircle%(mx1, my1, mx2, my2, bx, by, br, ix1, iy1, ix2, iy2)
  43.         IF contacts THEN PRINT "Contact"; contacts: _DELAY .5 'OK so far
  44.         IF contacts = 1 THEN 'just touched (or passed through)
  45.             IF _HYPOT(ix1 - mx, iy1 - my) < br THEN tx = ix1: ty = iy1
  46.         ELSEIF contacts = 2 THEN
  47.             'contact point would have been in middle of 2 points
  48.             tx = (ix1 + ix2) / 2: ty = (iy1 + iy2) / 2
  49.         END IF
  50.         IF tx > 0 THEN ' rebound ball
  51.             CIRCLE (tx, ty), 2
  52.             ba = _ATAN2(bdy, bdx)
  53.             bs = _HYPOT(bdx, bdy)
  54.             ta = _ATAN2(ty - by, tx - bx)
  55.             PRINT ba, bs, ta, ma
  56.             IF ba - (ma + _PI / 2) < _PI / 2 THEN
  57.                 ba = ba - (ma + _PI / 2)
  58.             ELSE
  59.                 ba = ba - (ma - _PI / 2)
  60.             END IF
  61.             bdx = bs * COS(ba) 'update the new direction of ball
  62.             bdy = bs * SIN(ba)
  63.         END IF
  64.     END IF
  65.     CIRCLE (bx, by), br 'ball
  66.     _DISPLAY
  67.     _LIMIT 60
  68.  
  69.  
  70. ' return 0 no Intersect, 1 = tangent 1 point touch, 2 = 2 point intersect
  71. FUNCTION lineIntersectCircle% (lx1, ly1, lx2, ly2, cx, cy, r, ix1, iy1, ix2, iy2)
  72.  
  73.     'needs    SUB slopeYintersect (X1, Y1, X2, Y2, slope, Yintercept)
  74.  
  75.     IF lx1 <> lx2 THEN
  76.         slopeYintersect lx1, ly1, lx2, ly2, m, Y0 ' Y0 otherwise know as y Intersect
  77.  
  78.         ' https://math.stackexchange.com/questions/228841/how-do-i-calculate-the-intersections-of-a-straight-line-and-a-circle
  79.         A = m ^ 2 + 1
  80.         B = 2 * (m * Y0 - m * cy - cx)
  81.         C = cy ^ 2 - r ^ 2 + cx ^ 2 - 2 * Y0 * cy + Y0 ^ 2
  82.         D = B ^ 2 - 4 * A * C 'telling part of Quadratic formula = 0 then circle is tangent  or > 0 then 2 intersect points
  83.         IF D < 0 THEN ' no intersection
  84.             ix1 = -999: iy1 = -999: ix2 = -999: iy2 = -999: lineIntersectCircle% = 0
  85.         ELSEIF D = 0 THEN ' one point tangent
  86.             x1 = (-B + SQR(D)) / (2 * A)
  87.             y1 = m * x1 + Y0
  88.             ix1 = x1: iy1 = y1: ix2 = -999: iy2 = -999: lineIntersectCircle% = 1
  89.         ELSE '2 points
  90.             x1 = (-B + SQR(D)) / (2 * A): y1 = m * x1 + Y0
  91.             x2 = (-B - SQR(D)) / (2 * A): y2 = m * x2 + Y0
  92.             ix1 = x1: iy1 = y1: ix2 = x2: iy2 = y2: lineIntersectCircle% = 2
  93.         END IF
  94.     ELSE 'vertical line
  95.         IF r = ABS(lx1 - cx) THEN ' tangent
  96.             ix1 = lx1: iy1 = cy: ix2 = -999: iy2 = -999: lineIntersectCircle% = 1
  97.         ELSEIF r < ABS(lx1 - cx) THEN 'no intersect
  98.             ix1 = -999: iy1 = -999: ix2 = -999: iy2 = -999: lineIntersectCircle% = 0
  99.         ELSE '2 point intersect
  100.             ydist = SQR(r ^ 2 - (lx1 - cx) ^ 2)
  101.             ix1 = lx1: iy1 = cy + ydist: ix2 = lx1: iy2 = cy - ydist: lineIntersectCircle% = 2
  102.         END IF
  103.     END IF
  104.  
  105. SUB slopeYintersect (X1, Y1, X2, Y2, slope, Yintercept) ' fix for when x1 = x2
  106.     slope = (Y2 - Y1) / (X2 - X1)
  107.     Yintercept = slope * (0 - X1) + Y1
  108.  
  109.  

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
Re: Angle Pong
« Reply #12 on: March 10, 2020, 06:04:59 am »
I should have posted my notes here rather than there! Ball rebound is perfectly calculated at:

https://www.qb64.org/forum/index.php?topic=2319.msg115468#msg115468

Limit the second ball at r=infinity to turn it into a line and let its mass be infinite if you dont want the paddle to rebound.
« Last Edit: March 10, 2020, 06:16:52 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 + ...
Re: Angle Pong
« Reply #13 on: March 10, 2020, 12:35:07 pm »
Well for now I will settle for treating ball meets paddle the same as ball meets wall, only the wall/paddle has infinitely many angles (theoretically). That is why I needed to know which side of the wall/paddle the ball is. Ball meets moving paddle/wall is for later.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Angle Pong
« Reply #14 on: March 10, 2020, 10:43:26 pm »
I think I have it. I put a tracer on the ball and paddle to show that the the angle in = the angle out as in a reflection of light.

Code: QB64: [Select]
  1. _TITLE "Angle Paddle Test, mouse wheel down is clockwise" 'b+ started 2020-03-08  from _vince idea
  2. CONST xmax = 800, ymax = 600, xc = 400, yc = 300
  3. DIM SHARED P, P2, Pd2
  4. P = _PI: P2 = 2 * P: Pd2 = P / 2
  5. SCREEN _NEWIMAGE(xmax, ymax, 32)
  6. _DELAY .2 'need time for screen to load before attempting to move it.
  7.  
  8. bx = xc: by = yc: br = 20: bs = 5: ba = _D2R(60)
  9. mr = 50: ma = 0
  10. WHILE _KEYDOWN(27) = 0
  11.  
  12.     LINE (0, 0)-(xmax, ymax), &H10000000, BF
  13.     bdx = bs * COS(ba): bdy = bs * SIN(ba)
  14.     LOCATE 1, 1: PRINT "ma"; _R2D(ma) \ 1; "  ba"; _R2D(ba) \ 1
  15.  
  16.     bx = bx + bdx
  17.     IF bx < br THEN bx = br: bdx = -bdx
  18.     IF bx > xmax - br THEN bx = xmax - br: bdx = -bdx
  19.  
  20.     by = by + bdy
  21.     IF by < br THEN by = br: bdy = -bdy
  22.     IF by > ymax - br THEN by = ymax - br: bdy = -bdy
  23.  
  24.     ba = _ATAN2(bdy, bdx)
  25.  
  26.     WHILE _MOUSEINPUT '                                            paddle
  27.         ma = ma + _MOUSEWHEEL * P2 / 72 '5 degrees change
  28.     WEND
  29.     mx = _MOUSEX: my = _MOUSEY
  30.     mx1 = mx + mr * COS(ma)
  31.     my1 = my + mr * SIN(ma)
  32.     mx2 = mx + mr * COS(ma + P)
  33.     my2 = my + mr * SIN(ma + P)
  34.     LINE (mx1, my1)-(mx2, my2), &HFFFF8800
  35.     'draw a handle to track the side the ball is on
  36.     hx1 = mx + br * COS(ma + Pd2): hy1 = my + br * SIN(ma + Pd2)
  37.     hx2 = mx + br * COS(ma - Pd2): hy2 = my + br * SIN(ma - Pd2)
  38.     d1 = _HYPOT(hx1 - bx, hy1 - by): d2 = _HYPOT(hx2 - bx, hy2 - by)
  39.  
  40.     IF d1 < d2 THEN
  41.         LINE (hx2, hy2)-(mx, my), &HFFFF8800
  42.         paddleNormal = _ATAN2(my - hy2, mx - hx2)
  43.     ELSE
  44.         LINE (hx1, hy1)-(mx, my), &HFFFF8800
  45.         paddleNormal = _ATAN2(my - hy1, mx - hx1)
  46.     END IF
  47.  
  48.     tx = -99: ty = -99
  49.     dist = _HYPOT(bx - mx, by - my) '                             collision?
  50.     IF dist < br + mr THEN '                                     centers close enough
  51.         contacts = lineIntersectCircle%(mx1, my1, mx2, my2, bx, by, br, ix1, iy1, ix2, iy2)
  52.         IF contacts THEN PRINT "Contact"; contacts ': _DELAY .5 'OK so far
  53.         IF contacts = 1 THEN 'just touched (or passed through)
  54.             IF _HYPOT(ix1 - mx, iy1 - my) < br THEN tx = ix1: ty = iy1
  55.         ELSEIF contacts = 2 THEN
  56.             'contact point would have been in middle of 2 points
  57.             tx = (ix1 + ix2) / 2: ty = (iy1 + iy2) / 2
  58.         END IF
  59.         IF tx > 0 THEN ' rebound ball
  60.             CIRCLE (tx, ty), 2 'show contact point
  61.  
  62.             'relocate bx, by
  63.             bx = tx + br * COS(paddleNormal) 'this is where the ball would be at contact
  64.             by = ty + br * SIN(paddleNormal)
  65.  
  66.             'find the angle of reflection
  67.             ba = _ATAN2(bdy, bdx)
  68.             aReflect = ABS(paddleNormal - ba) 'apparently I have to flip the next clac by PI
  69.             IF ba < paddleNormal THEN ba = paddleNormal + aReflect + P ELSE ba = paddleNormal - aReflect + P
  70.  
  71.         END IF
  72.     END IF
  73.     CIRCLE (bx, by), br 'ball
  74.     _DISPLAY
  75.     _LIMIT 60
  76.  
  77.  
  78. ' return 0 no Intersect, 1 = tangent 1 point touch, 2 = 2 point intersect
  79. FUNCTION lineIntersectCircle% (lx1, ly1, lx2, ly2, cx, cy, r, ix1, iy1, ix2, iy2)
  80.  
  81.     'needs    SUB slopeYintersect (X1, Y1, X2, Y2, slope, Yintercept)
  82.  
  83.     IF lx1 <> lx2 THEN
  84.         slopeYintersect lx1, ly1, lx2, ly2, m, Y0 ' Y0 otherwise know as y Intersect
  85.  
  86.         ' https://math.stackexchange.com/questions/228841/how-do-i-calculate-the-intersections-of-a-straight-line-and-a-circle
  87.         A = m ^ 2 + 1
  88.         B = 2 * (m * Y0 - m * cy - cx)
  89.         C = cy ^ 2 - r ^ 2 + cx ^ 2 - 2 * Y0 * cy + Y0 ^ 2
  90.         D = B ^ 2 - 4 * A * C 'telling part of Quadratic formula = 0 then circle is tangent  or > 0 then 2 intersect points
  91.         IF D < 0 THEN ' no intersection
  92.             ix1 = -999: iy1 = -999: ix2 = -999: iy2 = -999: lineIntersectCircle% = 0
  93.         ELSEIF D = 0 THEN ' one point tangent
  94.             x1 = (-B + SQR(D)) / (2 * A)
  95.             y1 = m * x1 + Y0
  96.             ix1 = x1: iy1 = y1: ix2 = -999: iy2 = -999: lineIntersectCircle% = 1
  97.         ELSE '2 points
  98.             x1 = (-B + SQR(D)) / (2 * A): y1 = m * x1 + Y0
  99.             x2 = (-B - SQR(D)) / (2 * A): y2 = m * x2 + Y0
  100.             ix1 = x1: iy1 = y1: ix2 = x2: iy2 = y2: lineIntersectCircle% = 2
  101.         END IF
  102.     ELSE 'vertical line
  103.         IF r = ABS(lx1 - cx) THEN ' tangent
  104.             ix1 = lx1: iy1 = cy: ix2 = -999: iy2 = -999: lineIntersectCircle% = 1
  105.         ELSEIF r < ABS(lx1 - cx) THEN 'no intersect
  106.             ix1 = -999: iy1 = -999: ix2 = -999: iy2 = -999: lineIntersectCircle% = 0
  107.         ELSE '2 point intersect
  108.             ydist = SQR(r ^ 2 - (lx1 - cx) ^ 2)
  109.             ix1 = lx1: iy1 = cy + ydist: ix2 = lx1: iy2 = cy - ydist: lineIntersectCircle% = 2
  110.         END IF
  111.     END IF
  112.  
  113. SUB slopeYintersect (X1, Y1, X2, Y2, slope, Yintercept) ' fix for when x1 = x2
  114.     slope = (Y2 - Y1) / (X2 - X1)
  115.     Yintercept = slope * (0 - X1) + Y1
  116.  
  117.  
« Last Edit: March 10, 2020, 10:45:25 pm by bplus »