# Vectors 3 This is my third try at vectors. It starts with basic vector algebra.

A vector is an ordered triple of numbers, representing the xyz coordinates of the head, the tail at 0,0,0. A vector and a point have the same structure, an array of 3 doubles. Vector algebra functions accept a vector as input and return the calculated vector. Position comes into play when we want to display the vector in autocad. (these are NOT all debugged on first draft)

Here are the elementary vector functions.
Plus (U,V) returns vector U + V
Minus (U,V) returns vector U – V
Scalar(c, U) returns vector c * U
Dot(U, V) returns double dot product
Leng(U) returns double length of vector
UnitV(U) returns unit vector along U
Dist(U, V) returns double distance between vectors
Angle(U, V) returns angle between vectors as double in radians
Ortho(U, V) returns boolean True if vectors are perpendicular
Proj(U, V) returns vector V projected on U
Neg(U) returns negative vector

Draw(vec) Draws vector in autocad as simple line

the function to create a point takes the triples input and returns the array of 3 doubles.

dim pt1() as double
pt1 = PT(1,2,3)

this is used as the basic vector creation function.

```dim u() as double
u= VEC(1,2,3)

Function vec(x As Double, y As Double, z As Double) As Double()
Dim pnt(0 To 2) As Double
pnt(0) = x: pnt(1) = y: pnt(2) = z
vec = pnt
End Function
```
```Function plus(u() As Double, v() As Double) As Double()
Dim w(0 To 2) As Double
w(0) = u(0) + v(0)
w(1) = u(1) + v(1)
w(2) = u(2) + v(2)

plus = w
End Function

Function scalar(c As Double, u() As Double) As Double()
Dim w(0 To 2) As Double
w(0) = c * u(0)
w(1) = c * u(1)
w(2) = c * u(2)

scalar = w
End Function

Function minus(u() As Double, v() As Double) As Double()
Dim w(0 To 2) As Double
w(0) = u(0) - v(0)
w(1) = u(1) - v(1)
w(2) = u(2) - v(2)

minus = w
End Function

Function dot(u() As Double, v() As Double) As Double
Dim w As Double
w = u(0) * v(0) + u(1) * v(1) + u(2) * v(2)
dot = w
End Function

Function leng(u() As Double) As Double
Dim w As Double
w = u(0) ^ 2 + u(1) ^ 2 + u(2) ^ 2
w = Sqr(w)

leng = w
End Function

Function unitv(u() As Double) As Double()
Dim w() As Double
Dim L As Double

L = leng(u)
w = scalar(1 / L, u)

unitv = w
End Function

Function dist(u() As Double, v() As Double) As Double
Dim L As Double
L = leng(minus(u, v))

dist = L
End Function

Function angle(u() As Double, v() As Double) As Double
Dim Dot_UV As Double
Dim len_U As Double
Dim len_V As Double
Dim cos_theta As Double

Dot_UV = dot(u, v)
len_U = leng(u)
len_V = leng(v)

cos_theta = Dot_UV / (len_U * len_V)

angle = WorksheetFunction.Acos(cos_theta)
End Function

Function ortho(u() As Double, v() As Double) As Boolean
Dim w As Double
w = dot(u, v)

If w = 0 Then
ortho = True
Else
ortho = False
End If
End Function

Function proj(u() As Double, v() As Double) As Double()
Dim w() As Double
Dim x As Double
Dim Dot_UV As Double
Dim Dot_UU As Double

x = Dot_UV / Dot_UU
w = scalar(x, u)

proj = w
End Function

Function neg(u() As Double) As Double()
Dim w(0 To 2) As Double
w(0) = -1 * u(0)
w(1) = -1 * u(1)
w(2) = -1 * u(2)

neg = w
End Function

```

To draw a vector in autocad, this is borrowed from the line wrapper, I kept the optional layer parameter even though i dont intend to use it much at first.

g_pt is a public point variable, same as a vector, if we set it each time, its easy to draw vectors end to end.
we could save the newly created line object the same way, and sometimes thats useful, but i removed it for now.

```
Public u() As Double
Public v() As Double
Public g_pt() As Double

Sub draw(vec() As Double, startpt() As Double, Optional strlayer As Variant)
Dim endpt() As Double

endpt = pt(vec(0) + startpt(0), vec(1) + startpt(1), vec(2) + startpt(2))

If Not IsMissing(strlayer) Then
lineobj.Layer = strlayer
End If

g_pt = endpt

End Sub
```

# Vectors in the Plane ```
Dim A() As Double, B() As Double
Dim C() As Double, D() As Double
Dim R() As Double

