Lisp Parabola

This is pretty simple. Its a start. Func1 defines the equation ax^2 + bx + c with the specific values of a b and c and returns the value when passed the current value of X.  C:para calls the parabola function and sets the x minimum, maximum and x increment.

screenshot from the visual lisp editor.
2017-03-05_2

if instead of unconnected lines, we want to graph with a 2D Polyline, the command is PLine, it takes the same point list. We start the Pline command with the first point, then enter the loop and calculate the next point each time through the loop, leaving the command processor running and just feeding it one point each time.

2017-03-05_4

For graphing polar equations – Polar Coordinates – P(R,Ɵ) – A point is defined by how far it is from the origin (R – Radius) and what angle (Ɵ – Theta) a line from the origin to the point makes with the horizontal axis. (I am using A for angle instead of Ɵ in the code)

To change the command from separate lines to connected polyline, we start the pline command outside the loop and only calculate one point in the loop, just as for the rectangular cartesian program.

Advertisements

Creating the Graph Point Data

Autocad AddLightWeightPolyline method requires an array of doubles. It does not require the lowerbound of the array to be zero. An array simply has to have an even number of elements, one element for each X and each Y alternating. (x1, y1, x2, y2, x3, y3…) For indexes and loops I typically use the counting numbers, which do not include zero. I am evaluating an autocad work-alike program that is similar but requires arrays to be zero-based. It does not throw an error with a one-based array but results are a failure. it creates zero values for non-existent indexes that it expects. However there is no reason the arrays cannot be zero-based so they run in both packages. To that end for that reason i am re-doing the graph loops.

Only the array needs to be zero based. The loop still executes one time for each point. The index of the array starts with zero.

Calculation of points for Coordinate XY graphing –

2016-10-03_1

Autocad does not care what indexes the array pt (below) was created with. The work-alike absolutely requires a starting index of zero.

Dim plineobj As AcadLWPolyline
Set plineobj = acadDoc.ModelSpace.AddLightWeightPolyline(pt)

in line drawing mode, subtracting lbound from ubound adding one and dividing by two will give the number of points in the array. There is one less line. Since we know lbound is zero we could remove that. The loop iterates once for each line drawn. We could do the loop to handle any lbound value, but it would be a little messy with no immediate benefit. For now we expect a zero base array.

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) - LBound(pt) + 1) / 2
numlines = numpts - 1

'this requires a zero base array
For i = 1 To numlines
x1 = pt(i * 2 - 2)
y1 = pt(i * 2 - 1)
x2 = pt(i * 2)
y2 = pt(i * 2 + 1)

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

Lines w/limits mode we use when the Y value approaches infinity, such as y=1/x near x=0. It is otherwise the same.

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) - LBound(pt) + 1) / 2
numlines = numpts - 1

'this requires a zero base array
For i = 1 To numlines
x1 = pt(i * 2 - 2)
y1 = pt(i * 2 - 1)
x2 = pt(i * 2)
y2 = pt(i * 2 + 1)

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

point mode


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) - LBound(pt) + 1) / 2

'this requires a zero base array
For i = 1 To numpts
x1 = pt(i * 2 - 2)
y1 = pt(i * 2 - 1)
pt1(0) = x1: pt1(1) = y1: pt1(2) = 0
Set pointobj = acadDoc.ModelSpace.AddPoint(pt1)
Next i

Update
End Sub

Autocad Graphing Calculator

Autocad has Euclidean roots. Its a classic geometry tool. And it has VBA. It is not necessary to download and install the VBA module to have full access to VBA through Excel.

this blog online 1 year with 100 pages, approx, More to come.

i apologize for the old posts with messed up links and code mangling. wordpress changed their editor last year and between them and me changing the theme, we messed up a few pages that were ok when first published. i just noticed some new broken links.

2016-09-05_1

Lissajous curves gone wrong. I unchecked the convert to Radians button in the Parametric form before graphing, so that Sin(360) is interpreted by VBA not as Sin(2 pi) but Sin(360) or in radians Sin(57 * 2 pi) approx, but more importantly the step increment between points instead of being 1 degree is 1 radian or 57 degrees.

2016-09-05_2

the Cochleoid

the Cochleoid is a polar spiral that spirals in on itself, because Sin A varies between -1 and 1, but A gets ever larger.

2016-08-29_1

at point 8 A is 210, not 30, but because the Sin is negative, R is negative. The graph passes thru 0,0 every time the sin is zero.

2016-08-29_2

running the graph from negative 1080 (-6 pi) to -1 (to avoid divide by zero error) draws the mirror image graph from the inside out.

2016-08-29_3

2016-08-29_4

wolfram reference
http://mathworld.wolfram.com/Cochleoid.html

Autocad VBA Font Tables

Tablestyles can be added and programmed without duplicating code by using a global variable for the AcadTableStyle object. This is a flexible method for getting a handle on them.

