I'm posting this - since I think some folks on here might find this curious. Especially since somewhat recently there were a couple posts in LinkedIn Fox Dev groups - about using AI to generate FoxPro code.
I recently started work on a little pet project. And, since I am now doing FoxPro fulltime, I figured doing some fun VFP coding on my lunch breaks would actually be FUN to do! Figured I would share a little about that project here...
But, first - the backstory about the project...
As I was traveling across the USA - on my way to Cleveland, OH from SoCal - I stopped at a buddy of mine in Utah. He's a 3D printing guy & a Youtuber by the name of Joe the 3D Printing Professor (feel free to search for him on YouTube - he is rather entertaining!). I originally met him in person in 2018 - on my original cross country journey from NY to CA. So, it was great to see him.
While we were hanging out in this MakerSpace (where he works to oversee the space), in the St. Georges Utah library - we were chatting about a personal project of mine. And, for that project - it's a kind of 3D Design issue I was discussing with him. After chatting for a bit, he jumped on his computer and opened up Blender - to suggest a way to easily model my concept - which is based upon making a 3D tree (but, with a number of rules). However, even as he was doing it - I pointed out issues with what he was creating (issues where it didn't follow my rules).
Suddenly he jumped up, erased all this writing on a white board and he began to quickly outline a rather elaborate algorithm. Because, in fact, like me - he has a bit of a programming background. And, his whole algorithm that was outlining not only shapes and how to produce them, he was also considering things like an array to store certain data as part of the process.
Now, normally in the world of 3D Printing - you using a modeling program, then export an STL file. Then, you use a program called a Slicer to Slice that STL file into GCode. Then, the GCode is fed into a 3D printer, and that code runs the printer.
However, my buddy was like - why not generate GCode directly! And, it became an obsession in my head as I was driving across the country. Then I finally began trying to write a FoxPro program to generate GCode.
Now, one complication I had was - how do I easily determine if 2 lines actually intersect. Well, I realized I could ask AI for that answer. I initially asked CoPilot to give me an algorithm for finding the intersection. Which it did. But, then I thought - when not see if AI could generate actual VFP code to do what I needed.
So, here was my Prompt for CoPilot:
Can you write Visual FoxPro code that allows me to determine the coordinate value for the intersection of 2 lines, based upon the X & Y endpoints of each of those 2 lines?
Here was what it generated - which is valid code:
* Define the endpoints of the lines
LOCAL x1, y1, x2, y2, x3, y3, x4, y4
x1 = 1 && X-coordinate of the first endpoint of the first line
y1 = 2 && Y-coordinate of the first endpoint of the first line
x2 = 4 && X-coordinate of the second endpoint of the first line
y2 = 6 && Y-coordinate of the second endpoint of the first line
x3 = 1 && X-coordinate of the first endpoint of the second line
y3 = 6 && Y-coordinate of the first endpoint of the second line
x4 = 4 && X-coordinate of the second endpoint of the second line
y4 = 2 && Y-coordinate of the second endpoint of the second line
* Calculate the intersection point
LOCAL xIntersect, yIntersect, denominator
denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)
IF denominator == 0
* Lines are parallel or coincident, no intersection
xIntersect = .NULL.
yIntersect = .NULL.
MESSAGEBOX("The lines are parallel or coincident and do not intersect.")
ELSE
xIntersect = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / denominator
yIntersect = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / denominator
MESSAGEBOX("Intersection point: (" + STR(xIntersect) + ", " + STR(yIntersect) + ")")
ENDIF
I also had AI generate some other code to draw a circle on the screen, using Polar coordinates to Cartesian coordinate conversion, and allowing input of a Radius. So, I used that code to wrap the from code above - so, if you run this code - it generates lines crossing and pops up with a message with the intersection:
* Define the endpoints of the lines
LOCAL x1, y1, x2, y2, x3, y3, x4, y4
x1 = 10 && X-coordinate of the first endpoint of the first line
y1 = 60 && Y-coordinate of the first endpoint of the first line
x2 = 40 && X-coordinate of the second endpoint of the first line
y2 = 25 && Y-coordinate of the second endpoint of the first line
x3 = 1 && X-coordinate of the first endpoint of the second line
y3 = 6 && Y-coordinate of the first endpoint of the second line
x4 = 54 && X-coordinate of the second endpoint of the second line
y4 = 72 && Y-coordinate of the second endpoint of the second line
* Create a form to draw the circle
LOCAL oForm
oForm = CREATEOBJECT("Form")
oForm.Width = 400
oForm.Height = 400
oForm.Show()
oForm.DrawWidth = 1
oForm.DrawStyle = 0
oForm.Line(X1, Y1, X2, Y2) && Draw a small line segment to create the circle
oForm.DrawWidth = 1
oForm.DrawStyle = 0
oForm.Line(X3, Y3, X4, Y4) && Draw a small line segment to create the circle
* Calculate the intersection point
LOCAL xIntersect, yIntersect, denominator
denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)
IF denominator == 0
* Lines are parallel or coincident, no intersection
xIntersect = .NULL.
yIntersect = .NULL.
MESSAGEBOX("The lines are parallel or coincident and do not intersect.")
ELSE
xIntersect = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / denominator
yIntersect = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / denominator
MESSAGEBOX("Intersection point: (" + STR(xIntersect) + ", " + STR(yIntersect) + ")")
ENDIF
Lastly - for those who are curious to see what GCode actually looks like, I'm including several lines of code, the 1st being a comment line. I will include a couple of the command lines, and even some comments per line - to explain what some of them do:
; generated by PrusaSlicer 2.8.0+win64 on 2025-03-24 at 11:02:10 UTC
; external perimeters extrusion width = 0.42mm
M205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec
G90 ; use absolute coordinates
M140 S60 ; set final bed temp
M104 S210 ; set final nozzle temp - Yes, that's 210 Celsius
G1 Z0.28 F240 ; Movement of the printer in the Z direction
G1 X117.315 Y90.902 E.04751 ; Movement of the print head in X & Y, from prior location to that new X/Y location, with plastic extrusion based upon amount listed by "E"
I hope some folks find this a tad interesting...
L8r G8rs,
-Kurt