The Secant challenge is the problem of plotting the infinitely large y values as the graph approaches an undefined point, then plotting the same situation only negative on the other side of the point, while skipping over the undefined point. Its the same problem for Tangent, Cotangent, Secant and Cosecant.

There are at least 3 approaches.

Since the graph is not continuous, a single polyline cannot be used. The collection of points has to be divided into separate arrays. A test has to be made to limit the length of lines and to recognize when the asymptote is crossed. This is an array challenge.

Instead of drawing a polyline, a normal line can be drawn. All the line segments can be added to a selection set and the selection set can be converted to polylines after the fact. Apparently vba does not have the methods to convert and join lines to polyline, so the “sendcommand” technique has to be used. This would be a fairly complex autocad challenge.

The lines can be drawn and converted to polylines manually through the autocad interface.

A fairly sophisticated lisp program can be run in the autocad interface to convert and join lines to polylines.

Excel programmers should always accept array challenges, but we also need to be able to just draw lines. We will draw the lines and leave the polyline conversion and the array work for later.

We will use the classic algebra distance formula to test and limit the length of lines drawn. This is the pythagorean right triangle rule, the sum of the squares of the two lesser sides is equal to the square of the hypotenuse.

Sub testdistance()

Dim d As Double

d = distance(-2, 1, 1, 5)

MsgBox d

End Sub

Function distance(X1 As Double, Y1 As Double, X2 As Double, Y2 As Double) As Double

distance = ((X2 – X1) ^ 2 + (Y2 – Y1) ^ 2) ^ (1 / 2)

End Function

In our program we will calculate the length of the line before drawing it, compared to a value taken from a form, that the user can change. If the line is too long, the program will just skip it. It has to be a line drawn across an asymptote or a line unsuitably long drawn alongside an asymptote. Max_l is the number taken from the form.

If distance(X1, Y1, X2, Y2) < max_l Then

Call line(X1, Y1, X2, Y2)

End If

There is an occasional divide by zero error, usually only when the starting point of the graph is zero, but just in case we need to check for error number 11, divide by zero.

Sub fnf_tan(a As Double, b As Double, max_l As Double) 'Xmin, Xmax, X_inc already set 'Y = a * Tan(b * X) Dim X1 As Double, Y1 As Double Dim X2 As Double, Y2 As Double Dim i As Integer Dim n As Integer 'number of line segments n = (Xmax - Xmin) / X_inc 'number of line segments For i = 1 To n X1 = Xmin + ((i - 1) * X_inc) Y1 = a * Tan(b * X1) X2 = Xmin + (i * X_inc) Y2 = a * Tan(b * X2) If distance(X1, Y1, X2, Y2) < max_l Then Call line(X1, Y1, X2, Y2) End If Next Update strLabel = "Y= " & a & "* Tan " & b & "X" End Sub Sub fnf_cot(a As Double, b As Double, max_l As Double) 'Xmin, Xmax, X_inc already set 'Y = a * (1 / Tan(b * X)) Dim X1 As Double, Y1 As Double Dim X2 As Double, Y2 As Double Dim i As Integer Dim n As Integer 'number of line segments On Error GoTo errtrap n = (Xmax - Xmin) / X_inc 'number of line segments For i = 1 To n X1 = Xmin + ((i - 1) * X_inc) Y1 = a * (1 / Tan(b * X1)) X2 = Xmin + (i * X_inc) Y2 = a * (1 / Tan(b * X2)) If distance(X1, Y1, X2, Y2) < max_l Then Call line(X1, Y1, X2, Y2) End If Next Update strLabel = "Y= " & a & "* Cot " & b & "X" errtrap: If Err.Number = 11 Then 'division by zero error Y1 = 1000 'just set y out of range Y2 = 1000 'where the distance formula will reject it MsgBox "div by zero" 'its rare but we should know to check results End If Resume Next End Sub Sub fnf_sec(a As Double, b As Double, max_l As Double) 'Xmin, Xmax, X_inc already set 'Y = a * (1 / Cos(b * X)) Dim X1 As Double, Y1 As Double Dim X2 As Double, Y2 As Double Dim i As Integer Dim n As Integer 'number of line segments On Error GoTo errtrap n = (Xmax - Xmin) / X_inc 'number of line segments For i = 1 To n X1 = Xmin + ((i - 1) * X_inc) Y1 = a * (1 / Cos(b * X1)) X2 = Xmin + (i * X_inc) Y2 = a * (1 / Cos(b * X2)) If distance(X1, Y1, X2, Y2) < max_l Then Call line(X1, Y1, X2, Y2) End If Next Update strLabel = "Y= " & a & "* Sec " & b & "X" errtrap: If Err.Number = 11 Then 'division by zero error Y1 = 1000 Y2 = 1000 MsgBox "div by zero" End If Resume Next End Sub Sub fnf_csc(a As Double, b As Double, max_l As Double) 'Xmin, Xmax, X_inc already set 'Y = a * (1 / Sin(b * X)) Dim X1 As Double, Y1 As Double Dim X2 As Double, Y2 As Double Dim i As Integer Dim n As Integer 'number of line segments On Error GoTo errtrap n = (Xmax - Xmin) / X_inc 'number of line segments For i = 1 To n X1 = Xmin + ((i - 1) * X_inc) Y1 = a * (1 / Sin(b * X1)) X2 = Xmin + (i * X_inc) Y2 = a * (1 / Sin(b * X2)) If distance(X1, Y1, X2, Y2) < max_l Then Call line(X1, Y1, X2, Y2) End If Next Update strLabel = "Y= " & a & "* Csc " & b & "X" errtrap: If Err.Number = 11 Then 'division by zero error Y1 = 1000 Y2 = 1000 MsgBox "div by zero" End If Resume Next End Sub