Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter Follow VBHelper on Twitter
 
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleFind the tangent lines between two circles in Visual Basic .NET
DescriptionThis example shows how to find the tangent lines between two circles in Visual Basic .NET.
Keywordstangents, circle, tangent lines, geometry, graphics, algorithms, Visual Basic .NET, VB.NET
CategoriesAlgorithms, VB.NET
 

Depending on how two circles are arranged, they can have 0, 2, or 4 tangent lines. If the circles don't intersect, as on the left in Figure 1, they have 4 tangents: 2 outer tangents (blue) and 2 inner tangents (red). If the circles overlap, as shown on the right in Figure 1, they have only 2 outer tangents. If one circle contains the other, they have no tangents.

Suppose the two circles C1 and C2 have radii r1 and r2 where r2 >= r1.

To find the outer tangents, consider Figure 2. The dashed circle has the same center as C2 and radius r2 - r1. By using the example Find the tangent lines between a point and a circle in Visual Basic .NET, you can find the tangent lines between C1's center and this dashed circle. Now move that line perpendicularly to itself distance r1 to get the outer tangent shown in Figure 2. Offset the other point/circle tangent perpendicular to itself to get the other outer tangent.

To find the inner tangents, consider Figure 3. Here the dashed circle has the same center as C1 and radius r1 + r2. By again using the example Find the tangent lines between a point and a circle in Visual Basic .NET, you can find the tangent lines between C2's center and this dashed circle. Now move that line perpendicularly to itself distance r2 to get the inner tangent shown in Figure 3. Offset the other point/circle tangent perpendicular to itself to get the other inner tangent.

The basic idea here is somewhat tricky but if you stare long enough at the pictures, you should be able to see how it works. You might also try drawing some pictures of your own.

The FindCircleCircleTangents method shown in the following code uses this technique to find the tangents between two circles.

 
' Find the tangent points for these two circles.
' Return the number of tangents: 4, 2, or 0.
Private Function FindCircleCircleTangents( _
    ByVal c1 As PointF, ByVal radius1 As Single, ByVal c2 As _
        PointF, ByVal radius2 As Single, _
    ByRef outer1_p1 As PointF, ByRef outer1_p2 As PointF, _
    ByRef outer2_p1 As PointF, ByRef outer2_p2 As PointF, _
    ByRef inner1_p1 As PointF, ByRef inner1_p2 As PointF, _
    ByRef inner2_p1 As PointF, ByRef inner2_p2 As PointF) _
As Integer
    ' Make sure radius1 <= radius2.
    If (radius1 > radius2) Then
        ' Call this method switching the circles.
        Return FindCircleCircleTangents( _
            c2, radius2, c1, radius1, _
            outer1_p2, outer1_p1, _
            outer2_p2, outer2_p1, _
            inner1_p2, inner1_p1, _
            inner2_p2, inner2_p1)
    End If

    ' Initialize the return values in case
    ' some tangents are missing.
    outer1_p1 = New PointF(-1, -1)
    outer1_p2 = New PointF(-1, -1)
    outer2_p1 = New PointF(-1, -1)
    outer2_p2 = New PointF(-1, -1)
    inner1_p1 = New PointF(-1, -1)
    inner1_p2 = New PointF(-1, -1)
    inner2_p1 = New PointF(-1, -1)
    inner2_p2 = New PointF(-1, -1)

    ' ***************************
    ' * Find the outer tangents *
    ' ***************************
    Dim radius2a As Single = radius2 - radius1
    If (Not FindTangents(c2, radius2a, c1, outer1_p2, _
        outer2_p2)) Then
        ' There are no tangents.
        Return 0
    End If

    ' Get the vector perpendicular to the
    ' first tangent with length radius1.
    Dim v1x As Single = -(outer1_p2.Y - c1.Y)
    Dim v1y As Single = outer1_p2.X - c1.X
    Dim v1_length As Single = CSng(Sqrt(v1x * v1x + v1y * _
        v1y))
    v1x *= radius1 / v1_length
    v1y *= radius1 / v1_length
    ' Offset the tangent vector's points.
    outer1_p1 = New PointF(c1.X + v1x, c1.Y + v1y)
    outer1_p2 = New PointF(outer1_p2.X + v1x, outer1_p2.Y + _
        v1y)

    ' Get the vector perpendicular to the
    ' second tangent with length radius1.
    Dim v2x As Single = outer2_p2.Y - c1.Y
    Dim v2y As Single = -(outer2_p2.X - c1.X)
    Dim v2_length As Single = CSng(Sqrt(v2x * v2x + v2y * _
        v2y))
    v2x *= radius1 / v2_length
    v2y *= radius1 / v2_length
    ' Offset the tangent vector's points.
    outer2_p1 = New PointF(c1.X + v2x, c1.Y + v2y)
    outer2_p2 = New PointF(outer2_p2.X + v2x, outer2_p2.Y + _
        v2y)

    ' If the circles intersect, then there are no inner
    ' tangents.
    Dim dx As Single = c2.X - c1.X
    Dim dy As Single = c2.Y - c1.Y
    Dim dist As Double = Sqrt(dx * dx + dy * dy)
    If (dist <= radius1 + radius2) Then Return 2

    ' ***************************
    ' * Find the inner tangents *
    ' ***************************
    Dim radius1a As Single = radius1 + radius2
    FindTangents(c1, radius1a, c2, inner1_p2, inner2_p2)

    ' Get the vector perpendicular to the
    ' first tangent with length radius2.
    v1x = inner1_p2.Y - c2.Y
    v1y = -(inner1_p2.X - c2.X)
    v1_length = CSng(Sqrt(v1x * v1x + v1y * v1y))
    v1x *= radius2 / v1_length
    v1y *= radius2 / v1_length
    ' Offset the tangent vector's points.
    inner1_p1 = New PointF(c2.X + v1x, c2.Y + v1y)
    inner1_p2 = New PointF(inner1_p2.X + v1x, inner1_p2.Y + _
        v1y)

    ' Get the vector perpendicular to the
    ' second tangent with length radius2.
    v2x = -(inner2_p2.Y - c2.Y)
    v2y = inner2_p2.X - c2.X
    v2_length = CSng(Sqrt(v2x * v2x + v2y * v2y))
    v2x *= radius2 / v2_length
    v2y *= radius2 / v2_length
    ' Offset the tangent vector's points.
    inner2_p1 = New PointF(c2.X + v2x, c2.Y + v2y)
    inner2_p2 = New PointF(inner2_p2.X + v2x, inner2_p2.Y + _
        v2y)

    Return 4
End Function
 
Note that this problem is closely related to the "Belt Problem" where the goal is to calculate the length of a belt needed to connect two pulleys directly (using the outer tangents) or crossed (using the inner tangents). Sometimes the direct (external tangent) version is called the "Pulley Problem."

A couple of definitions:

  • An inner tangent is one that intersects the segment joining the circles' centers.
  • An outer tangent is one that does not intersect the segment joining the circles' centers.
  • The point where the internal tangents intersect is called the internal homeothetic center and it lies along the segment connecting the circles' centers.
  • The point where the extensions of the external tangents intersect is called the external homeothetic center and it lies along the segment connecting the circles' centers. If the circles have the same radii, then the external tangents are parallel and the external homeothetic center is at infinity.
 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated