float shadows_highlights (float input, float shadowsX, float shadowsY, float highlightsX, float highlightsY) { float x = input; float a = shadowsX; float b = shadowsY; float c = highlightsX; float d = highlightsY; float y0a = 0.00; // initial y float x0a = 0.00; // initial x float y1a = b; // 1st influence y float x1a = a; // 1st influence x float y2a = d; // 2nd influence y float x2a = c; // 2nd influence x float y3a = 1.00; // final y float x3a = 1.00; // final x float A = x3a - 3*x2a + 3*x1a - x0a; float B = 3*x2a - 6*x1a + 3*x0a; float C = 3*x1a - 3*x0a; float D = x0a; float E = y3a - 3*y2a + 3*y1a - y0a; float F = 3*y2a - 6*y1a + 3*y0a; float G = 3*y1a - 3*y0a; float H = y0a; // Solve for t given x (using Newton-Raphson), then solve for y given t. // Assume for the first guess that t = x. float currentt = x; int nRefinementIterations = 5; for (int i = 0; i < nRefinementIterations; i++) { float currentx = xFromT(currentt, A, B, C, D); float currentslope = slopeFromT(currentt, A, B, C); currentt -= (currentx - x) * (currentslope); currentt = min(max(currentt, float(0)), float(1)); } float y = yFromT (currentt, E, F, G, H); return y; }
double Bezier::findSplit(QPointF p, double minDistance) const { double bestT = 0; double lastDistance = std::numeric_limits<int>::max(); double blen = computeCubicCurveLength(1.0, 24); double increment = 1.0 / blen; double minDSqd = minDistance * minDistance; for (double t = 0; t <= 1; t += increment) { double x = xFromT(t); double y = yFromT(t); double d = GraphicsUtils::distanceSqd(p, QPointF(x, y)); if (d >= lastDistance) { if (d > minDSqd) continue; break; } bestT = t; lastDistance = d; } return bestT; }