A = pt(4, 1, 0)
B = pt(2, -3, 0)
C = pt(-2, 2, 0)
D = pt(-3, -2, 0)

vec_draw1 A, "A"
vec_draw1 B, "B"
vec_draw1 C, "C"
vec_draw1 D, "D"

vec_draw1 R, "A+B"

vec_draw1 R, "A+C"

vec_draw1 R, "A+D"

vec_draw1 R, "A+B+C"

R = vec_add_2(1, A, 2, B)
vec_draw1 R, "A+2B"

R = vec_add_2(1, A, -3, C)
vec_draw1 R, "A-3C"

R = v_add3(A, C, v_m(1 / 3, D))
vec_draw1 R, "A+C+1/3D"

Sub vec_draw1(pt1() As Double, Optional str_text As Variant)
'line from origin to pt1

If Not IsMissing(str_text) Then
txt1 CStr(str_text), pt1, 0.25
End If
End Sub

Function v_add(pt1() As Double, pt2() As Double) As Double()
v_add = pt(pt1(0) + pt2(0), pt1(1) + pt2(1), pt1(2) + pt2(2))
End Function

'multiply scalar by vector, return vector
Function v_m(m As Double, pt1() As Double) As Double()
v_m = pt(m * pt1(0), m * pt1(1), m * pt1(2))
End Function

Function v_add3(pt1() As Double, pt2() As Double, pt3() As Double) As Double()
v_add3 = pt(pt1(0) + pt2(0) + pt3(0), pt1(1) + pt2(1) + pt3(1), pt1(2) + pt2(2) + pt3(2))
End Function

'add 2 vectors each multiplied by a scalar, A-B would be vec_add_2(1, A, -1, B)
Function vec_add_2(m As Double, pt1() As Double, n As Double, pt2() As Double) As Double()
Dim temp1() As Double,  temp2() As Double
temp1 = v_m(m, pt1)
temp2 = v_m(n, pt2)

End Function

```

it would be possible to do this on one line but it would be hard to read.

```Dim temp1() As Double, temp2() As Double

temp1 = vec_add_2(2, A, -3, B)
temp2 = vec_add_2(-3, C, 4, D)
vec_draw1 R, "2A-3B-3C+4D"
```

Length and Direction – ```Function vec_len(pt1() As Double) As Double
Dim x As Double, y As Double, z As Double
x = pt1(0): y = pt1(1): z = pt1(2)
vec_len = (x ^ 2 + y ^ 2 + z ^ 2) ^ (1 / 2)
End Function
```

Dividing a vector by the length (multiplying by the inverse of the length) produces a vector with length one in the same direction – The angle of a 2D vector is a directed line measured from the positive X axis. It takes a value between 0 and 360 degrees not including 360 or 0 and 2 pi not including 2 pi. The inverse tangent is used with y/x as argument. Tangent returns an angle for an undirected line between -90 to +90 or -pi/2 to +pi/2. The code is a bit tedious but its pretty straightforward. We have to trap out zero values of x, to avoid divide by zero, then check for zeros of y and interpret, then retrieve the value for the inverse tangent and interpret according to which quadrant the head of the vector is in.

```Function vec_ang(pt1() As Double) As Double
'check for zero length vector return 0 for angle
Dim x As Double, y As Double

x = pt1(0)
y = pt1(1)

If x = 0 And y = 0 Then
vec_ang = 0
Exit Function
End If

'get axis directions
If x = 0 Or y = 0 Then
If y = 0 And x > 0 Then vec_ang = 0
If x = 0 And y > 0 Then vec_ang = Pi / 2
If y = 0 And x < 0 Then vec_ang = Pi
If x = 0 And y < 0 Then vec_ang = 3 * Pi / 2
Exit Function
End If

'calculate m tangent
Dim m As Double
m = y / x

If x > 0 And y > 0 Then  'First Q
vec_ang = Atn(m)
End If

If x < 0 And y > 0 Then  'Second Q
vec_ang = Pi + Atn(m)
End If

If x < 0 And y < 0 Then  'Third Q
vec_ang = Pi + Atn(m)
End If

If x > 0 And y < 0 Then  'Fourth Q
vec_ang = 2 * Pi + Atn(m)
End If

End Function
```  ```
Sub vec_draw3(startpt1() As Double, vectorpt2() As Double, Optional str_text As Variant)
'line from startpoint at vector distance and angle
Dim pt3() As Double

If Not IsMissing(str_text) Then
txt1 CStr(str_text), pt1, 0.25
End If
End Sub
```

triangles with random vertexes and medians – (I moved them after the program drew them) ```
Sub vec_draw2(pt1() As Double, pt2() As Double, Optional str_text As Variant)
'simple line from pt1 to pt2