Line Intersect Circle
BlitzMax Forums/BlitzMax Beginners Area/Line Intersect Circle
| ||
hi! someone can help me to find a function to detect if a line collide with a circle ? (and determine intersection points?) please helpme !!! I have tried various methods but they are slow... help! |
| ||
To find if the line intersects the circle, just take the point at the center of the circle, use the point distance to line formula and then check if that distance is less than the radius of the circle. |
| ||
Pretty sure I posted some code for this in the main BMax forum. Check back a page or two. |
| ||
Thought I'd have a go at the challenge, so after thinking through the algebra on a piece of paper, how about something like this: Basically you pass any two points on the line, the center of the circle, and the radius to GetIntersectionLineCircle() and the function will return the points of intersection (if there are any). I've added a timer, so you can see how fast it is... On my Intel Core 2 Duo 2.00Ghz, it takes approx 0.002ms to find the two points of intersection! Who say's high school maths doesn't come in handy? |
| ||
thanks guys! @SebHoll wow! |
| ||
I've added this to the code archives in case anybody else needs to use it. |
| ||
@SebHoll I have tried the code, but I think there is something that doesn't work with the recognition of the collision... try this code... thanks SuperStrict Local tmpIntersectLineCircle#[][] Graphics 640, 480, 0 Local mx:Float, my: Float While Not KeyHit(key_escape) Cls SetColor(50, 200, 100) DrawCircle(320, 240, 40) mx = MouseX() my = MouseY() SetColor(50, 70, 222) DrawLine(0,0, mx, my) tmpIntersectLineCircle = GetIntersectionLineCircle( [0.0,0.0], [mx, my], [320.0, 240.0], 40.0 ) If tmpIntersectLineCircle.length = 1 SetColor(255, 0,0) DrawCircle(tmpIntersectLineCircle[0][0], tmpIntersectLineCircle[0][1], 4) EndIf If tmpIntersectLineCircle.length = 2 SetColor(255,50,30) DrawText "COLLISION", 290, 20 SetColor(255, 0,0) DrawCircle(tmpIntersectLineCircle[1][0], tmpIntersectLineCircle[1][1], 4) DrawCircle(tmpIntersectLineCircle[0][0], tmpIntersectLineCircle[0][1], 4) EndIf Flip 0 Wend Function DrawCircle(xCentre:Float, yCentre:Float, Radius:Float) DrawOval(xCentre - (Radius), yCentre - (Radius), Radius * 2, Radius * 2) End Function Function GetIntersectionLineCircle#[][]( pLineStart#[], pLineEnd#[], pCircleCenter#[], pCircleRadius# ) Local tmpIntersections#[][] Local p# = pCircleCenter[0], q# = pCircleCenter[1] Local m# = (pLineEnd[1]-pLineStart[1])/(pLineEnd[0]-pLineStart[0]) Local r# = pCircleRadius Local t# = pLineEnd[1]- (m*pLineEnd[0]) Local s# = t-q Local a# = m*m + 1, b# = (2*m*s) - (2*p), c# = s^2 + p^2 - (r^2) 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 |
| ||
has anyone gotten this detection working with vertical or near vertical lines? this returns more inaccurate the closer the line is to vertical and nothing at all for a vertical line. |
| ||
Hiya, I tried the code and it does suffer from bad vertical intersections. I didn't bother to try fix it as I had this on my h/drive which gives much more information... If you can't understand how to use it then let me know and I'll help you out. Move the line with W,S,A,D and the mouse. Last edited 2012 |
| ||
Hey! Thanks so much for this, seems to work awesomely! the command Var makes those input values update globaly? never knew that... o.0 should be simple enough to incorporate. :D |
| ||
the command Var makes those input values update globaly? never knew that... o.0 Using Var will pass the variable by pointer, or by reference - whatever people choose to call it these days. So altering the value of the variable in the 'called function' will also alter the same variable in the 'calling function'. This can help reduce the use of real Global variables. I dont think you actually need it in this example, as you are passing objects in such as a type or an array as these are passed to a function by reference anyway, but it's there for completeness and understanding when you read the code 6 months later :P A good use is when you want to return more than one value from the function : bit of a pain as a function can only return one value. Say you have 2 or 3 Local variables in one function that you want altered by another function. Instead of making them Globals, put those variable into the parameters of the function using Var on the end, alter them in the 'called function' and they are also altered in the 'calling code' too. |
| ||
yeah, stuff I should have known for years lol. thanks again. |