but first – make font tables in autocad – run a loop from 0 to 255 to advance the Chr(#), change the textstyle of the table style to instantly change the table.

Sub test_array_to_acadtable3()

'0 to 255 ascii table
'font style is set in the table style
'send the array to the maketable routine

Call connect_acad
Dim rows As Integer, i As Integer
Dim columns As Integer, j As Integer

rows = 16
columns = 16

Dim ar_mult() As String
ReDim ar_mult(1 To rows, 1 To columns)

For i = 1 To rows
For j = 1 To columns
ar_mult(i, j) = Chr((i - 1) * 16 + (j - 1))
Next j
Next i

Call makethetable3(ar_mult)
End Sub

2016-08-07_3

2016-08-07_2

2016-08-07_4

2016-08-07_1

2016-08-07_5

2016-08-07_6

VBA Arrays and Autocad Tables

Here is the basic routine for making an autocad table from an array in its simplest form from a one-based array, and a generalized form that creates a table from any two-dimensional array.


Sub test_array_to_acadtable1()
'test to make a one-based two dimensional array of numbers
'and send the array to the maketable routines

Call connect_acad
Dim rows As Integer, i As Integer
Dim columns As Integer, j As Integer
'change these to anything you like
rows = 14
columns = 16

Dim ar_mult() As Integer
ReDim ar_mult(1 To rows, 1 To columns)

For i = 1 To rows
For j = 1 To columns
ar_mult(i, j) = i * j
Next j
Next i

'makes two identical tables
Call makethetable2(ar_mult)
Call makethetable3(ar_mult)
End Sub


Sub test_array_to_acadtable2()
'test to make a random-based two dimensional array of numbers
'and send the array to the maketable routine
'that has been generalized to accept an array of any base

Call connect_acad
Dim rows As Integer, i As Integer
Dim columns As Integer, j As Integer
'change these to anything you like
rows = 14
columns = 16

Dim ar_mult() As Integer
ReDim ar_mult(3 To rows + 2, 3 To columns + 2)

For i = 3 To rows + 2
For j = 3 To columns + 2
ar_mult(i, j) = (i - 2) * (j - 2)
Next j
Next i

Call makethetable3(ar_mult)
End Sub


Sub makethetable3(ar As Variant)
'table is two-dimensional and any-base
    Dim tbl As AcadTable
    Dim i As Integer, j As Integer
    Dim rowcount As Integer, colcount As Integer
    Dim rowLbound As Integer, colLbound As Integer
    Dim rowUbound As Integer, colUbound As Integer
    
    Dim drowh As Double, dcolw As Double
    Dim pt0(0 To 2) As Double
    
    rowLbound = LBound(ar, 1)
    colLbound = LBound(ar, 2)
    rowUbound = UBound(ar, 1)
    colUbound = UBound(ar, 2)
    rowcount = rowUbound - rowLbound + 1
    colcount = colUbound - colLbound + 1
        
        drowh = 0.125
        dcolw = 0.625
    Set tbl = acadDoc.ModelSpace.AddTable(pt0, rowcount, colcount, drowh, dcolw)
        tbl.UnmergeCells 0, 0, 0, 0
        tbl.TitleSuppressed = True
        tbl.HeaderSuppressed = True

    For i = rowLbound To rowUbound
        For j = colLbound To colUbound
        tbl.SetText i - colLbound, j - rowLbound, ar(i, j)
        Next j
    Next i
End Sub


Sub makethetable2(ar As Variant)
'the simpler routine
'assume table is two-dimensional and one-base
'no attempt to set up a tablestyle
'which makes the unmerge method necessary
 
    Dim tbl As AcadTable
    Dim i As Integer, j As Integer
    Dim rowcount As Integer, colcount As Integer
    Dim drowh As Double, dcolw As Double
    Dim pt0(0 To 2) As Double
    
    rowcount = UBound(ar, 1)
    colcount = UBound(ar, 2)
    drowh = 0.125
    dcolw = 0.625
    'create the table sized for the array
   Set tbl = acadDoc.ModelSpace.AddTable(pt0, rowcount, colcount, drowh, dcolw)
    tbl.UnmergeCells 0, 0, 0, 0
    tbl.TitleSuppressed = True
    tbl.HeaderSuppressed = True

    For i = 1 To rowcount
     For j = 1 To colcount
     tbl.SetText i - 1, j - 1, ar(i, j)
     Next j
    Next i

End Sub

any selection of data on a spreadsheet can be saved to an array with a single line of code, and the array fed to the makethetable routine. of course the formatting is terrible but we have tools for that.


Sub make_table_from_selection()
Dim ar_tbl As Variant
ar_tbl = Selection.Value
 'a selection assigned to a variant
 'creates a one-based two-dimension array
 'the first dim is the row, the second is the column
  
'MsgBox LBound(ar_tbl, 1)  returns 1
'MsgBox LBound(ar_tbl, 2)  returns 1

Call connect_acad
Call makethetable3(ar_tbl)

End Sub