The Secant Challenge

Capture_10-23-2015

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

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s