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.
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