10-15-2022, 04:01 AM
(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...)