QB64 Phoenix Edition
Angle Collisions - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://qb64phoenix.com/forum/forumdisplay.php?fid=3)
+---- Forum: Help Me! (https://qb64phoenix.com/forum/forumdisplay.php?fid=10)
+---- Thread: Angle Collisions (/showthread.php?tid=972)

Pages: 1 2 3 4 5 6 7 8 9 10


Angle Collisions - james2464 - 10-15-2022

Just wondering as I am still trying to better understand collisions, if anyone here would be interested in shedding some light on this subject.

I'm currently trying to get my mind around the idea of angular collision responses.   Specifically if a moving ball is to collide with odd angled surfaces (2D only).   Looking into this, I've discovered yet again that my math skills are nearly zero, so this could perhaps be easy for others here.   Or maybe it's difficult - I don't know.   

Vectors are at play here and apparently the math involves multiplying vectors, which is new to me.   The "dot product" seems to be the way to do this, rather than using degrees and more code.   But honestly it's a bit confusing to me at this point. 

So just to illustrate the idea...if the ball in this scenario was bouncing off these walls, would this be a nightmare to program?   Or is this not as bad as it seems?
Code: (Select All)
Screen _NewImage(800, 600, 32)

Randomize Timer
Dim c1 As Long
c1 = _RGB(255, 255, 255)

x1 = 50
y1 = 50
flag = 0
While flag = 0
    x2 = (Rnd * 80) + 80 + x1
    If x2 > 750 Then
        x2 = 750
        flag = 1
    End If
    y2 = Rnd * 60 + 20
    Line (x1, y1)-(x2, y2), c1
    x1 = x2
    y1 = y2
Wend

flag = 0
While flag = 0
    y2 = (Rnd * 80) + 80 + y1
    If y2 > 550 Then
        y2 = 550
        flag = 1
    End If
    x2 = 750 - (Rnd * 60 + 20)
    Line (x1, y1)-(x2, y2), c1
    x1 = x2
    y1 = y2
Wend

flag = 0
While flag = 0
    x2 = x1 - ((Rnd * 80) + 80)
    If x2 < 50 Then
        x2 = 50
        flag = 1
    End If
    y2 = 550 - (Rnd * 60 + 20)
    Line (x1, y1)-(x2, y2), c1
    x1 = x2
    y1 = y2
Wend

flag = 0
While flag = 0
    y2 = y1 - ((Rnd * 80) + 80)
    If y2 < 50 Then
        y2 = 50
        flag = 1
    End If
    x2 = Rnd * 60 + 20
    If flag = 1 Then x2 = 50
    Line (x1, y1)-(x2, y2), c1
    x1 = x2
    y1 = y2
Wend

Circle (400, 300), 10, c1



RE: Angle Collisions - bplus - 10-15-2022

It might get a little hairy with all the lines but according to ball location you'd only have to check one line, maybe?

Here is study with a ball and angled paddle, uses LineIntersectCircle code:
Code: (Select All)
_Title "Angle Paddle Test, mouse wheel down is clockwise" 'b+ started 2020-03-08  from _vince idea
Const xmax = 800, ymax = 600, xc = 400, yc = 300
Dim Shared P, P2, Pd2
P = _Pi: P2 = 2 * P: Pd2 = P / 2
Screen _NewImage(xmax, ymax, 32)
_Delay .2 'need time for screen to load before attempting to move it.
_ScreenMove _Middle
Randomize Timer

bx = xc: by = yc: br = 20: bs = 5: ba = _D2R(60)
mr = 50: ma = 0
While _KeyDown(27) = 0

    Line (0, 0)-(xmax, ymax), &H10000000, BF
    bdx = bs * Cos(ba): bdy = bs * Sin(ba)
    Locate 1, 1: Print "ma"; _R2D(ma) \ 1; "  ba"; _R2D(ba) \ 1

    bx = bx + bdx
    If bx < br Then bx = br: bdx = -bdx
    If bx > xmax - br Then bx = xmax - br: bdx = -bdx

    by = by + bdy
    If by < br Then by = br: bdy = -bdy
    If by > ymax - br Then by = ymax - br: bdy = -bdy

    ba = _Atan2(bdy, bdx)

    While _MouseInput '                                            paddle
        ma = ma + _MouseWheel * P2 / 72 '5 degrees change
    Wend
    mx = _MouseX: my = _MouseY
    mx1 = mx + mr * Cos(ma)
    my1 = my + mr * Sin(ma)
    mx2 = mx + mr * Cos(ma + P)
    my2 = my + mr * Sin(ma + P)
    Line (mx1, my1)-(mx2, my2), &HFFFF8800
    'draw a handle to track the side the ball is on
    hx1 = mx + br * Cos(ma + Pd2): hy1 = my + br * Sin(ma + Pd2)
    hx2 = mx + br * Cos(ma - Pd2): hy2 = my + br * Sin(ma - Pd2)
    d1 = _Hypot(hx1 - bx, hy1 - by): d2 = _Hypot(hx2 - bx, hy2 - by)

    If d1 < d2 Then
        Line (hx2, hy2)-(mx, my), &HFFFF8800
        paddleNormal = _Atan2(my - hy2, mx - hx2)
    Else
        Line (hx1, hy1)-(mx, my), &HFFFF8800
        paddleNormal = _Atan2(my - hy1, mx - hx1)
    End If

    tx = -99: ty = -99
    dist = _Hypot(bx - mx, by - my) '                             collision?
    If dist < br + mr Then '                                     centers close enough
        contacts = lineIntersectCircle%(mx1, my1, mx2, my2, bx, by, br, ix1, iy1, ix2, iy2)
        If contacts Then Print "Contact"; contacts ': _DELAY .5 'OK so far
        If contacts = 1 Then 'just touched (or passed through)
            If _Hypot(ix1 - mx, iy1 - my) < br Then tx = ix1: ty = iy1
        ElseIf contacts = 2 Then
            'contact point would have been in middle of 2 points
            tx = (ix1 + ix2) / 2: ty = (iy1 + iy2) / 2
        End If
        If tx > 0 Then ' rebound ball
            Circle (tx, ty), 2 'show contact point

            'relocate bx, by
            bx = tx + br * Cos(paddleNormal) 'this is where the ball would be at contact
            by = ty + br * Sin(paddleNormal)

            'find the angle of reflection
            ba = _Atan2(bdy, bdx)
            aReflect = Abs(paddleNormal - ba) 'apparently I have to flip the next clac by PI
            If ba < paddleNormal Then ba = paddleNormal + aReflect + P Else ba = paddleNormal - aReflect + P

        End If
    End If
    Circle (bx, by), br 'ball
    _Display
    _Limit 60
Wend


' return 0 no Intersect, 1 = tangent 1 point touch, 2 = 2 point intersect
Function lineIntersectCircle% (lx1, ly1, lx2, ly2, cx, cy, r, ix1, iy1, ix2, iy2)

    'needs    SUB slopeYintersect (X1, Y1, X2, Y2, slope, Yintercept)

    If lx1 <> lx2 Then
        slopeYintersect lx1, ly1, lx2, ly2, m, Y0 ' Y0 otherwise know as y Intersect

        ' https://math.stackexchange.com/questions/228841/how-do-i-calculate-the-intersections-of-a-straight-line-and-a-circle
        A = m ^ 2 + 1
        B = 2 * (m * Y0 - m * cy - cx)
        C = cy ^ 2 - r ^ 2 + cx ^ 2 - 2 * Y0 * cy + Y0 ^ 2
        D = B ^ 2 - 4 * A * C 'telling part of Quadratic formula = 0 then circle is tangent  or > 0 then 2 intersect points
        If D < 0 Then ' no intersection
            ix1 = -999: iy1 = -999: ix2 = -999: iy2 = -999: lineIntersectCircle% = 0
        ElseIf D = 0 Then ' one point tangent
            x1 = (-B + Sqr(D)) / (2 * A)
            y1 = m * x1 + Y0
            ix1 = x1: iy1 = y1: ix2 = -999: iy2 = -999: lineIntersectCircle% = 1
        Else '2 points
            x1 = (-B + Sqr(D)) / (2 * A): y1 = m * x1 + Y0
            x2 = (-B - Sqr(D)) / (2 * A): y2 = m * x2 + Y0
            ix1 = x1: iy1 = y1: ix2 = x2: iy2 = y2: lineIntersectCircle% = 2
        End If
    Else 'vertical line
        If r = Abs(lx1 - cx) Then ' tangent
            ix1 = lx1: iy1 = cy: ix2 = -999: iy2 = -999: lineIntersectCircle% = 1
        ElseIf r < Abs(lx1 - cx) Then 'no intersect
            ix1 = -999: iy1 = -999: ix2 = -999: iy2 = -999: lineIntersectCircle% = 0
        Else '2 point intersect
            ydist = Sqr(r ^ 2 - (lx1 - cx) ^ 2)
            ix1 = lx1: iy1 = cy + ydist: ix2 = lx1: iy2 = cy - ydist: lineIntersectCircle% = 2
        End If
    End If
End Function

Sub slopeYintersect (X1, Y1, X2, Y2, slope, Yintercept) ' fix for when x1 = x2
    slope = (Y2 - Y1) / (X2 - X1)
    Yintercept = slope * (0 - X1) + Y1
End Sub

PS I am not using vectors formally and physics might not be perfect but looks OK to me.

Update: just discovered glitch when paddle is 270 degrees, probably dividing by 0 somewhere.


RE: Angle Collisions - james2464 - 10-15-2022

(10-15-2022, 02:16 AM)bplus Wrote: It might get a little hairy with all the lines but according to ball location you'd only have to check one line, maybe?

Here is study with a ball and angled paddle, uses LineIntersectCircle code:
Code: (Select All)
_Title "Angle Paddle Test, mouse wheel down is clockwise" 'b+ started 2020-03-08  from _vince idea
Const xmax = 800, ymax = 600, xc = 400, yc = 300
Dim Shared P, P2, Pd2
P = _Pi: P2 = 2 * P: Pd2 = P / 2
Screen _NewImage(xmax, ymax, 32)
_Delay .2 'need time for screen to load before attempting to move it.
_ScreenMove _Middle
Randomize Timer

bx = xc: by = yc: br = 20: bs = 5: ba = _D2R(60)
mr = 50: ma = 0
While _KeyDown(27) = 0

    Line (0, 0)-(xmax, ymax), &H10000000, BF
    bdx = bs * Cos(ba): bdy = bs * Sin(ba)
    Locate 1, 1: Print "ma"; _R2D(ma) \ 1; "  ba"; _R2D(ba) \ 1

    bx = bx + bdx
    If bx < br Then bx = br: bdx = -bdx
    If bx > xmax - br Then bx = xmax - br: bdx = -bdx

    by = by + bdy
    If by < br Then by = br: bdy = -bdy
    If by > ymax - br Then by = ymax - br: bdy = -bdy

    ba = _Atan2(bdy, bdx)

    While _MouseInput '                                            paddle
        ma = ma + _MouseWheel * P2 / 72 '5 degrees change
    Wend
    mx = _MouseX: my = _MouseY
    mx1 = mx + mr * Cos(ma)
    my1 = my + mr * Sin(ma)
    mx2 = mx + mr * Cos(ma + P)
    my2 = my + mr * Sin(ma + P)
    Line (mx1, my1)-(mx2, my2), &HFFFF8800
    'draw a handle to track the side the ball is on
    hx1 = mx + br * Cos(ma + Pd2): hy1 = my + br * Sin(ma + Pd2)
    hx2 = mx + br * Cos(ma - Pd2): hy2 = my + br * Sin(ma - Pd2)
    d1 = _Hypot(hx1 - bx, hy1 - by): d2 = _Hypot(hx2 - bx, hy2 - by)

    If d1 < d2 Then
        Line (hx2, hy2)-(mx, my), &HFFFF8800
        paddleNormal = _Atan2(my - hy2, mx - hx2)
    Else
        Line (hx1, hy1)-(mx, my), &HFFFF8800
        paddleNormal = _Atan2(my - hy1, mx - hx1)
    End If

    tx = -99: ty = -99
    dist = _Hypot(bx - mx, by - my) '                             collision?
    If dist < br + mr Then '                                     centers close enough
        contacts = lineIntersectCircle%(mx1, my1, mx2, my2, bx, by, br, ix1, iy1, ix2, iy2)
        If contacts Then Print "Contact"; contacts ': _DELAY .5 'OK so far
        If contacts = 1 Then 'just touched (or passed through)
            If _Hypot(ix1 - mx, iy1 - my) < br Then tx = ix1: ty = iy1
        ElseIf contacts = 2 Then
            'contact point would have been in middle of 2 points
            tx = (ix1 + ix2) / 2: ty = (iy1 + iy2) / 2
        End If
        If tx > 0 Then ' rebound ball
            Circle (tx, ty), 2 'show contact point

            'relocate bx, by
            bx = tx + br * Cos(paddleNormal) 'this is where the ball would be at contact
            by = ty + br * Sin(paddleNormal)

            'find the angle of reflection
            ba = _Atan2(bdy, bdx)
            aReflect = Abs(paddleNormal - ba) 'apparently I have to flip the next clac by PI
            If ba < paddleNormal Then ba = paddleNormal + aReflect + P Else ba = paddleNormal - aReflect + P

        End If
    End If
    Circle (bx, by), br 'ball
    _Display
    _Limit 60
Wend


' return 0 no Intersect, 1 = tangent 1 point touch, 2 = 2 point intersect
Function lineIntersectCircle% (lx1, ly1, lx2, ly2, cx, cy, r, ix1, iy1, ix2, iy2)

    'needs    SUB slopeYintersect (X1, Y1, X2, Y2, slope, Yintercept)

    If lx1 <> lx2 Then
        slopeYintersect lx1, ly1, lx2, ly2, m, Y0 ' Y0 otherwise know as y Intersect

        ' https://math.stackexchange.com/questions/228841/how-do-i-calculate-the-intersections-of-a-straight-line-and-a-circle
        A = m ^ 2 + 1
        B = 2 * (m * Y0 - m * cy - cx)
        C = cy ^ 2 - r ^ 2 + cx ^ 2 - 2 * Y0 * cy + Y0 ^ 2
        D = B ^ 2 - 4 * A * C 'telling part of Quadratic formula = 0 then circle is tangent  or > 0 then 2 intersect points
        If D < 0 Then ' no intersection
            ix1 = -999: iy1 = -999: ix2 = -999: iy2 = -999: lineIntersectCircle% = 0
        ElseIf D = 0 Then ' one point tangent
            x1 = (-B + Sqr(D)) / (2 * A)
            y1 = m * x1 + Y0
            ix1 = x1: iy1 = y1: ix2 = -999: iy2 = -999: lineIntersectCircle% = 1
        Else '2 points
            x1 = (-B + Sqr(D)) / (2 * A): y1 = m * x1 + Y0
            x2 = (-B - Sqr(D)) / (2 * A): y2 = m * x2 + Y0
            ix1 = x1: iy1 = y1: ix2 = x2: iy2 = y2: lineIntersectCircle% = 2
        End If
    Else 'vertical line
        If r = Abs(lx1 - cx) Then ' tangent
            ix1 = lx1: iy1 = cy: ix2 = -999: iy2 = -999: lineIntersectCircle% = 1
        ElseIf r < Abs(lx1 - cx) Then 'no intersect
            ix1 = -999: iy1 = -999: ix2 = -999: iy2 = -999: lineIntersectCircle% = 0
        Else '2 point intersect
            ydist = Sqr(r ^ 2 - (lx1 - cx) ^ 2)
            ix1 = lx1: iy1 = cy + ydist: ix2 = lx1: iy2 = cy - ydist: lineIntersectCircle% = 2
        End If
    End If
End Function

Sub slopeYintersect (X1, Y1, X2, Y2, slope, Yintercept) ' fix for when x1 = x2
    slope = (Y2 - Y1) / (X2 - X1)
    Yintercept = slope * (0 - X1) + Y1
End Sub

PS I am not using vectors formally and physics might not be perfect but looks OK to me.

Update: just discovered glitch when paddle is 270 degrees, probably dividing by 0 somewhere.

Thanks, I'll study this code!

In the meantime I've found a bit of vector basics help:  https://youtu.be/sXKiAKn0WCM

And I had bookmarked this earlier:  http://www.3dkingdoms.com/weekly/weekly.php?a=2

(My problem is I don't understand this stuff...)


RE: Angle Collisions - James D Jarvis - 10-15-2022

I experimented a little, I didn't get the complete results I hoped for... but something happens a little like you'd hope, some of the time. I had to make the lines at the boundaries fatter so they wouldn't get missed too often while the program looked for them so the line drawing to do that is in there too.  

Code: (Select All)
'caveball
ms& = _NewImage(800, 600, 32)
border& = _NewImage(800, 600, 32)
Randomize Timer
Dim c1 As Long
Dim klr As _Unsigned Long
Dim empty As _Unsigned Long
Screen border&
c1 = _RGB(255, 255, 255)
x1 = 50
y1 = 50
flag = 0
While flag = 0
    x2 = (Rnd * 80) + 80 + x1
    If x2 > 750 Then
        x2 = 750
        flag = 1
    End If
    y2 = Rnd * 60 + 20
    fatline x1, y1, x2, y2, 2, c1
    x1 = x2
    y1 = y2
Wend

flag = 0
While flag = 0
    y2 = (Rnd * 80) + 80 + y1
    If y2 > 550 Then
        y2 = 550
        flag = 1
    End If
    x2 = 750 - (Rnd * 60 + 20)
    fatline x1, y1, x2, y2, 2, c1
    x1 = x2
    y1 = y2
Wend

flag = 0
While flag = 0
    x2 = x1 - ((Rnd * 80) + 80)
    If x2 < 50 Then
        x2 = 50
        flag = 1
    End If
    y2 = 550 - (Rnd * 60 + 20)
    fatline x1, y1, x2, y2, 2, c1
    x1 = x2
    y1 = y2
Wend

flag = 0
While flag = 0
    y2 = y1 - ((Rnd * 80) + 80)
    If y2 < 50 Then
        y2 = 50
        flag = 1
    End If
    x2 = Rnd * 60 + 20
    If flag = 1 Then x2 = 50
    fatline x1, y1, x2, y2, 2, c1
    x1 = x2
    y1 = y2
Wend
bx = 400
by = 400
speed = 2
Screen ms&

bang = 11
Do
    _Limit 60
    Cls
    _PutImage , border&, ms&
    bang = bang + bm
    bx = bx + speed * Cos(0.01745329 * bang)
    by = by + speed * Sin(0.01745329 * bang)
    bm = 0
    For bv = bang - 120 To bang + 120 Step 10
        checkx = bx + (12 * bang / bv) * Cos(0.01745329 * bv)
        checky = by + (12 * bang / bv) * Sin(0.01745329 * bv)
        klr = Point(checkx, checky)

        If klr = c1 And bm = 0 Then

            bm = bm + bv

            ' bx = bx + 2 * Cos(0.01745329 * bang)
            'by = by + 2 * Sin(0.01745329 * bang)
        End If
    Next

    Circle (bx, by), 10, c1
    _Display
    kk$ = InKey$




Loop Until kk$ = Chr$(27)







Sub circleBF (cx As Long, cy As Long, r As Long, klr As _Unsigned Long)
    rsqrd = r * r
    y = -r
    While y <= r
        x = Sqr(rsqrd - y * y)
        Line (cx - x, cy + y)-(cx + x, cy + y), klr, BF
        y = y + 1
    Wend
End Sub

Sub fatline (x0, y0, x1, y1, r, klr As _Unsigned Long)
    If Abs(y1 - y0) < Abs(x1 - x0) Then
        If x0 > x1 Then
            lineLow x1, y1, x0, y0, r, klr

        Else
            lineLow x0, y0, x1, y1, r, klr
        End If
    Else
        If y0 > y1 Then
            lineHigh x1, y1, x0, y0, r, klr
        Else
            lineHigh x0, y0, x1, y1, r, klr
        End If
    End If
End Sub
Sub lineLow (x0, y0, x1, y1, r, klr As _Unsigned Long)
    dx = x1 - x0
    dy = y1 - y0
    yi = 1
    If dy < 0 Then
        yi = -1
        dy = -dy
    End If
    'D = (2 * dy) - dx
    d = (dy + dy) - dx
    y = y0
    For x = x0 To x1
        circleBF x, y, r, klr

        If d > 0 Then
            y = y + yi
            ' D = D + (2 * (dy - dx))
            d = d + ((dy - dx) + (dy - dx))
        Else
            ' D = D + 2 * dy
            d = d + dy + dy
        End If
    Next x
End Sub
Sub lineHigh (x0, y0, x1, y1, r, klr As _Unsigned Long)
    dx = x1 - x0
    dy = y1 - y0
    xi = 1
    If dx < 0 Then
        xi = -1
        dx = -dx
    End If
    ' D = (2 * dx) - dy
    D = (dx + dx) - dy
    x = x0
    For y = y0 To y1
        circleBF x, y, r, klr

        If D > 0 Then
            x = x + xi
            ' D = D + (2 * (dx - dy))
            D = D + ((dx - dy) + (dx - dy))
        Else
            ' D = D + 2 * dx
            D = D + dx + dx
        End If
    Next y
End Sub



RE: Angle Collisions - Pete - 10-15-2022

The first time I tried it, the ball got stuck in the Florida pan handle. The second time, somewhere in Texas. Isn't it supposed to keep going until ESC?

I only noticed one area of "overlap" where it looked like part of the ball crossed the boundary.

Over-all, pretty neat irregular collision detection technique.

Pete


RE: Angle Collisions - James D Jarvis - 10-15-2022

It is odd the way it just hangs every now and again. Not sure how'd that happen, maybe the spots it checks end up switching back and forth across the line?


RE: Angle Collisions - Pete - 10-16-2022

It's a problem with your numbers exceeding type limits. The variable bang never gets lowered, it only goes higher until it errors out.

For fun, I reset the variable to zero, to make a race track simulation...

Code: (Select All)
DIM bv AS _INTEGER64
'caveball
ms& = _NEWIMAGE(800, 600, 32)
border& = _NEWIMAGE(800, 600, 32)
RANDOMIZE TIMER
DIM c1 AS LONG
DIM klr AS _UNSIGNED LONG
DIM empty AS _UNSIGNED LONG
SCREEN border&
c1 = _RGB(255, 255, 255)
x1 = 50
y1 = 50
flag = 0
WHILE flag = 0
    x2 = (RND * 80) + 80 + x1
    IF x2 > 750 THEN
        x2 = 750
        flag = 1
    END IF
    y2 = RND * 60 + 20
    fatline x1, y1, x2, y2, 2, c1
    x1 = x2
    y1 = y2
WEND

flag = 0
WHILE flag = 0
    y2 = (RND * 80) + 80 + y1
    IF y2 > 550 THEN
        y2 = 550
        flag = 1
    END IF
    x2 = 750 - (RND * 60 + 20)
    fatline x1, y1, x2, y2, 2, c1
    x1 = x2
    y1 = y2
WEND

flag = 0
WHILE flag = 0
    x2 = x1 - ((RND * 80) + 80)
    IF x2 < 50 THEN
        x2 = 50
        flag = 1
    END IF
    y2 = 550 - (RND * 60 + 20)
    fatline x1, y1, x2, y2, 2, c1
    x1 = x2
    y1 = y2
WEND

flag = 0
WHILE flag = 0
    y2 = y1 - ((RND * 80) + 80)
    IF y2 < 50 THEN
        y2 = 50
        flag = 1
    END IF
    x2 = RND * 60 + 20
    IF flag = 1 THEN x2 = 50
    fatline x1, y1, x2, y2, 2, c1
    x1 = x2
    y1 = y2
WEND
bx = 400
by = 400
speed = 2
SCREEN ms&

bang = 11
DO
    _LIMIT 60
    CLS
    LOCATE 1, 1: PRINT bx; by; bv; "    ";
    _PUTIMAGE , border&, ms&
    bang = bang + bm
    bx = bx + speed * COS(0.01745329 * bang)
    by = by + speed * SIN(0.01745329 * bang)
    bm = 0
    FOR bv = bang - 120 TO bang + 120 STEP 10
        checkx = bx + (12 * bang / bv) * COS(0.01745329 * bv)
        checky = by + (12 * bang / bv) * SIN(0.01745329 * bv)
        klr = POINT(checkx, checky)

        IF klr = c1 AND bm = 0 THEN
            bm = bm + bv
        END IF
    NEXT
    bang = 0 ' JUST FOR FUR RACE TRACK EFFECT...

    CIRCLE (bx, by), 10, c1
    _DISPLAY
    kk$ = INKEY$

LOOP UNTIL kk$ = CHR$(27)


SUB circleBF (cx AS LONG, cy AS LONG, r AS LONG, klr AS _UNSIGNED LONG)
    rsqrd = r * r
    y = -r
    WHILE y <= r
        x = SQR(rsqrd - y * y)
        LINE (cx - x, cy + y)-(cx + x, cy + y), klr, BF
        y = y + 1
    WEND
END SUB

SUB fatline (x0, y0, x1, y1, r, klr AS _UNSIGNED LONG)
    IF ABS(y1 - y0) < ABS(x1 - x0) THEN
        IF x0 > x1 THEN
            lineLow x1, y1, x0, y0, r, klr

        ELSE
            lineLow x0, y0, x1, y1, r, klr
        END IF
    ELSE
        IF y0 > y1 THEN
            lineHigh x1, y1, x0, y0, r, klr
        ELSE
            lineHigh x0, y0, x1, y1, r, klr
        END IF
    END IF
END SUB
SUB lineLow (x0, y0, x1, y1, r, klr AS _UNSIGNED LONG)
    dx = x1 - x0
    dy = y1 - y0
    yi = 1
    IF dy < 0 THEN
        yi = -1
        dy = -dy
    END IF
    'D = (2 * dy) - dx
    d = (dy + dy) - dx
    y = y0
    FOR x = x0 TO x1
        circleBF x, y, r, klr

        IF d > 0 THEN
            y = y + yi
            ' D = D + (2 * (dy - dx))
            d = d + ((dy - dx) + (dy - dx))
        ELSE
            ' D = D + 2 * dy
            d = d + dy + dy
        END IF
    NEXT x
END SUB
SUB lineHigh (x0, y0, x1, y1, r, klr AS _UNSIGNED LONG)
    dx = x1 - x0
    dy = y1 - y0
    xi = 1
    IF dx < 0 THEN
        xi = -1
        dx = -dx
    END IF
    ' D = (2 * dx) - dy
    D = (dx + dx) - dy
    x = x0
    FOR y = y0 TO y1
        circleBF x, y, r, klr

        IF D > 0 THEN
            x = x + xi
            ' D = D + (2 * (dx - dy))
            D = D + ((dx - dy) + (dx - dy))
        ELSE
            ' D = D + 2 * dx
            D = D + dx + dx
        END IF
    NEXT y
END SUB

Jut get rid of my bang = 0 ' JUST FOR FUR RACE TRACK EFFECT... and watch the counter I put in. When it errors, it displays a bogus scientific number notation, and the ball freezes.

I hope that is of some help.

Pete


RE: Angle Collisions - james2464 - 10-16-2022

Thanks for taking a shot at this....I think it's safe to say that I'm very much in over my head with this.

I've been searching all over for the answers and the info I keep getting is "if you don't understand this, go back to the earlier lesson".   And I'm almost at the point of just looking up 'vector' in the dictionary  Sad


Your program does very much demonstrate the idea, so thanks again!

This video explains the reflection of a vector, but I don't know what 'n' is. At 10:27 he says "don't forget if n is unit length you know that n.n is 1 and you can cross that out". But there are still more n's in the formula and I can't figure out what they are supposed to represent. He just said n=1 !! Or n.n = 1 anyway. I just wish there were numbers involved instead of just letters. That would be a huge help.

https://youtu.be/naaeH1qbjdQ


RE: Angle Collisions - Pete - 10-16-2022

Hmm, _INTEGER64 fixes the freezing problem, but now we have a problem with the ball escaping when that type is exceeded. I tried to reset the numbers, but it is unclear to me the point that needs to be done. I tried one fix, and it worked for awhile and then the ball moved in other directions that did not trigger the reset.

More testing and we are getting warmer, but I'm seeing other instances where that refresh line I put in simply isn't called. It needs to be called every time a directional change occurs. I'm not quite seeing what we need for that, yet.

Pete


RE: Angle Collisions - bplus - 10-16-2022

OK I worked up a demo of bouncing a circle around the insides of polygons.

I am not using point for collision detection but actual code that checks line (segment) intersections with circles.

I use regular polygons about a central point for easy normal line angles perpendicular to polygon boundary lines that point to center.

https://qb64phoenix.com/forum/showthread.php?tid=967&pid=7950#pid7950