30 #define BEZIERSUBDIVISION 20
37 #define M_PI 3.14159265358979323846
39 #define D2R(d) (M_PI*(d)/180.0)
40 #define R2D(r) (180.0*(r)/M_PI)
42 static double currentmiterlimit = 10.0;
44 #define moveto(p,x,y) addto(p,x,y)
45 #define lineto(p,x,y) addto(p,x,y)
47 static void addto (
stroke_t* p,
double x,
double y)
60 static void arcn (
stroke_t* p,
double x,
double y,
double r,
double a1,
double a2)
65 addto (p, x+r*cos(a1), y+r*sin(a1));
67 while (a2 > a1) a2 -= 2*
M_PI;
69 while (theta > 2*
M_PI) theta -= 2*
M_PI;
72 addto (p, x+r*cos(a1-i*theta), y+r*sin(a1-i*theta));
80 addto (p, pt.
x, pt.
y);
89 static double myatan (
double y,
double x)
92 if ((x == 0) && (y == 0))
97 else return (v + 2*
M_PI);
104 static double mymod (
double original,
double modulus)
107 if ((original < 0) || (original >= modulus)) {
108 v = -floor(original/modulus);
109 return ((v*modulus) + original);
147 if (arr->
cnt >= arr->
sz) {
164 fprintf (fp,
"cnt %d sz %d\n", arr->
cnt, arr->
sz);
165 for (i = 0; i < arr->
cnt; i++) {
167 fprintf (fp,
" [%d] x %.02f y %.02f d %.02f\n", i, pt.
x, pt.
y, pt.
lengthsofar);
175 if (arr->
sz > arr->
cnt)
188 double delx = p0.
x - p1.
x;
189 double dely = p0.
y - p1.
y;
190 return sqrt(delx*delx + dely*dely);
199 double seglen, linelen = 0;
205 insertArr (arr, A[0], 0);
207 for (i = 0; i + 3 < n; i += 3) {
209 for (j = 1; j <= 3; j++)
214 seglen = l2dist(p0, p1);
221 insertArr (arr, p1, linelen);
228 printArr (arr, stderr);
233 static void drawbevel(
double x,
double y,
double lineout,
int forward,
double dir,
double dir2,
int linejoin,
stroke_t* p)
246 if (a <=
D2R(0.1)) a +=
D2R(360);
249 arcn (p,x,y,lineout,a1,a2);
251 lineto (p, x + lineout*cos(a2), x + lineout*sin(a2));
254 lineto (p, x + lineout*cos(a2), x + lineout*sin(a2));
258 typedef double (*
radfunc_t) (
double curlen,
double totallen,
double initwid);
274 int pathcount, bevel;
275 double direction=0, direction_2=0;
276 vararr_t* arr = pathtolines (bez, initwid);
278 pathpoint cur_point, last_point, next_point;
279 double x=0, y=0,
dist;
282 double lineout=0, linerad=0, linelen=0;
286 pathcount = arr->
cnt;
287 pathpoints = arr->
pts;
291 for (i = 0; i < pathcount; i++) {
292 l = mymod(i-1,pathcount);
293 n = mymod(i+1,pathcount);
295 cur_point = pathpoints[i];
300 next_point = pathpoints[n];
303 ndir = myatan (ny-y, nx-x);
305 last_point = pathpoints[l];
308 ldir = myatan (ly-y, lx-x);
314 linerad = radfunc(
dist, linelen, initwid);
316 if ((i == 0) || (i == pathcount-1)) {
319 direction = ndir +
D2R(90);
321 x -= cos(ndir)*lineout;
322 y -= sin(ndir)*lineout;
325 direction = ldir -
D2R(90);
327 x -= cos(ldir)*lineout;
328 y -= sin(ldir)*lineout;
331 direction_2 = direction;
337 phi =
D2R(90)-(theta/2);
342 lineout = linerad/(cos(phi));
345 direction = ndir+
D2R(90)+phi;
346 if ((0 != linejoin) || (lineout > currentmiterlimit * linerad)) {
349 direction = mymod(ldir-
D2R(90),
D2R(360));
350 direction_2 = mymod(ndir+
D2R(90),
D2R(360));
351 if (i == pathcount-1) {
355 direction_2 = direction;
361 pathpoints[i].
type =
'l';
362 pathpoints[i].
dir = direction;
363 pathpoints[i].
lout = lineout;
364 pathpoints[i].
bevel = bevel;
365 pathpoints[i].
dir2 = direction_2;
371 for (i = 0; i < pathcount; i++) {
372 cur_point = pathpoints[i];
375 direction = cur_point.
dir;
376 lineout = cur_point.
lout;
377 bevel = cur_point.
bevel;
378 direction_2 = cur_point.
dir2;
380 moveto (p, x+cos(direction)*lineout, y+sin(direction)*lineout);
382 lineto (p, x+cos(direction)*lineout, y+sin(direction)*lineout);
385 drawbevel (x, y, lineout,
TRUE, direction, direction_2, linejoin, p);
390 arcn (p, x,y,lineout,direction,direction+
D2R(180));
392 direction +=
D2R(180);
393 lineto (p, x+cos(direction)*lineout, y+sin(direction)*lineout);
396 for (i = pathcount-2; i >= 0; i--) {
397 cur_point = pathpoints[i];
400 direction = cur_point.
dir +
D2R(180);
401 lineout = cur_point.
lout;
402 bevel = cur_point.
bevel;
403 direction_2 = cur_point.
dir2 +
D2R(180);
404 lineto (p, x+cos(direction_2)*lineout, y+sin(direction_2)*lineout);
406 drawbevel (x, y, lineout,
FALSE, direction, direction_2, linejoin, p);
411 arcn (p, x,y,lineout,direction,direction+
D2R(180));
418 static double halffunc (
double curlen,
double totallen,
double initwid)
420 return ((1 - (curlen/totallen))*initwid/2.0);
425 return taper(bez, halffunc, initwid, 0, 0);
445 printf (
"newpath\n");
449 printf (
"fill showpage\n");
#define RALLOC(size, ptr, type)
double(* radfunc_t)(double, double, double)
stroke_t * taper(bezier *, double(*radfunc_t)(double, double, double), double initwid, int linejoin, int linecap)
pointf Bezier(pointf *V, int degree, double t, pointf *Left, pointf *Right)
#define BEZIERSUBDIVISION
double dist(Site *s, Site *t)
int main(int argc, char **argv)
stroke_t * taper0(bezier *bez, double initwid)