Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleFind the angle between two line segments
Keywordsangle, line segments
CategoriesAlgorithms, Graphics
 
The GetAngle function uses vector mathematics including dot products and cross products. Before you can understand the function, it helps to understand a little vector algebra.

A vector consists of a series of components giving a direction and a distance. You can think of the vector as an arrow: it has direction and length.

In 2 dimensions, you can write a vector as <x, y> where x and y give the vector's X and Y components. For example, the vector <2, 0> is a vector of length 2 parallel to the X axis and pointing to the right (in the positive X direction).

You can find the vector between two points by subtracting the coordinates of the points. The vector from point (x1, y1) to point (x2, y2) is:

    V = <x2 - x1, y2 - y1>

The length of a vector <x, y> is written |<x, y>| . Using the Pythagorean Theorem it is easy to show that:

    |<x, y>| = Sqr(x * x + y * y)

Dot Product

The dot product of two vectors A = <x1, y1> and B = <x2, y2> is written A · B and has the value:

    A · B = |A| * |B| * Cos(theta)

where theta is the angle between the two vectors. You can easily calculate the dot product using this equation:

    A · B = x1 * x2 + y1 * y2

The following code calculates the dot product of two vectors. The function takes as parameters the coordinates of three points A, B, and C, and finds the dot product of the vectors AB and BC.

 
' Return the dot product AB · BC.
' Note that AB · BC = |AB| * |BC| * Cos(theta).
Private Function DotProduct( _
    ByVal Ax As Single, ByVal Ay As Single, _
    ByVal Bx As Single, ByVal By As Single, _
    ByVal Cx As Single, ByVal Cy As Single _
  ) As Single
Dim BAx As Single
Dim BAy As Single
Dim BCx As Single
Dim BCy As Single

    ' Get the vectors' coordinates.
    BAx = Ax - Bx
    BAy = Ay - By
    BCx = Cx - Bx
    BCy = Cy - By

    ' Calculate the dot product.
    DotProduct = BAx * BCx + BAy * BCy
End Function
 
Cross Product

The cross product of two vectors A = <x1, y1> and B = <x2, y2> is written A × B. The result is a new vector that is prependicular to both A and B and that has length:

    |A × B| = |A| * |B| * Sin(theta)

where theta is the angle between the two vectors. You can calculate the cross product of two vectors in the X-Y plane using this equation:

    A × B = <0, 0, x1 * y2 - x2 * y1>

Note that this vector is parallel to the Z-axis. That makes sense because the vectors A and B lie in the X-Y plane and the cross product should give a vector perpendicular to both. Exercise: Calculate <1, 0> × <0, 1>. Does the result make sense?

There are similar formulas (although they are a bit more complicated) for calculating cross products in higher dimensions.

The following code calculates the cross product of two vectors and returns the length of the result.

 
' Return the cross product AB x BC.
' The cross product is a vector perpendicular to AB
' and BC having length |AB| * |BC| * Sin(theta) and
' with direction given by the right-hand rule.
' For two vectors in the X-Y plane, the result is a
' vector with X and Y components 0 so the Z component
' gives the vector's length and direction.
Public Function CrossProductLength( _
    ByVal Ax As Single, ByVal Ay As Single, _
    ByVal Bx As Single, ByVal By As Single, _
    ByVal Cx As Single, ByVal Cy As Single _
  ) As Single
Dim BAx As Single
Dim BAy As Single
Dim BCx As Single
Dim BCy As Single

    ' Get the vectors' coordinates.
    BAx = Ax - Bx
    BAy = Ay - By
    BCx = Cx - Bx
    BCy = Cy - By

    ' Calculate the Z coordinate of the cross product.
    CrossProductLength = BAx * BCy - BAy * BCx
End Function
 
Finding Angles
Now you can use the dot product and cross product to find the sine and cosine of the angle between the two vectors.

    Cos(theta) =  A · B  / (|A| * |B|)
    Sin(theta) = |A × B| / (|A| * |B|)

A little trigonometry gives you:

    Tan(theta) = Sin(theta) / Cos(theta)

So

    Tan(theta) = [|A × B| / (|A| * |B|)] / [A · B  / (|A| * |B|)]
               = |A × B| / A · B

The following routines use these facts to calculate the angle between two vectors.

 
' Return the angle with tangent opp/hyp. The returned
' value is between PI and -PI.
Public Function ATan2(ByVal opp As Single, ByVal adj As _
    Single) As Single
Dim angle As Single

    ' Get the basic angle.
    If Abs(adj) < 0.0001 Then
        angle = PI / 2
    Else
        angle = Abs(Atn(opp / adj))
    End If

    ' See if we are in quadrant 2 or 3.
    If adj < 0 Then
        ' angle > PI/2 or angle < -PI/2.
        angle = PI - angle
    End If

    ' See if we are in quadrant 3 or 4.
    If opp < 0 Then
        angle = -angle
    End If

    ' Return the result.
    ATan2 = angle
End Function

' Return the angle ABC.
' Return a value between PI and -PI.
' Note that the value is the opposite of what you might
' expect because Y coordinates increase downward.
Public Function GetAngle(ByVal Ax As Single, ByVal Ay As _
    Single, ByVal Bx As Single, ByVal By As Single, ByVal _
    Cx As Single, ByVal Cy As Single) As Single
Dim dot_product As Single
Dim cross_product As Single

    ' Get the dot product and cross product.
    dot_product = DotProduct(Ax, Ay, Bx, By, Cx, Cy)
    cross_product = CrossProductLength(Ax, Ay, Bx, By, Cx, _
        Cy)

    ' Calculate the angle.
    GetAngle = ATan2(cross_product, dot_product)
End Function
 
The book Visual Basic Graphics Programming contains more information on vector calculations used fro producing three-dimensional graphics.
 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated