y = 1 / x

the graph of y = 1 / x  is non-continuous and has values approaching infinity as x approaches zero. Being able to graph this would bring the autocad graphing calculator program to a successful 1.0 release state.

Using a continuous pline from x=-6 to x=6, with an x increment of 0.1, near zero, x in left column, y value in right. 

-0.2 -5
-0.1 -10
3.33067E-16 3.0024E+15
0.1 10
0.2 5

 

Capture_12-22-2015_2the vertical line does not belong and should not be drawn. The graph extends upward to a value of y= 3,002,399,751,580,331 , which i believe is the next number past trillion.

By rights we should get a divide by zero error. But we do not in this case due to the floating point inaccuracy.Capture_12-22-2015_3

Our normal graph is made with  an autocad polyline that takes an array of doubles representing x and y values. This point list array pt() can also be used to draw individual lines, where it is easier to filter out unwanted values, such as inconveniently large numbers, and the segment across the undefined value, in this case x=0.  If the generation of the point data and the application to the autocad graphic command are separated into modular sub-routines, we can introduce a drawmode the user can select.  Another easy feature to have is a command button to erase the previous graph.

the loop to create the points accepts the empty array as as argument. An array passed as an argument is passed by reference – the called program modifies the array in the calling program. The array filled with data is then available to the calling program to implement the array with various routines.

the modes look like this, with Pline as default


Sub rect_draw_mode()
With frm_rect.cbo_draw_mode
.AddItem "PLine"
.AddItem "Lines"
.AddItem "LinesWLimits"
.AddItem "Points"
.Value = "PLine"
End With
End Sub

the loop is stripped of everything except the generation of the points


Sub loop_rect(funcname As String, ByRef pt() As Double)
Dim x As Double, Y As Double
Dim i As Integer, numpts As Integer

numpts = (Xmax - xmin) / x_inc 'number of line segments
numpts = numpts + 1 'one more pt than line segment
ReDim pt(1 To numpts * 2) 'store x and y for one pt

For i = 1 To numpts
x = xmin + ((i - 1) * x_inc)
Y = Application.Run(funcname, x)
pt(i * 2 - 1) = x: pt(i * 2) = Y
Next i
End Sub

other loop subroutines are used for Polar and Parametric coordinate graphing.

a typical calling program initiated directly from a form button –


Sub draw_c02()
On Error Resume Next
Call init_rect
funcname = "C_02"

A = frm_rect.txt_a2.Value
B = frm_rect.txt_b2.Value
C = frm_rect.txt_c2.Value
strLabel = "Y= " & A & "X^2 + " & B & "X + " & C

Dim pt() As Double
Call loop_rect(funcname, pt)
Call finish_draw(pt)
End Sub

the error handler “resume next” allows the input values to be blank which defaults to zero values.

the initialization that gathers form values –


Sub init_rect()
xmin = frm_rect.txt_xmin
Xmax = frm_rect.txt_xmax
x_inc = frm_rect.txt_xinc

xlim = frm_rect.txt_Xlim
ylim = frm_rect.txt_Ylim
Drawmode = frm_rect.cbo_draw_mode.Value

If frm_rect.chkbox_excel_table = True Then
bln_excelmode = True
Else
bln_excelmode = False
End If

If frm_rect.chkbox_label_graph = True Then
bln_labelmode = True
Else
bln_labelmode = False
End If

A = 0
B = 0
C = 0
D = 0
E = 0
F = 0
End Sub

the final draw sequence which takes the point list array as argument and directs it to be implemented by whichever drawmode routine the user has requested on the form.


Sub finish_draw(pt() As Double)
Select Case Drawmode
Case "PLine"
Call draw_pline(pt)
Case "Lines"
Call draw_lines(pt)
Case "LinesWLimits"
Call draw_lines_wlimits(xlim, ylim, pt)
Case "Points"
Call draw_points(pt)
End Select

If bln_labelmode Then
label_graph
End If

If bln_excelmode Then
Call display_pt2(pt)
End If
End Sub

the sub-routines to draw either Pline, Lines, Lines with Limits, or Point objects –


'most common option after constructing pt array of point data
Sub draw_pline(ByRef pt() As Double)
Dim plineobj As AcadLWPolyline
Set plineobj = acadDoc.ModelSpace.AddLightWeightPolyline(pt)
Update
End Sub

Sub draw_lines(ByRef pt() As Double)
Dim lineobj As AcadLine
Dim i As Integer, numpts As Integer, numlines As Integer
Dim x1 As Double, x2 As Double, y1 As Double, y2 As Double
Dim pt1(0 To 2) As Double
Dim pt2(0 To 2) As Double

numpts = UBound(pt) / 2
numlines = numpts - 1

For i = 1 To numlines
x1 = pt(i * 2 - 1)
y1 = pt(i * 2)
x2 = pt(i * 2 + 1)
y2 = pt(i * 2 + 2)

pt1(0) = x1: pt1(1) = y1: pt1(2) = 0
pt2(0) = x2: pt2(1) = y2: pt2(2) = 0
Set lineobj = acadApp.ActiveDocument.ModelSpace.AddLine(pt1, pt2)

Next i
Update
End Sub

Sub draw_lines_wlimits(xlim As Double, ylim As Double, ByRef pt() As Double)
Dim lineobj As AcadLine
Dim i As Integer, numpts As Integer, numlines As Integer
Dim x1 As Double, x2 As Double, y1 As Double, y2 As Double
Dim pt1(0 To 2) As Double
Dim pt2(0 To 2) As Double

numpts = UBound(pt) / 2
numlines = numpts - 1

For i = 1 To numlines
x1 = pt(i * 2 - 1)
y1 = pt(i * 2)
x2 = pt(i * 2 + 1)
y2 = pt(i * 2 + 2)

If Abs(x1) < xlim And Abs(y1) < ylim And Abs(x2) < xlim And Abs(y2) < ylim Then
pt1(0) = x1: pt1(1) = y1: pt1(2) = 0
pt2(0) = x2: pt2(1) = y2: pt2(2) = 0
Set lineobj = acadApp.ActiveDocument.ModelSpace.AddLine(pt1, pt2)
End If
Next i

Update
End Sub

Sub draw_points(ByRef pt() As Double)
Call pointmode
Dim pointobj As AcadPoint
Dim i As Integer, numpts As Integer
Dim x1 As Double, y1 As Double

Dim pt1(0 To 2) As Double
numpts = UBound(pt) / 2

For i = 1 To numpts
x1 = pt(i * 2 - 1)
y1 = pt(i * 2)
pt1(0) = x1: pt1(1) = y1: pt1(2) = 0
Set pointobj = acadDoc.ModelSpace.AddPoint(pt1)
Next i

Update
End Sub

the DrawMode LinesWLimits takes the user entered values for maximum X and Y skips any line segment with a greater point value. The user can use the program to graph

Y=\frac{1}{X}

Capture_12-22-2015_1

Capture_12-24-2015_1

 

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