5 #define PINC 32 /* realloc granularity */
7 typedef struct Plist Plist;
11 int np; /* -1 if malloc/realloc failed */
15 appendpt(Plist *l, Point p)
20 l->p = malloc(PINC*sizeof(Point));
21 else if(l->np%PINC == 0)
22 l->p = realloc(l->p, (l->np+PINC)*sizeof(Point));
33 return p.x*p.x+p.y*p.y;
37 psdist(Point p, Point a, Point b)
43 num = p.x*b.x + p.y*b.y;
48 return normsq(subpt(b, p));
49 return normsq(subpt(divpt(mulpt(b, num), den), p));
53 * Convert cubic Bezier curve control points to polyline
54 * vertices. Leaves the last vertex off, so you can continue
58 bpts1(Plist *l, Point p0, Point p1, Point p2, Point p3, int scale)
60 Point p01, p12, p23, p012, p123, p0123;
61 Point tp0, tp1, tp2, tp3;
66 if(psdist(tp1, tp0, tp3)<=1 && psdist(tp2, tp0, tp3)<=1){
73 * if scale factor is getting too big for comfort,
74 * rescale now & concede the rounding error
88 p0123=addpt(p012, p123);
89 bpts1(l, mulpt(p0, 8), mulpt(p01, 4), mulpt(p012, 2), p0123, scale*8);
90 bpts1(l, p0123, mulpt(p123, 2), mulpt(p23, 4), mulpt(p3, 8), scale*8);
95 bpts(Plist *l, Point p0, Point p1, Point p2, Point p3)
97 bpts1(l, p0, p1, p2, p3, 1);
101 bezierpts(Plist *l, Point p0, Point p1, Point p2, Point p3)
103 bpts(l, p0, p1, p2, p3);
108 _bezsplinepts(Plist *l, Point *pt, int npt)
117 periodic = eqpt(pt[0], ep[2]);
119 a = divpt(addpt(ep[1], pt[0]), 2);
120 b = divpt(addpt(ep[1], mulpt(pt[0], 5)), 6);
121 c = divpt(addpt(mulpt(pt[0], 5), pt[1]), 6);
122 d = divpt(addpt(pt[0], pt[1]), 2);
125 for(p=pt; p<=ep; p++){
126 if(p==pt && !periodic){
128 b = divpt(addpt(p[0], mulpt(p[1], 2)), 3);
131 a = divpt(addpt(p[0], p[1]), 2);
132 b = divpt(addpt(p[0], mulpt(p[1], 5)), 6);
134 if(p==ep && !periodic){
135 c = divpt(addpt(mulpt(p[1], 2), p[2]), 3);
139 c = divpt(addpt(mulpt(p[1], 5), p[2]), 6);
140 d = divpt(addpt(p[1], p[2]), 2);
148 bezsplinepts(Point *pt, int npt, Point **pp)
153 _bezsplinepts(&l, pt, npt);
159 bezier(Image *dst, Point p0, Point p1, Point p2, Point p3, int end0, int end1, int radius, Image *src, Point sp)
161 return bezierop(dst, p0, p1, p2, p3, end0, end1, radius, src, sp, SoverD);
165 bezierop(Image *dst, Point p0, Point p1, Point p2, Point p3, int end0, int end1, int radius, Image *src, Point sp, Drawop op)
170 bezierpts(&l, p0, p1, p2, p3);
174 polyop(dst, l.p, l.np, end0, end1, radius, src, addpt(subpt(sp, p0), l.p[0]), op);
181 bezspline(Image *dst, Point *pt, int npt, int end0, int end1, int radius, Image *src, Point sp)
183 return bezsplineop(dst, pt, npt, end0, end1, radius, src, sp, SoverD);
187 bezsplineop(Image *dst, Point *pt, int npt, int end0, int end1, int radius, Image *src, Point sp, Drawop op)
192 _bezsplinepts(&l, pt, npt);
196 polyop(dst, l.p, l.np, end0, end1, radius, src, addpt(subpt(sp, pt[0]), l.p[0]), op);
203 fillbezier(Image *dst, Point p0, Point p1, Point p2, Point p3, int w, Image *src, Point sp)
205 return fillbezierop(dst, p0, p1, p2, p3, w, src, sp, SoverD);
209 fillbezierop(Image *dst, Point p0, Point p1, Point p2, Point p3, int w, Image *src, Point sp, Drawop op)
214 bezierpts(&l, p0, p1, p2, p3);
218 fillpolyop(dst, l.p, l.np, w, src, addpt(subpt(sp, p0), l.p[0]), op);
225 fillbezspline(Image *dst, Point *pt, int npt, int w, Image *src, Point sp)
227 return fillbezsplineop(dst, pt, npt, w, src, sp, SoverD);
231 fillbezsplineop(Image *dst, Point *pt, int npt, int w, Image *src, Point sp, Drawop op)
236 _bezsplinepts(&l, pt, npt);
240 fillpolyop(dst, l.p, l.np, w, src, addpt(subpt(sp, pt[0]), l.p[0]), op);