The Dot Product

Autocad does not have a 3D arc command and its kind of wild how hard it is to draw an arc on a sphere. I think we can do it, but there is a lot of theory involved, which is good because its fun and what else were you going to do? Googling the problem, the best solution I saw (which i won’t use here) was “ProjectGeometry” where a line drawn from point to point on the sphere is projected onto the solid sphere object and converted to an arc. I did not spend a lot of time looking for it, but I am not sure if that method is available in activeX. Its not an object type. Its a command, a written program in autocad, so its a manual technique. Although possibly you could use sendcommand or something similar.

To draw an arc on a sphere – two endpoints, center and radius will be the givens. Two vectors from 0,0,0 to the endpoints are drawn. The dot product, also called the scalar product of two vectors, has all the theory we need to construct a new ucs in the plane of the vectors and the arc we want to draw. Its a math topic in a beginning vectors class. The dot product is a calculation that projects a perpendicular from one vector to the other. The point that it touches becomes the origin of the new ucs. The new x-axis is defined by the endpoint of the vector, and the new y-axis is defined by the projecting vector endpoint. The 3 points must form a right angle, which they do. The dot product also gives us the included angle between the vectors, just from the endpoint coordinates. very nice.

There is no way to draw an arc that is not parallel to the current ucs, so you have to change the ucs. However all the other data that goes into creating an arc stays tied to the World ucs, as far as drawing in activeX is concerned. If you are drawing manually, autocad accomodates your desire to draw in the new ucs. 0,0,0 typed in at the command line is interpreted to be the new ucs origin. Activex generally ignores the ucs, except as it defines the drawing plane.

Draw an arc with any method then look at the arc in the properties window to see what data is read/write and what is grayed out. You can edit the center xyz coordinates, the radius, the start and end angle. Thats all. Those are the exact same prompts the activex addarc requires. Moving the center moves it parallel to its plane of creation. If the other data are changed, the shape of the curve is changed and new endpoints are calculated by autocad, but it stays parallel to the plane it was made in.

Startangle is a hard problem. With the dot product, we can calculate the included angle from the endpoints. We know the center and the radius. The startangle for the arc is not the angle from the current ucs. It is not the angle projected onto the world ucs. With 2D vectors, there is only one reference angle, the angle from the vector to the positive X axis. In the 2D plane autocad measures angles from the positive x-axis. The angle of a 3D vector is defined by the angle from the vector directly to each positive axis. The angle to the X-axis is called the Alpha angle. In the tilted ucs I did not see what the logic of startangle was. I drew an arc with startangle zero, and the arc touched down on the world x-axis. The startangle is the vector direction angle Alpha from the new x-axis directly to the world x-axis. But it is not that simple either. My vectors were 5,5,5 and -5,5,5. They were symmetrical across the z-axis, which made an alpha projection hit the x-axis. If the ucs has another twist, the alpha angle will extend to where it breaks the xy plane apparently.

I need to find the intersection of the ucs with the world xy plane. The only way i know how to do it right now is to draw an arc with startangle 0 and see where it starts. Pretty sure its a solvable problem.

(actually have ny and la backwards labeled. my latitude longtitude converter is not handling east west correctly, the arclength came out correct)

Sub A_scalar_dot_B(x1 As Double, y1 As Double, z1 As Double, x2 As Double, y2 As Double, z2 As Double)

Dim ptA() As Double
Dim ptB() As Double

Dim A_dot_B As Double
Dim len_A As Double
Dim len_B As Double
Dim cos_theta As Double
Dim theta As Double
Dim theta_deg As Double

Dim A_unit_vector() As Double
Dim A_unit_x As Double
Dim A_unit_y As Double
Dim A_unit_z As Double

Dim B_unit_vector() As Double
Dim B_unit_x As Double
Dim B_unit_y As Double
Dim B_unit_z As Double

Dim scalar_B_on_A As Double
Dim scalar_A_on_B As Double

Dim pt_scalar_B_on_A() As Double

ptA = pt(x1, y1, z1)
ptB = pt(x2, y2, z2)

A_dot_B = x1 * x2 + y1 * y2 + z1 * z2
len_A = (x1 ^ 2 + y1 ^ 2 + z1 ^ 2) ^ (1 / 2)
len_B = (x2 ^ 2 + y2 ^ 2 + z2 ^ 2) ^ (1 / 2)
cos_theta = A_dot_B / (len_A * len_B)
theta = WorksheetFunction.Acos(cos_theta)
theta_deg = rad2deg(theta)

A_unit_x = x1 / len_A
A_unit_y = y1 / len_A
A_unit_z = z1 / len_A

B_unit_x = x2 / len_B
B_unit_y = y2 / len_B
B_unit_z = z2 / len_B

scalar_B_on_A = len_B * cos_theta
scalar_A_on_B = len_A * cos_theta

pt_scalar_B_on_A = pt(A_unit_x * scalar_B_on_A, A_unit_y * scalar_B_on_A, A_unit_z * scalar_B_on_A)

ucs pt_scalar_B_on_A, ptA, ptB, "wow"

Debug.Print theta_deg

public_theta_deg = theta_deg

End Sub

Sub testconv()
Call Connect_Acad
  pt0 = pt(0, 0, 0)
 
  set_ucs 0, 0, 0, 1, 0, 0, 0, 1, 0, "world"
 
 pt1 = conv(40.713, 74.006, 3963)  'NEW YORK
 pt2 = conv(34.052, 118.244, 3963)  'LOS ANGELES
  'CONV IS PRELIMINARY
  
 line1 pt0, pt1
 line1 pt0, pt2
 
  Call A_scalar_dot_B(pt1(0), pt1(1), pt1(2), pt2(0), pt2(1), pt2(2))
  
  Dim r As Double
  r = 3963  'RADIUS IN MILES
     
     Dim alpha As Double
     alpha = 85.727
    ' alpha = 0
    'try 0, measure and input value
     
  arc1 pt0, r, alpha, alpha + public_theta_deg

Debug.Print pt1(0)
Debug.Print pt1(1)
Debug.Print pt1(2)

Debug.Print pt2(0)
Debug.Print pt2(1)
Debug.Print pt2(2)

acadApp.Update

End Sub
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.