Finding the tangent points of a circle
Posted: Sun Jul 28, 2024 4:48 pm
I need to find the 2 tangent points of 2 intersecting lines to a circle as shown in the image.
I had to use chatgpt because i could not do it. The following code draws the circle at the correct position you can increase or decrease the radius pressing up and down keys.
How to find the tangent points marked in the image?
I had to use chatgpt because i could not do it. The following code draws the circle at the correct position you can increase or decrease the radius pressing up and down keys.
How to find the tangent points marked in the image?
Code: Select all
EnableExplicit
Structure PointD
x.d
y.d
EndStructure
Global.d g_radius
Global.PointD g_intersection, g_endPoint1, g_endPoint2
;TODO
Procedure findTangentPoint(*intersection.PointD, *endPoint.PointD, *circleCenter.PointD, radius.d, *outTangentPoint.PointD)
EndProcedure
Procedure drawCircle(*intersection.PointD, *endPoint1.PointD, *endPoint2.PointD, radius.d)
Protected.d angle1, angle2, bisectorAngle, angleDifference, distance
Protected.PointD circleCenter
;Calculate the angles formed by the lines With respect To the intersection point
angle1 = ATan2(*endPoint1\x - *intersection\x, *endPoint1\y - *intersection\y)
angle2 = ATan2(*endPoint2\x - *intersection\x, *endPoint2\y - *intersection\y)
;Find the bisector of the angle formed by the two lines
bisectorAngle = (angle1 + angle2) / 2.0
;Calculate the distance from the intersection point To the point where the circle is tangent To both lines
angleDifference = Abs(angle1 - angle2)
If angleDifference > #PI
angleDifference = 2 * #PI - angleDifference
EndIf
distance = radius / Sin(angleDifference / 2.0)
;Find the center of the circle using the bisector angle And the calculated distance
circleCenter\x = *intersection\x + distance * Cos(bisectorAngle)
circleCenter\y = *intersection\y + distance * Sin(bisectorAngle)
AddPathCircle(circleCenter\x, circleCenter\y, radius)
;TODO FIND TANGENT POINTS
Protected.PointD tangentPoint1, tangentPoint2
findTangentPoint(*intersection, *endPoint1, @circleCenter, radius, @tangentPoint1)
findTangentPoint(*intersection, *endPoint2, @circleCenter, radius, @tangentPoint2)
EndProcedure
Procedure drawCanvas(*intersection.PointD, *endPoint1.PointD, *endPoint2.PointD, radius.d)
StartVectorDrawing(CanvasVectorOutput(0))
;Clear
VectorSourceColor(RGBA(255, 255, 255, 255))
FillVectorOutput()
VectorSourceColor(RGBA(0, 0, 255, 255))
;Lines
MovePathCursor(*intersection\x, *intersection\y)
AddPathLine(*endPoint1\x, *endPoint1\y)
MovePathCursor(*intersection\x, *intersection\y)
AddPathLine(*endPoint2\x, *endPoint2\y)
StrokePath(4)
;Circle
VectorSourceColor(RGBA(255, 0, 0, 255))
drawCircle(*intersection, *endPoint1, *endPoint2, radius)
StrokePath(4)
StopVectorDrawing()
EndProcedure
Procedure onKeyDown()
If GetGadgetAttribute(0, #PB_Canvas_Key) = #PB_Shortcut_Up
g_radius + 1.0
drawCanvas(@g_intersection, @g_endPoint1, @g_endPoint2, g_radius)
ElseIf GetGadgetAttribute(0, #PB_Canvas_Key) = #PB_Shortcut_Down
g_radius - 1.0
If g_radius < 0
g_radius = 1
EndIf
drawCanvas(@g_intersection, @g_endPoint1, @g_endPoint2, g_radius)
EndIf
EndProcedure
Procedure main()
Protected.l ev
Protected.PointD intersection, endPoint1, endPoint2
g_radius = DesktopScaledX(40)
g_intersection\x = DesktopScaledX(400)
g_intersection\y = DesktopScaledY(300)
g_endPoint1\x = DesktopScaledX(500)
g_endPoint1\y = DesktopScaledY(10)
g_endPoint2\x = DesktopScaledX(600)
g_endPoint2\y = DesktopScaledY(200)
OpenWindow(0, 0, 0, 800, 600, "VectorDrawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, WindowWidth(0), WindowHeight(0), #PB_Canvas_Keyboard)
BindGadgetEvent(0, @onKeyDown(), #PB_EventType_KeyDown)
drawCanvas(@g_intersection, @g_endPoint1, @g_endPoint2, g_radius)
SetActiveGadget(0)
Repeat
ev = WaitWindowEvent()
Until ev = #PB_Event_CloseWindow
EndProcedure
main()