Friday, March 24, 2017

geometry - Newbie: determine if line *segment* intersects circle

I've read related posts, including:



How to tell if a line segment intersects with a circle?
where the suggestions are probably relevant, but above my level, and the final solution is actually not what I need, and




Circle and Line segment intersection
Which may be what I need, but assumes more math knowledge than is in my brain.



Context: I have two circles in powerpoint, each of which have 8 points (anchors) on the perimeter. I am cycling through all 64 combinations in VBA to identify which two lines provide the longest point-to-point connectors that do not go through either circle. For convenience, I can check each line against each circle separately.



Basically, I am trying to create code that will allow me to automatically create something like this http://www.harrisgolfonline.com/userfiles/image/wlcc%201932%20bylaws%20callout.jpg except I'll also have a small circle around the enlarged part of the original image. I'm trying to get the math to figure out which circle anchors will give me those two outer lines.



So for example, if I draw the shortest possible line segment between the two closest connectors, I should not intersect with either circle. A line between the furthest away connectors would have to travel through both circles, and therefore fail either circle test.



Anyway, I'm hoping someone can help me with the equation setup, since the two pages I reference put in multiple equations and then say "then just solve it". I'm not exactly sure how to combine those formulas to solve. What I'm hoping for is something more like this equation, except this evaluates based on the whole line and not just a line segment:




Private Function LineCrossesCircle(x1, y1, x2, y2, cx, cy, cr) As Boolean



x1 = x1 - cx

y1 = y1 - cy

x2 = x2 - cx

y2 = y2 - cy


LineCrossesCircle = 0 <= cr ^ 2 * ((x2 - x1) ^ 2 + (y2 - y1) ^ 2) - (x1 * y2 - x2 * y1) ^ 2


End Function



Reading the answers, I do understand that there may be multiple conditions, e.g. it may be something similar to the above AND some other equation or two.



My connector points will always be on the circumference of the circle, so I was adjusting my calculated radius value to be [r*.95] otherwise they might all intersect at the endpoints. That means that my endpoints will never fall within the circles, but part of the line will fall in one or both circles probably 80% of the time. Once I find the lines that don't, I can check their lengths and add them as connectors.




Any help translating the previous solutions into one or more equations that just take the two endpoints (x1, y1, x2, y2) and circle info (cx, cy, cr) and return a boolean for whether there is an intersect would be greatly appreciated!!



===================================================================================



Sample code based on OAO's helpful post. I think I got something wrong, because it is no connectors with intersects, when I know about 80% should have an intersect.



EDIT: updated the formulas for MA and MB (I had some of the elements reversed I think) but still showing no intersects



Private Function IntersectCheck(ByVal Cx As Single, _
ByVal Cy As Single, _

ByVal Radius As Single, _
ByVal Ax As Single, _
ByVal Ay As Single, _
ByVal Bx As Single, _
ByVal By As Single) As Boolean


'distance between endpoints



d = (((Bx - Ax) ^ 2) + ((By - Ay) ^ 2)) ^ 0.5




'not totally sure what this is



alpha = (1 / (d ^ 2)) * ((Bx - Ax) * (Cx - Ax) + (Bx - Ax) * (Cx - Ax))



'point nearest circle center



mx = Ax + ((Bx - Ax) * alpha)



my = Ay + ((By - Ay) * alpha)




MC = ((Cx - mx) ^ 2 + (Cy - my) ^ 2) ^ 0.5



MA = ((Ax - mx) ^ 2 + (Ay - my) ^ 2) ^ 0.5



MB = ((Bx - mx) ^ 2 + (By - my) ^ 2) ^ 0.5



AC = ((Cx - Ax) ^ 2 + (Cy - Ay) ^ 2) ^ 0.5



BC = ((Cx - Bx) ^ 2 + (Cy - By) ^ 2) ^ 0.5




IntersectCheck = False



If MC > Radius Then



'there is no intersect



Else



If (MA < d) And (MB < d) Then


'there is an intersect

IntersectCheck = True

Else

If AC <= Radius Or BC <= Radius Then

'there is an intersect


IntersectCheck = True

End If

End If


End If




End Function

No comments:

Post a Comment

analysis - Injection, making bijection

I have injection $f \colon A \rightarrow B$ and I want to get bijection. Can I just resting codomain to $f(A)$? I know that every function i...