void QNanoPainter::quadTo(const QPointF &controlPoint, const QPointF &endPoint) { quadTo(controlPoint.x(), controlPoint.y(), endPoint.x(), endPoint.y()); }
void WPainterPath::quadTo(const WPointF& c, const WPointF& endPoint) { quadTo(c.x(), c.y(), endPoint.x(), endPoint.y()); }
/* genEllipticPath: * Approximate an elliptical arc via Beziers of given degree * threshold indicates quality of approximation * if isSlice is true, the path begins and ends with line segments * to the center of the ellipse. * Returned path must be freed by the caller. */ static Ppolyline_t *genEllipticPath(ellipse_t * ep, int degree, double threshold, boolean isSlice) { double dEta; double etaB; double cosEtaB; double sinEtaB; double aCosEtaB; double bSinEtaB; double aSinEtaB; double bCosEtaB; double xB; double yB; double xBDot; double yBDot; double t; double alpha; Ppolyline_t *path = NEW(Ppolyline_t); // find the number of Bezier curves needed boolean found = FALSE; int i, n = 1; while ((!found) && (n < 1024)) { double dEta = (ep->eta2 - ep->eta1) / n; if (dEta <= 0.5 * M_PI) { double etaB = ep->eta1; found = TRUE; for (i = 0; found && (i < n); ++i) { double etaA = etaB; etaB += dEta; found = (estimateError(ep, degree, etaA, etaB) <= threshold); } } n = n << 1; } dEta = (ep->eta2 - ep->eta1) / n; etaB = ep->eta1; cosEtaB = cos(etaB); sinEtaB = sin(etaB); aCosEtaB = ep->a * cosEtaB; bSinEtaB = ep->b * sinEtaB; aSinEtaB = ep->a * sinEtaB; bCosEtaB = ep->b * cosEtaB; xB = ep->cx + aCosEtaB * ep->cosTheta - bSinEtaB * ep->sinTheta; yB = ep->cy + aCosEtaB * ep->sinTheta + bSinEtaB * ep->cosTheta; xBDot = -aSinEtaB * ep->cosTheta - bCosEtaB * ep->sinTheta; yBDot = -aSinEtaB * ep->sinTheta + bCosEtaB * ep->cosTheta; if (isSlice) { moveTo(path, ep->cx, ep->cy); lineTo(path, xB, yB); } else { moveTo(path, xB, yB); } t = tan(0.5 * dEta); alpha = sin(dEta) * (sqrt(4 + 3 * t * t) - 1) / 3; for (i = 0; i < n; ++i) { double xA = xB; double yA = yB; double xADot = xBDot; double yADot = yBDot; etaB += dEta; cosEtaB = cos(etaB); sinEtaB = sin(etaB); aCosEtaB = ep->a * cosEtaB; bSinEtaB = ep->b * sinEtaB; aSinEtaB = ep->a * sinEtaB; bCosEtaB = ep->b * cosEtaB; xB = ep->cx + aCosEtaB * ep->cosTheta - bSinEtaB * ep->sinTheta; yB = ep->cy + aCosEtaB * ep->sinTheta + bSinEtaB * ep->cosTheta; xBDot = -aSinEtaB * ep->cosTheta - bCosEtaB * ep->sinTheta; yBDot = -aSinEtaB * ep->sinTheta + bCosEtaB * ep->cosTheta; if (degree == 1) { lineTo(path, xB, yB); #if DO_QUAD } else if (degree == 2) { double k = (yBDot * (xB - xA) - xBDot * (yB - yA)) / (xADot * yBDot - yADot * xBDot); quadTo(path, (xA + k * xADot), (yA + k * yADot), xB, yB); #endif } else { curveTo(path, (xA + alpha * xADot), (yA + alpha * yADot), (xB - alpha * xBDot), (yB - alpha * yBDot), xB, yB); } } endPath(path, isSlice); return path; }