Inclination – angle in radians or degrees a 2D line makes with the positive x-axis, measuring counter-clockwise. A line extends indefinitely in both directions.

In radians, 0 <= theta < pi

In degrees, 0 <= theta < 180

Slope – tangent of the inclination, y/x, rise over run.

Slope m = Tan alpha = y/x

Lines are perpendicular if their slopes are m1 = -1/m2

Tan alpha = – tan (180 – alpha)

A 3D line, a 3D vector, is determined by any two points. If one of these points is the origin, the coordinates of every point on the line form a set of direction numbers. Every line has an infinite set of direction numbers. The numbers always have the same proportions. You can get the coordinates of any point by multiplying the coordinates of some other point by some constant.

The direction angles of a 3D line are defined to be the angle the line makes directly with each of the positive axes. Knowing any two the third can be calculated. The angles are limited to 0 to 180, similar to the 2D inclination, but not limited to being counter-clockwise.

For an undirected line that extends indefinitely in both directions, there are two sets of direction angles,

theta and (180 – theta)

The basic calculation of 3D line direction is the division of the direction numbers by the length between the two points that generated that set. This gives the direction cosines, the x,y and z values for a line of length one. Multiplying the direction cosines by a constant gives a point on the same line at distance of the constant. The 3 direction angles of the line can be found with the Cos(-1) function.

For instance a line from the origin to (3,4,5) has a length of 7.07. The direction cosines are 3/7.07, 4/7.07, 5/7.07), the angle of the line to each of the axes, xyz, by calculator cos(-1), is approx 65, 55, and 45 degrees. Lets check that out with autocad and VBA.

Sub test24() Call Connect_Acad Dim x As Double, y As Double, z As Double Dim pt0() As Double pt0 = pt(0, 0, 0) Dim ptX() As Double 'pt on x axis to make alpha ucs Dim ptY() As Double 'pt on y axis to make beta ucs Dim ptZ() As Double 'pt on z axis to make gamma ucs 'i could re-use these to only have one Dim ptx2() As Double 'pt to define new x axis for alpha Dim pty2() As Double 'pt to define new x axis for beta Dim ptz2() As Double 'pt to define new x axis for gamma Dim A() As Double, B() As Double, C() As Double Dim dir_cos() As Double Dim dir_ang() As Double x = -3: y = -4: z = 5 A = pt(x, y, z) 'draw the autocad line vec_draw1 A ptX = pt(x, 0, 0) ptx2 = pt(x + 1, 0, 0) ucs ptX, ptx2, A, "ucs_alpha" ptX = pt(Abs(x), 0, 0) dim_ang pt0, ptX, A, midpt2(ptX, A) label_pt A, "A" ptY = pt(0, y, 0) pty2 = pt(0, y + 1, 0) ucs ptY, pty2, A, "ucs_beta" ptY = pt(0, Abs(y), 0) dim_ang pt0, ptY, A, midpt2(ptY, A) ptZ = pt(0, 0, z) ptz2 = pt(0, 0, z + 1) ucs ptZ, ptz2, A, "ucs_gamma" ptZ = pt(0, 0, Abs(z)) dim_ang pt0, ptZ, A, midpt2(ptZ, A) 'the box is a visual aid not always required 'Dim pt1() As Double 'pt1 = pt(x / 2, y / 2, z / 2) 'solidbox pt1, Abs(x), Abs(y), Abs(z) 'here are the calculations dir_cos = dir_cos1(A) Debug.Print "< " & x; ", " & y & ", " & z & " >" Debug.Print "alpha_cos " & dir_cos(0) Debug.Print "beta_cos " & dir_cos(1) Debug.Print "gamma_cos " & dir_cos(2) Debug.Print 'direction cosines are the xyz values where the line 'has a length of one 'put an autocad point object at those coordinates draw_pt dir_cos, "L=1" dir_ang = dir_ang1(A) Debug.Print "Alpha " & rad2deg(dir_ang(0)) Debug.Print "Beta " & rad2deg(dir_ang(1)) Debug.Print "Gamma " & rad2deg(dir_ang(2)) Debug.Print 're-set ucs to world set_wcs acadApp.Update End Sub

Call the autocad dimangular method. First the ucs is changed for each of the 3 angles. UCS requires 3 points. a new origin, a point on the new x-axis, and a point on the new y-axis. the origin is variously either (x,0,0), (0,y,0), or (0,0,z), the point on the new x-axis is variously (x+1,0,0), (0,y+1,0) or (0,0,z+1). the point on the new y-axis is always the point of the vector. that establishes a right triangle in the plane of the vector and the axis to which the angular dimension is drawn.

Sub dim_ang(pt1() As Double, pt2() As Double, pt3() As Double, pt4() As Double) Dim dimObj As AcadDimAngular 'Set dimObj = acadDoc.ModelSpace.AddDimAngular(AngleVertex, firstendpoint, secondendpoint, textpoint) Set dimObj = acadDoc.ModelSpace.AddDimAngular(pt1, pt2, pt3, pt4) End Sub

Independently of the autocad dimangular method, the direction cosines and direction angles are calculated. Since these are always triples, the most convenient way to store them is in a 3 place array of doubles, exactly as point coordinates are stored. In fact the direction cosines are the point coordinates for any line at the point where the length of the line is one. Both direction cosines and direction angles are calculated for a vector with tail at the origin. The version to calculate with tail not at the origin would simply do the subtraction of coordinates then call this version.

Function dir_cos1(pt1() As Double) As Double() Dim cos_alpha As Double, cos_beta As Double, cos_gamma As Double Dim x As Double, y As Double, z As Double Dim D As Double D = dist1(pt1) If D = 0 Then dir_cos1 = pt(0, 0, 0) Exit Function End If x = pt1(0): y = pt1(1): z = pt1(2) cos_alpha = x / D cos_beta = y / D cos_gamma = z / D dir_cos1 = pt(cos_alpha, cos_beta, cos_gamma) End Function Function dir_ang1(pt1() As Double) As Double() Dim alpha As Double, beta As Double, gamma As Double Dim dir_cos() As Double Dim pt2(0 To 2) As Double dir_cos = dir_cos1(pt1) alpha = WorksheetFunction.Acos(dir_cos(0)) beta = WorksheetFunction.Acos(dir_cos(1)) gamma = WorksheetFunction.Acos(dir_cos(2)) pt2(0) = alpha pt2(1) = beta pt2(2) = gamma dir_ang1 = pt2 End Function

testing the subroutine for values in all 8 quadrants. the angles are always measured to the positive side of the axis. therefore they are always between 0 and 180, never negative. Getting the confidence that all quadrants return true values, the next step is to develop a sub-routine that returns the angle between two lines.