@@ -41,7 +41,7 @@ export class GCodeRuntimeParser {
4141 private genRunTime ( ) : boolean {
4242 const oldpt : Coords = { x : 0 , y : 0 , z : 0 } ;
4343 const newpt : Coords = { x : 0 , y : 0 , z : 0 } ;
44- const ijk : Coords = { x : 0 , y : 0 , z : 0 } ;
44+ const ijkr = { i : 0 , j : 0 , k : 0 , r : - 1 } ;
4545 const state : State = {
4646 distance : 0 ,
4747 feedrate : 1 ,
@@ -124,27 +124,54 @@ export class GCodeRuntimeParser {
124124
125125 // Circular Interpolation
126126 if ( letter === 'I' ) {
127- ijk . x = + argument ;
127+ ijkr . i = + argument ;
128128 }
129-
130129 if ( letter === 'J' ) {
131- ijk . y = + argument ;
130+ ijkr . j = + argument ;
132131 }
133132
134133 if ( letter === 'K' ) {
135- ijk . z = + argument ;
134+ ijkr . k = + argument ;
135+ }
136+
137+ if ( letter === 'R' ) {
138+ ijkr . r = + argument ;
136139 }
137140 } ) ;
138141
139142 // End of Line
140143
141144 // Calculate Distance Moved
145+
142146 if ( state . abs ) {
147+ // Absolute Mode
143148 state . distance = Math . sqrt (
144149 Math . pow ( newpt . x - oldpt . x , 2 ) + Math . pow ( newpt . y - oldpt . y , 2 ) + Math . pow ( newpt . z - oldpt . z , 2 ) ,
145150 ) ;
146151
152+ if ( state . circ ) {
153+ // Circular Interpolation
154+ const centerpt = [ oldpt . x - ijkr . i , oldpt . y - ijkr . j , oldpt . z - ijkr . k ] ;
155+ let radius : number ;
156+ if ( ijkr . r === - 1 ) {
157+ // IJK Mode
158+ radius = Math . sqrt (
159+ Math . pow ( centerpt [ 0 ] , 2 ) + Math . pow ( centerpt [ 1 ] , 2 ) + Math . pow ( centerpt [ 2 ] , 2 ) ,
160+ ) ;
161+ } else {
162+ // Radius Mode
163+ radius = ijkr . r ;
164+ }
165+
166+ // Arc Length: ( 2( arcsin(d / 2r) ) / 2)
167+ const arclen = 2 * Math . asin ( state . distance / ( 2 * radius ) ) * radius ;
168+
169+ state . distance = arclen ;
170+ }
171+
147172 Object . assign ( oldpt , newpt ) ;
173+ } else {
174+ // Incremental Mode
148175 }
149176
150177 if ( ! state . rapid ) {
0 commit comments