Line and Circular Interpolation on XY Plane

Tips: This is my homework of “Computer Control System” course, so mistakes do happen.

This article will discuss an interpolation algorithms for line and circular. And it provides an implement of C language.

Interpolation Algorithms

Many numerical control machines are powered by stepping motors. When a pulse is sent to a stepping motor, the stepping motor alters its position by a unit step. Two motors can be used to control the XY movements of an arm or tool over a working plane.

If the pulse are generated by a device which can remember or generate a specified train of pulses, repetitive operations such as grinding, painting, or cutting can be performed hunderds of times with virtually no variation. A microcomputer is an obvious choice to gernerate and remember the pulse.

Since stepper motors can move only in discrete steps, we must approximate the actual curve by a series of small XY motions. Many algorithms rely upon parametric functions such as sine and cosine to perform the necessary calculations. Parametric functions, however, typically require a high degree of numeric precision. Calculating sine and cosine values with a microcomputer can be too time-consuming to be useful in a realtime application.

The following two algorithms require no parametric functions. This makes them ideally suited to the computation and memory capacities of microcomputers. Since these algorithms do not require a large amount of complex mathematical calculation, they are fast enough to be used in real-time applications.

C Program

main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
char type[10];
char data1[5],data2[5],data3[5],data4[5],data5[5];
/* consider that the point may be decimal, so use "int" */
int x_0,y_0; // starting point
int x_1,y_1; // endpoint
int xe,ye; // relative endpoint
int xi,yi; // relative position
int x,y; // real position
int dx,dy; // the value of impulse
int fxy; // value of function
int step; // consider that the step may be decimal
int rad; // the radius of the circle
int x_dir,y_dir; // direction of impulse
int p2x; // Circle: when fxy is positive, decide step towards x or not
int cw; // present clockwise
int check,requirement = 1; // make sure endpoint locates at the desired one
void doline();
void getdir();
void docircle(); // according to requirement, the arc is 1/4 circle
void clockwise();
void counterclockwise();
int main(void)
{
printf("Please input command line (ie: 'G01 (2,3,7,8) 1') :\n");
scanf("%s (%[^,],%[^,],%[^,],%[^)]) %s",type,data1,data2,data3,data4,data5);
x_0 = atof(data1);
y_0 = atof(data2);
x_1 = atof(data3);
y_1 = atof(data4);
x = x_0;
y = y_0;
step = atof(data5);
getdir();
printf("\n\nFor code '%s' with step = %d",type,step);
printf("\nGoing from (%d,%d) to (%d,%d):\n",x_0,y_0,x_1,y_1);
printf("\nXi\tYi\tFxy\tDx\tDy\tX\tY");
if(!strcmp(type,"G01")) doline();
else
{
if(!strcmp(type,"G02")) cw = 1;
else cw = 0;
docircle();
}
printf("\n%d\t%d\t\t\t\t%d\t%d",xi,yi,x,y);
//system("pause");
return 0;
}
void getdir()
{
if(x_1>=x_0) x_dir = 1;
else x_dir = -1;
if(y_1>=y_0) y_dir = 1;
else y_dir = -1;
}
void doline()
{
xe = x_1 - x_0;
ye = y_1 - y_0;
xi = yi = 0.0;
p2x = 1;
while((xi<xe)||(yi<ye))
{
fxy = abs(xe)*abs(yi) - abs(ye)*abs(xi);
impulse();
}
}
void docircle()
{
rad = abs(x_1 - x_0);
if(cw) clockwise();
else counterclockwise();
while(requirement)
{
fxy = (xi*xi) + (yi*yi) - (rad*rad);
impulse();
switch(check)
{
case 1: if((xi<=xe)&&(yi>=ye)) requirement = 0;break;
case 2: if((xi>=xe)&&(yi>=ye)) requirement = 0;break;
case 3: if((xi>=xe)&&(yi<=ye)) requirement = 0;break;
case 4: if((xi<=xe)&&(yi<=ye)) requirement = 0;break;
}
}
}
void impulse()
{
if(fxy>=0)
{
dx = x_dir*p2x*step;
dy = y_dir*(!p2x)*step;
}
else
{
dx = x_dir*(!p2x)*step;
dy = y_dir*(p2x)*step;
}
printf("\n%d\t%d\t%d\t%d\t%d\t%d\t%d",xi,yi,fxy,dx,dy,x,y);
xi = xi + dx;
yi = yi + dy;
x = x + dx;
y = y + dy;
}
void clockwise()
{
if((x_1>x_0)&&(y_1<y_0))
{
p2x = 0;
xe = rad;
ye = 0.0;
xi = 0.0;
yi = rad;
check = 3;
}
if((x_1>x_0)&&(y_1>y_0))
{
p2x = 1;
xe = 0.0;
ye = rad;
xi = -rad;
yi = 0.0;
check = 2;
}
if((x_1<x_0)&&(y_1>y_0))
{
p2x = 0;
xe = -rad;
ye = 0.0;
xi = 0.0;
yi = -rad;
check = 1;
}
if((x_1<x_0)&&(y_1<y_0))
{
p2x = 1;
xe = 0.0;
ye = -rad;
xi = rad;
yi = 0.0;
check = 4;
}
}
void counterclockwise()
{
if((x_1<x_0)&&(y_1>y_0))
{
p2x = 1;
xe = 0.0;
ye = rad;
xi = rad;
yi = 0.0;
check = 1;
}
if((x_1<x_0)&&(y_1<y_0))
{
p2x = 0;
xe = -rad;
ye = 0.0;
xi = 0.0;
yi = rad;
check = 4;
}
if((x_1>x_0)&&(y_1<y_0))
{
p2x = 1;
xe = -rad;
ye = 0.0;
xi = 0.0;
yi = -rad;
check = 3;
}
if((x_1>x_0)&&(y_1>y_0))
{
p2x = 0;
xe = rad;
ye = 0.0;
xi = 0.0;
yi = -rad;
check = 2;
}
}

Result

G01

G02

Reference

“XY INTERPOLATION ALGORITHMS” By Kenneth and Melvin Goldberg