Author Topic: Find Azimuth of a 3d vector  (Read 14639 times)

0 Members and 1 Guest are viewing this topic.

Troy Williams

  • Guest
Find Azimuth of a 3d vector
« on: August 15, 2005, 01:31:11 PM »
Hi all, I have a little problem that is mostly solved except one small piece.

I have a line defined in 3D. I want to determine the azimuth of this line relative to the line's start point in the plane defined by the normal (0,0,1) and the point (0,0,0). The plane is the xy plane. The azimuth would be measured from the vector (0,1,0) in the xy plane.

Here is how I get the angle
Code: [Select]

N is the normal of the plane (0,0,1)
P is the line that I am working with. It has coordinates Psx,Psy,Psz and Pex,Pey,Pez. where Ps refers to the starting point and Pe refers to the end point.

V is a vector in the direction of P. Vx = Pex-Psx;Vy = Pey-Psy;Vz = Pez-Psz

Now, project V onto the xy plane:
U = V - (V.N)*N; where V.N is the dot product

Now we have a vector in the xy plane, we can find the angle of the this vector and the vector M (0,1,0) which defines North.

To determine the angle:

theta = arccos(U.M/(|U|*|M|))


The problem that I am having is that theta will be the acute angle between  the two vectors. In other words, if I have a line that should be 270 degrees, the calculation will report back 90 degrees.

Troy Williams

  • Guest
Find Azimuth of a 3d vector
« Reply #1 on: August 15, 2005, 02:20:15 PM »
I think that I need to take the determinant of the vectors involved in order to figure out what way the angle is measured from.

Code: [Select]

N = 0,0,1; this is the direction of the normal describing the xy plane
M = 0,1,0; This vector defines north
U = Ux,Uy,Uz; this is the vector that I want to find the angle of relative to M

For an example, lets say U = -1,1,0; this would put the vector in the 2nd quadrant and it should have an angle of 315 degrees. If I use the procedure in my last post I get an angle of 45 degrees.

Now if I find the determinant of:

|-1 1 0|
| 0 1 0|  = -1
| 0 0 1|

I believe, according to the sign that the angle has been calculated the wrong way. So If I take 360 and subtract 45 I arrive at 315 degrees. Which is what I want.



Say I used U=2,2,0 which is 45 degrees, I would get

| 2 2 0|
| 0 1 0|  = 2
| 0 0 1|

The positive result would indicate that I do not need a correction.

If the result is 0, it means that the vectors are parallel.


I have looked all over the place and I can't seem to find an answer (or at least one that I understand). I believe taking the determint of the 3 vectors and checking the sign of the result is the correct way to go. I have tested the results for a number of cases and in each case it seems to work. I haven't changed the plane that I am working in or the direction of the north vector.

Can any verify this for me or am I doing things incorrectly?

cad-waulader

  • Guest
Find Azimuth of a 3d vector
« Reply #2 on: August 15, 2005, 02:57:09 PM »
how about this:
Defining a northern azimuth as the number of degrees measured clockwise from due north, calc the delta x and delta y of your line.  forget delta z.  Impose the origin of an xy grid upon the start of your line, and see in which quadrant your line resides.  Depending on which quadrant that is, apply different rules to calculate the azimuth:
Quadrant I:
  azimuth = arctan (delta x/delta y)
Quadrant II:
 azimuth = arctan (delta x / delta y) + 360°
Quadrant III or IV: azimuth = arctan (delta x / delta y)  + 180°

Troy Williams

  • Guest
Find Azimuth of a 3d vector
« Reply #3 on: August 15, 2005, 03:08:55 PM »
Quote from: cad-waulader
how about this:
Defining a northern azimuth as the number of degrees measured clockwise from due north, calc the delta x and delta y of your line.  forget delta z.  Impose the origin of an xy grid upon the start of your line, and see in which quadrant your line resides.  Depending on which quadrant that is, apply different rules to calculate the azimuth:
Quadrant I:
  azimuth = arctan (delta x/delta y)
Quadrant II:
 azimuth = arctan (delta x / delta y) + 360°
Quadrant III or IV: azimuth = arctan (delta x / delta y)  + 180°


Thanks for the reply cad-waulader.

Thank you for your approach. I have used a similar method when calculating underground drill hole angles and it worked well (however I like your method better).

I will probably use your approach, but I am still wondering if I was out to lunch in my last post in regard to the determinant?

cad-waulader

  • Guest
Find Azimuth of a 3d vector
« Reply #4 on: August 15, 2005, 03:17:34 PM »
Have to consult the books on that one...  vector calcs are kept in the rusty/dusty side of my brain.

Troy Williams

  • Guest
Find Azimuth of a 3d vector
« Reply #5 on: August 15, 2005, 03:28:15 PM »
Quote from: cad-waulader
vector calcs are kept in the rusty/dusty side of my brain.


Tell me about it  :wink:  I should have paid more attention in school. I never thought I would be working with them so extensively.


From some of the texts I am currently reading, the determinant as I have done it in my previous post is the signed volume of a parallelepiped. The signed volume means that it indicates the direction of sweep. I believe that this can tell me which way the angle was calculated. I have done quite a few tests and they seem to confirm my suspicions.

Anyway, I will probably mock up some vba for autocad to confirm my calculations. I'll post my results plus the macro sometime tomorrow, if anyone is interested.

Troy Williams

  • Guest
