60#define TWOPI (2 * M_PI)
71 double lambda1,
double lambda2) {
77 ep->
eta1 = atan2(sin(lambda1) / b, cos(lambda1) / a);
78 ep->
eta2 = atan2(sin(lambda2) / b, cos(lambda2) / a);
96 {{3.85268, -21.229, -0.330434, 0.0127842},
97 {-1.61486, 0.706564, 0.225945, 0.263682},
98 {-0.910164, 0.388383, 0.00551445, 0.00671814},
99 {-0.630184, 0.192402, 0.0098871, 0.0102527}},
100 {{-0.162211, 9.94329, 0.13723, 0.0124084},
101 {-0.253135, 0.00187735, 0.0230286, 0.01264},
102 {-0.0695069, -0.0437594, 0.0120636, 0.0163087},
103 {-0.0328856, -0.00926032, -0.00173573, 0.00527385}}};
109 {{0.0899116, -19.2349, -4.11711, 0.183362},
110 {0.138148, -1.45804, 1.32044, 1.38474},
111 {0.230903, -0.450262, 0.219963, 0.414038},
112 {0.0590565, -0.101062, 0.0430592, 0.0204699}},
113 {{0.0164649, 9.89394, 0.0919496, 0.00760802},
114 {0.0191603, -0.0322058, 0.0134667, -0.0825018},
115 {0.0156192, -0.017535, 0.00326508, -0.228157},
116 {-0.0236752, 0.0405821, -0.0173086, 0.176187}}};
120static const double safety3[] = {0.001, 4.98, 0.207, 0.0067};
127 return (x * (x * c[0] + c[1]) + c[2]) / (x + c[3]);
136 double c0, c1, eta = 0.5 * (etaA + etaB);
138 double x = ep->
b / ep->
a;
139 double dEta = etaB - etaA;
140 double cos2 = cos(2 * eta);
141 double cos4 = cos(4 * eta);
142 double cos6 = cos(6 * eta);
167static void moveTo(bezier_path_t *polypath,
double x,
double y) {
171static void curveTo(bezier_path_t *polypath,
double x1,
double y1,
double x2,
172 double y2,
double x3,
double y3) {
178static void lineTo(bezier_path_t *polypath,
double x,
double y) {
180 curveTo(polypath, curp.
x, curp.
y, x, y, x, y);
196 static const double THRESHOLD = 0.00001;
201 while (!found && n < 1024) {
202 double diffEta = (ep->
eta2 - ep->
eta1) / n;
203 if (diffEta <= 0.5 *
M_PI) {
204 double etaOne = ep->
eta1;
206 for (i = 0; found && i < n; ++i) {
207 double etaA = etaOne;
215 const double dEta = (ep->
eta2 - ep->
eta1) / n;
216 double etaB = ep->
eta1;
218 double cosEtaB = cos(etaB);
219 double sinEtaB = sin(etaB);
220 double aCosEtaB = ep->
a * cosEtaB;
221 double bSinEtaB = ep->
b * sinEtaB;
222 double aSinEtaB = ep->
a * sinEtaB;
223 double bCosEtaB = ep->
b * cosEtaB;
224 double xB = ep->
cx + aCosEtaB;
225 double yB = ep->
cy + bSinEtaB;
226 double xBDot = -aSinEtaB;
227 double yBDot = bCosEtaB;
229 bezier_path_t bezier_path = {0};
230 moveTo(&bezier_path, ep->
cx, ep->
cy);
231 lineTo(&bezier_path, xB, yB);
233 const double t = tan(0.5 * dEta);
234 const double alpha = sin(dEta) * (sqrt(4 + 3 * t * t) - 1) / 3;
236 for (i = 0; i < n; ++i) {
240 double xADot = xBDot;
241 double yADot = yBDot;
246 aCosEtaB = ep->
a * cosEtaB;
247 bSinEtaB = ep->
b * sinEtaB;
248 aSinEtaB = ep->
a * sinEtaB;
249 bCosEtaB = ep->
b * cosEtaB;
250 xB = ep->
cx + aCosEtaB;
251 yB = ep->
cy + bSinEtaB;
256 xB -
alpha * xBDot, yB -
alpha * yBDot, xB, yB);
273 double angle0,
double angle1) {
276 initEllipse(&ell, ctr.
x, ctr.
y, xsemi, ysemi, angle0, angle1);
Memory allocation wrappers that exit on failure.
static void * gv_alloc(size_t size)
static void lineTo(bezier_path_t *polypath, double x, double y)
static Ppolyline_t * genEllipticPath(ellipse_t *ep)
static const erray_t coeffs3Low
static const erray_t coeffs3High
static double RationalFunction(double x, const double *c)
static void initEllipse(ellipse_t *ep, double cx, double cy, double a, double b, double lambda1, double lambda2)
Ppolyline_t * ellipticWedge(pointf ctr, double xsemi, double ysemi, double angle0, double angle1)
static double estimateError(ellipse_t *ep, double etaA, double etaB)
static void endPath(bezier_path_t *polypath)
static void curveTo(bezier_path_t *polypath, double x1, double y1, double x2, double y2, double x3, double y3)
static const double safety3[]
type-generic dynamically expanding list
#define LIST_DETACH(list, datap, sizep)
#define LIST_APPEND(list, item)
#define LIST_GET(list, index)
finds and smooths shortest paths