Robin2:
Below is my Python code for expanding a GCode arc into a series of straight lines.
The function call is like this
arcLines = expandArc(gCmd, prevXaxisVal, prevYaxisVal, xAxisVal, yAxisVal, iVal, jVal)
in which gCmd will be one of 'G02', 'G03', 'G2', 'G3' and the paramters xAxisVal, yAxisVal, iVal, jVal come from the line of GCode. For example G2 X41.1994 Y30.0377 Z1.0000 I-14.9907 J-14.9903
The variable arcLines will contain all the straight-lines that are needed to follow the arc
Note that this function does not prefix each line of GCode with 'G1' as the rest of my Python program takes that as given. It just produces the relevant X and Y values as they would appear in a line of GCode like this G1 Xaaa Ybbb
My notes tell me that I got the idea from this website
How to Improve the 2-axis CNC GCODE Interpreter to Understand Arcs – Marginally Clever Robots
I hope, with that description, you will be able to follow the Python code
def expandArc(gCmd, prevXaxisVal, prevYaxisVal, xAxisVal, yAxisVal, iVal, jVal):
arcMoveList = []
dirn = 'CW'
if gCmd in ['G03', 'G3']:
dirn = 'CCW'
startX = prevXaxisVal
startY = prevYaxisVal
centreX = startX + iVal
centreY = startY + jVal
# calculate angle to start point
dxStart = startX - centreX
dyStart = startY - centreY
startAngle = math.atan2(dyStart, dxStart) #* 180 / math.pi
# calculate angle to end point
dxEnd = xAxisVal - centreX
dyEnd = yAxisVal - centreY
endAngle = math.atan2(dyEnd, dxEnd) #* 180 / math.pi
# make sure direction works
if endAngle > startAngle:
endAngle = endAngle - (math.pi * 2)
radius = math.sqrt((dyStart * dyStart) + (dxStart * dxStart));
sweep = endAngle - startAngle
if dirn == 'CCW':
sweep = (math.pi * 2) + sweep # for 'CW' sweep will be negative
# ~ arcLen = abs(sweep) * radius
# ~ numSegments = int(arcLen / mD.arcSegmentLength)
numSegments = int(abs(sweep / (math.pi * 2) * mD.circleDiv))
for x in range(numSegments):
fraction = float(x) / numSegments
stepAngle = startAngle + ( sweep * fraction )
stepX = centreX + math.cos(stepAngle) * radius;
stepY = centreY + math.sin(stepAngle) * radius;
if dirn == 'CW':
if sweep > 0:
stepY = - stepY
else:
if sweep < 0:
stepY = - stepY
arcMoveList.append([round(stepX,4), round(stepY,4)])
arcMoveList.append([xAxisVal, yAxisVal])
# ~ print("ArcList STARTx %s STARTy %s" %(startX, startY))
# ~ for m in arcMoveList:
# ~ print (m)
# ~ pass
# ~ print ("--------\n")
return arcMoveList
...R
Thank you. Looks great and since i have my GCode Streamer for the Laser in Python this will be very easy to implement.