Autocad VBA Logo Turtle Graphics

Logo was a lisp like educational language designed to introduce children to coding. I believe there may be no serious impediments to implementing an experimental version in Autocad VBA. This is a work in process, first post is proof of concept. The full implementation is yet to be planned. I wont worry too much about deviating from standard logo methods or syntax. If i hit a problem that cannot be coded around, that will be information gained. I believe the concepts may turn out to be useful for more general VBA parametric autocad code.

For all of my projects, I code in an Excel XLSM file. I have a standard ACAD_CONNECT sub i use, and reference the Autocad Type Library in the Excel VBAProject. i have never downloaded the Autocad VBA implementation. It is not necessary to code Autocad VBA. I use the VBA editor provided routinely in Excel.

The fundamental element of turtle geometry is the current position of the pen, and the heading or direction it is pointing. This prototype will be 2D, so we need a global variable for the X and Y position, and a variable for the heading. We will keep heading in degrees and convert it in the low level subs to radians.

The first thing we will need is a line subroutine that takes logo style input – current point, distance, and heading – to draw the line and change the pen position to the end of the line. The user wont call this sub directly but will use std routines like Forward, PenUP, Right, Left, etc.

Option Explicit
 Public px As Double 'position x
 Public py As Double 'position y
 Public hxy As Double 'heading degree


Sub line_hd(x1 As Double, y1 As Double, dist As Double, heading As Double)
' call line_t(x1,y1,dist,heading)
' heading in degrees

Dim lineobj As AcadLine
Dim pt1(0 To 2) As Double
Dim pt2(0 To 2) As Double
Dim heading_radian As Double

pt1(0) = x1: pt1(1) = y1: pt1(2) = 0
heading_radian = heading * Pi / 180

'px and py are global position
px = px + dist * Cos(heading_radian)
py = py + dist * Sin(heading_radian)

pt2(0) = px: pt2(1) = py: pt2(2) = 0
Set lineobj = acadDoc.ModelSpace.AddLine(pt1, pt2)

Update
End Sub

standard logo subroutines FORWARD, RIGHT, LEFT and BACK to get started are pretty simple at this point. i dont have a PENUP, PENDOWN yet that will modify these.

Sub forward(dist As Double)
Call line_hd(px, py, dist, hxy)
End Sub

Sub right(deg As Double)
hxy = hxy - deg
End Sub

Sub left(deg As Double)
hxy = hxy + deg
End Sub

Sub back(dist As Double)
Dim heading_radian As Double
heading_radian = hxy * Pi / 180
px = px - (dist * Cos(heading_radian))
py = py - (dist * Sin(heading_radian))
End Sub

a sample user prototype sub and init sub helper.

 Sub init_turtle()
 Call connect_acad
 px = 0
 py = 0
 hxy = 0
 End Sub
 
 Sub to_honeycomb()
  init_turtle
 Dim i As Integer, j As Integer

For j = 1 To 3
For i = 1 To 6
forward 6
left 60
Next i

left 120
Next j

End Sub

2017-01-15_1

 Sub to_star()
 init_turtle
 Dim i As Integer
 
 For i = 1 To 5
 forward 6
 right 144
 Next i
 
 End Sub
 

2017-01-15_2

the circle routine according to python turtle graphics just takes a radius. from the position and heading of the turtle, it makes a 360 arc back to the starting point. if the radius is positive, it turns counterclockwise, if negative then opposite. the task then is to run a normal perpendicular off the heading vector the same distance as the radius to find the center.

this is a little messy, i dont think it will stay this way.

first a demo calling program, then the circle primitive code.

Sub test_circle()
init_turtle

For i = 1 To 21
forward 6
right 15 + i
forward 6
curcle 3
forward 3
curcle -3
forward 6
curcle -3
forward 3
curcle 3
Next i

End Sub

Sub curcle(radius As Double)
Call circle_turtle(px, py, radius, hxy)
End Sub


Sub circle_turtle(x1 As Double, y1 As Double, radius As Double, hxy As Double)
' circle wrapper
' call circle_hd(x1,y1,radius,heading)
' heading in degrees
Dim newheading As Double
Dim newheading_radian As Double
Dim Cx As Double, Cy As Double
Dim circleobj As AcadCircle
Dim pt2(0 To 2) As Double

If radius > 0 Then
newheading = hxy + 90
Else
newheading = hxy - 90
End If

newheading_radian = newheading * Pi / 180

'px and py are global position
'we are calculating circle center but not changing position
Cx = px + Abs(radius) * Cos(newheading_radian)
Cy = py + Abs(radius) * Sin(newheading_radian)
pt2(0) = Cx: pt2(1) = Cy: pt2(2) = 0

Set circleobj = acadDoc.ModelSpace.AddCircle(pt2, Abs(radius))

Update
End Sub

2017-01-16_1

more to come

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