Code archives/Algorithms/GetIntersectionLineCircle()
This code has been declared by its author to be Public Domain code.
Download source code
| These function will return the points of intersection (if there are any) for any line and any circle. Please note that all values passed to and from the function are floating point. GetIntersectionLineCircle(): Returns points of intersection for any line which passes through the points specified. GetIntersectionLineCircle2(): Returns points of interesection for a line that starts and ends at the points given. Note: This function requires GetIntersectionLineCircle() in order to run. The parameters are as follows: pLineStart#[] - Any point on the line that's being tested, e.g. [3.0,5.0]. pLineEnd#[] - Any other point on the line that's being tested, e.g. [1.0, 3.0] pCircleCenter#[] - The center of the circle that's being tested, e.g. [1.5, 3.5] pCircleRadius# - The radius of the circle that's being tested, e.g. 5.2 . It's worth noting that the two points passed must be different, otherwise there could be an infinite number of lines running through them. Credit goes to GregBUG for the sample code that shows these functions working. |
SuperStrict
Local tmpIntersectLineCircle#[][]
Local mx:Float, my: Float, mode:Int = 2
Graphics 640, 480, 0
While Not (KeyHit(key_escape) Or AppTerminate())
Cls
SetColor(50, 200, 100);DrawCircle(320, 240, 40)
mx = MouseX();my = MouseY()
SetColor(50, 70, 222);DrawLine(0,0, mx, my)
SetColor(255,50,30)
DrawText "No. of Collisions: " + tmpIntersectLineCircle.length, (GraphicsWidth()-TextWidth("No. of Collisions: "))/2, 20
If (mode=1) Then
DrawText("Using GetIntersectionLineCircle()",(GraphicsWidth()-TextWidth("Using GetIntersectionLineCircle()"))/2,5)
tmpIntersectLineCircle = GetIntersectionLineCircle( [0.0,0.0], [mx, my], [320.0, 240.0], 40.0 )
ElseIf (mode=2) Then
DrawText("Using GetIntersectionLineCircle2()",(GraphicsWidth()-TextWidth("Using GetIntersectionLineCircle2()"))/2,5)
tmpIntersectLineCircle = GetIntersectionLineCircle2( [0.0,0.0], [mx, my], [320.0, 240.0], 40.0 )
EndIf
SetColor(255, 0,0)
For Local tmpIntersectionPoint#[] = EachIn tmpIntersectLineCircle
DrawCircle(tmpIntersectionPoint[0], tmpIntersectionPoint[1], 4)
Next
SetColor(255,255,255)
DrawText("[F1] Use GetIntersectionLineCircle()", GraphicsWidth()-TextWidth("[F1] Use GetIntersectionLineCircle()"),GraphicsHeight()-(TextHeight("A")*2))
DrawText("[F2] Use GetIntersectionLineCircle2()", GraphicsWidth()-TextWidth("[F2] Use GetIntersectionLineCircle2()"),GraphicsHeight()-TextHeight("A"))
If KeyHit(KEY_F1) Then mode = 1
If KeyHit(KEY_F2) Then mode = 2
Flip 1
Wend
Function GetIntersectionLineCircle#[][]( pLinePoint1#[], pLinePoint2#[], pCircleCenter#[], pCircleRadius# )
Local tmpIntersections#[][]
Local p# = pCircleCenter[0], q# = pCircleCenter[1]
Local m# = (pLinePoint2[1]-pLinePoint1[1])/(pLinePoint2[0]-pLinePoint1[0])
Local r# = pCircleRadius
Local t# = pLinePoint2[1]- (m*pLinePoint2[0])
Local s# = t-q
Local a# = m*m + 1, b# = (2*m*s) - (2*p), c# = (s*s) + (p*p) - (r*r)
Local bsqminfourac# = b*b-4*a*c
If bsqminfourac > 0 Then
bsqminfourac = Sqr(bsqminfourac)
Local x1# = ((-b)+bsqminfourac)/(2*a)
Local x2# = ((-b)-bsqminfourac)/(2*a)
tmpIntersections = [[x1,(m*x1)+t],[x2,(m*x2)+t]]
ElseIf bsqminfourac = 0 Then
tmpIntersections = [[(-b)/(2*a),(-b*m)/(2*a)+t]]
EndIf
Return tmpIntersections
EndFunction
Function GetIntersectionLineCircle2#[][]( pLineStart#[], pLineEnd#[], pCircleCenter#[], pCircleRadius# )
Local tmpResult#[][]
Local tmpIntersectLineCircle#[][] = GetIntersectionLineCircle( pLineStart, pLineEnd, pCircleCenter, pCircleRadius )
Local minX# = Min(pLineStart[0],pLineEnd[0]), maxX# = Max(pLineStart[0],pLineEnd[0])
Local minY# = Min(pLineStart[1],pLineEnd[1]), maxY# = Max(pLineStart[1],pLineEnd[1])
For Local tmpIntersectionPoint#[] = EachIn tmpIntersectLineCircle
If tmpIntersectionPoint[0] < maxX And tmpIntersectionPoint[0] > minX And ..
tmpIntersectionPoint[1] < maxY And tmpIntersectionPoint[1] > minY Then
tmpResult = tmpResult + [tmpIntersectionPoint]
EndIf
Next
Return tmpResult
EndFunction
Function DrawCircle(xCentre:Float, yCentre:Float, Radius:Float)
DrawOval(xCentre - (Radius), yCentre - (Radius), Radius * 2, Radius * 2)
EndFunction |