Find Azimuth of a 3d vector
« Reply #6 on: August 16, 2005, 08:51:33 AM »
If anyone is interested here is the code that I came up with. It is written in VBA for AutoCAD. It seems to work as I would expect it to. Just copy and paste it into an empty module.


Code: [Select]

Option Explicit
Private Const x As Integer = 0
Private Const y As Integer = 1
Private Const z As Integer = 2
Private Const PI As Double = 3.14159

Public Sub findAzimuth()
Dim pickedEntity As AcadEntity
Dim pickedPoint As Variant
Dim myLine As AcadLine

ThisDrawing.Utility.GetEntity pickedEntity, pickedPoint, "Please select a line: " & vbCr

If pickedEntity Is Nothing Then Exit Sub

If TypeOf pickedEntity Is AcadLine Then
    Set myLine = pickedEntity
Else
    ThisDrawing.Utility.Prompt vbCrLf & "Be sure to select a line next time!" & vbCr
    Exit Sub
End If

Dim N(2) As Double 'the normal of the plane
Dim M(2) As Double 'the direction of the azimuth line
Dim v(2) As Double 'the vector representing the line
Dim U(2) As Double 'the projection of V onto the plane

N(x) = 0
N(y) = 0
N(z) = 1

M(x) = 0
M(y) = 1
M(z) = 0

v(x) = myLine.EndPoint(x) - myLine.StartPoint(x)
v(y) = myLine.EndPoint(y) - myLine.StartPoint(y)
v(z) = myLine.EndPoint(z) - myLine.StartPoint(z)

Dim dpResult As Double 'dot product result

dpResult = dotProduct(v, N)
U(x) = v(x) - dpResult * N(x)
U(y) = v(y) - dpResult * N(y)
U(z) = v(z) - dpResult * N(z)

Dim theta As Double
Dim dpVectorNormal As Double
Dim vectMagnitude As Double

vectMagnitude = (vectorMagnitude(U) * vectorMagnitude(M)) 'pre-calculate this value - if it is zero, are angle calculation is greatly simplified

If vectMagnitude > 0 Then
    dpVectorNormal = dotProduct(U, M) 'calculate the dot product of the projected vector and the azimuth vector
   
    theta = aCos(dpVectorNormal / vectMagnitude)
   
    'now we need to figure out which way the angle was measured from
    Dim D As Double
    D = determinant(U, M, N)
   
    If D < 0 Then
        theta = 2 * PI - theta
    End If
Else
    'the hole looks vertical in that plane
    theta = 0
End If

'convert the angle to degrees
theta = theta * 180 / PI

ThisDrawing.Utility.Prompt vbCr & "The Azimuth is: " & theta

Set myLine = Nothing
Set pickedEntity = Nothing
End Sub

Private Function determinant(v1 As Variant, v2 As Variant, v3 As Variant) As Double
'this will calculate the 3x3 determinant of the passed vectors
'v1(x),v1(y),v1(z)
'v2(x),v2(y),v2(z)
'v3(x),v3(y),v3(z)

Dim a As Double
Dim b As Double
Dim c As Double

a = v1(x) * (v2(y) * v3(z) - v2(z) * v3(y))
b = v1(y) * (v2(x) * v3(z) - v2(z) * v3(x))
c = v1(z) * (v2(x) * v3(y) - v2(y) * v3(x))

determinant = a - b + c
End Function

Private Function aCos(v As Double) As Double
aCos = Atn(-v / Sqr(-v * v + 1)) + 2 * Atn(1)
End Function

Private Function vectorMagnitude(v As Variant) As Double
    vectorMagnitude = v(x) * v(x) + v(y) * v(y) + v(z) * v(z)
    vectorMagnitude = Sqr(vectorMagnitude)
End Function

Private Function dotProduct(v1 As Variant, v2 As Variant) As Double
dotProduct = v1(0) * v2(0) + v1(1) * v2(1) + v1(2) * v2(2)
End Function

t-bear

  • Guest
Find Azimuth of a 3d vector
« Reply #7 on: August 16, 2005, 09:36:49 AM »
Looks great!  I haven't got the first clue .......but it looks great! :dood:  :mrgreen:

Troy Williams

  • Guest
Find Azimuth of a 3d vector
« Reply #8 on: August 16, 2005, 09:54:58 AM »
Quote from: t-bear
Looks great!  I haven't got the first clue .......but it looks great! :dood:  :mrgreen:


If you run it in autocad, it'll ask you to pick a line. It will then tell you the azimuth of that line. It assumes that you want the azimuth of the line as if it were projected onto the xy plane (plan view) and it assumes that the positive y axis is North.

There are a number of optimizations that could be made to make it faster, but I didn't make them because it may obscure how some of the math works.

t-bear

  • Guest
Find Azimuth of a 3d vector
« Reply #9 on: August 16, 2005, 11:17:55 AM »
Thanks Troy........I'm a mechanical type who has never had cause to need an azimuth......thought it was sum'pin like athsma....


OK....not funny....

SwiftGuest

  • Guest
Find Azimuth of a 3d vector
« Reply #10 on: August 16, 2005, 03:10:56 PM »
Troy, Looks alright to me
Swift

Troy Williams

  • Guest
Find Azimuth of a 3d vector
« Reply #11 on: August 16, 2005, 03:21:50 PM »
Hey Swift, great to see you found this place!