62#define TWOPI (2 * M_PI)
73 double lambda1,
double lambda2) {
79 ep->
eta1 = atan2(sin(lambda1) / b, cos(lambda1) / a);
80 ep->
eta2 = atan2(sin(lambda2) / b, cos(lambda2) / a);
98 {{3.85268, -21.229, -0.330434, 0.0127842},
99 {-1.61486, 0.706564, 0.225945, 0.263682},
100 {-0.910164, 0.388383, 0.00551445, 0.00671814},
101 {-0.630184, 0.192402, 0.0098871, 0.0102527}},
102 {{-0.162211, 9.94329, 0.13723, 0.0124084},
103 {-0.253135, 0.00187735, 0.0230286, 0.01264},
104 {-0.0695069, -0.0437594, 0.0120636, 0.0163087},
105 {-0.0328856, -0.00926032, -0.00173573, 0.00527385}}};
111 {{0.0899116, -19.2349, -4.11711, 0.183362},
112 {0.138148, -1.45804, 1.32044, 1.38474},
113 {0.230903, -0.450262, 0.219963, 0.414038},
114 {0.0590565, -0.101062, 0.0430592, 0.0204699}},
115 {{0.0164649, 9.89394, 0.0919496, 0.00760802},
116 {0.0191603, -0.0322058, 0.0134667, -0.0825018},
117 {0.0156192, -0.017535, 0.00326508, -0.228157},
118 {-0.0236752, 0.0405821, -0.0173086, 0.176187}}};
122static const double safety3[] = {0.001, 4.98, 0.207, 0.0067};
129 return (x * (x * c[0] + c[1]) + c[2]) / (x + c[3]);
138 double c0, c1, eta = 0.5 * (etaA + etaB);
140 double x = ep->
b / ep->
a;
141 double dEta = etaB - etaA;
142 double cos2 = cos(2 * eta);
143 double cos4 = cos(4 * eta);
144 double cos6 = cos(6 * eta);
169static void moveTo(bezier_path_t *polypath,
double x,
double y) {
173static void curveTo(bezier_path_t *polypath,
double x1,
double y1,
double x2,
174 double y2,
double x3,
double y3) {
180static void lineTo(bezier_path_t *polypath,
double x,
double y) {
182 curveTo(polypath, curp.
x, curp.
y, x, y, x, y);
198 static const double THRESHOLD = 0.00001;
203 while (!found && n < 1024) {
204 double diffEta = (ep->
eta2 - ep->
eta1) / n;
205 if (diffEta <= 0.5 *
M_PI) {
206 double etaOne = ep->
eta1;
208 for (i = 0; found && i < n; ++i) {
209 double etaA = etaOne;
217 const double dEta = (ep->
eta2 - ep->
eta1) / n;
218 double etaB = ep->
eta1;
220 double cosEtaB = cos(etaB);
221 double sinEtaB = sin(etaB);
222 double aCosEtaB = ep->
a * cosEtaB;
223 double bSinEtaB = ep->
b * sinEtaB;
224 double aSinEtaB = ep->
a * sinEtaB;
225 double bCosEtaB = ep->
b * cosEtaB;
226 double xB = ep->
cx + aCosEtaB;
227 double yB = ep->
cy + bSinEtaB;
228 double xBDot = -aSinEtaB;
229 double yBDot = bCosEtaB;
231 bezier_path_t bezier_path = {0};
232 moveTo(&bezier_path, ep->
cx, ep->
cy);
233 lineTo(&bezier_path, xB, yB);
235 const double t = tan(0.5 * dEta);
236 const double alpha = sin(dEta) * (sqrt(4 + 3 * t * t) - 1) / 3;
238 for (i = 0; i < n; ++i) {
242 double xADot = xBDot;
243 double yADot = yBDot;
248 aCosEtaB = ep->
a * cosEtaB;
249 bSinEtaB = ep->
b * sinEtaB;
250 aSinEtaB = ep->
a * sinEtaB;
251 bCosEtaB = ep->
b * cosEtaB;
252 xB = ep->
cx + aCosEtaB;
253 yB = ep->
cy + bSinEtaB;
258 xB -
alpha * xBDot, yB -
alpha * yBDot, xB, yB);
275 double angle0,
double angle1) {
278 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