2362N/A * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A // We are using addInstance here to avoid inserting horisontal 0N/A // Store coordinates for splitting at tmp[3..10] 0N/A // Perform a "2 element sort"... 0N/A // Recalculate tmp[1] relative to the range [tmp[0]...1] 0N/A * Return the count of the number of horizontal sections of the 0N/A * specified cubic Bezier curve. Put the parameters for the 0N/A * horizontal sections into the specified <code>ret</code> array. 0N/A * If we examine the parametric equation in t, we have: 0N/A * Py(t) = C0(1-t)^3 + 3CP0 t(1-t)^2 + 3CP1 t^2(1-t) + C1 t^3 0N/A * = C0 - 3C0t + 3C0t^2 - C0t^3 + 0N/A * 3CP0t - 6CP0t^2 + 3CP0t^3 + 0N/A * 3CP1t^2 - 3CP1t^3 + 0N/A * Py(t) = (C1 - 3CP1 + 3CP0 - C0) t^3 + 0N/A * (3C0 - 6CP0 + 3CP1) t^2 + 0N/A * If we take the derivative, we get: 0N/A * Py(t) = Dt^3 + At^2 + Bt + C 0N/A * dPy(t) = 3Dt^2 + 2At + B = 0 0N/A * 0 = 3*(C1 - 3*CP1 + 3*CP0 - C0)t^2 0N/A * + 2*(3*CP1 - 6*CP0 + 3*C0)t 0N/A * 0 = 3*(C1 - 3*CP1 + 3*CP0 - C0)t^2 0N/A * + 3*2*(CP1 - 2*CP0 + C0)t 0N/A * 0 = (C1 - CP1 - CP1 - CP1 + CP0 + CP0 + CP0 - C0)t^2 0N/A * + 2*(CP1 - CP0 - CP0 + C0)t 0N/A * 0 = (C1 - CP1 + CP0 - CP1 + CP0 - CP1 + CP0 - C0)t^2 0N/A * + 2*(CP1 - CP0 - CP0 + C0)t 0N/A * 0 = ((C1 - CP1) - (CP1 - CP0) - (CP1 - CP0) + (CP0 - C0))t^2 0N/A * + 2*((CP1 - CP0) - (CP0 - C0))t 0N/A * Note that this method will return 0 if the equation is a line, 0N/A * which is either always horizontal or never horizontal. 0N/A * Completely horizontal curves need to be eliminated by other 0N/A * means outside of this method. 0N/A // No splits at t==0 and t==1 0N/A if (t >
0 && t <
1) {
0N/A * Split the cubic Bezier stored at coords[pos...pos+7] representing 0N/A * the parametric range [0..1] into two subcurves representing the 0N/A * parametric subranges [0..t] and [t..1]. Store the results back 0N/A * into the array at coords[pos...pos+7] and coords[pos+6...pos+13]. 0N/A // REMIND: Better accuracy in the root finding methods would 0N/A // ensure that cys are in range. As it stands, they are never 0N/A // more than "1 mantissa bit" out of range... 0N/A * Solve the cubic whose coefficients are in the a,b,c,d fields and 0N/A * return the first root in the range [0, 1]. 0N/A * The cubic solved is represented by the equation: 0N/A * x^3 + (ycoeff2)x^2 + (ycoeff1)x + (ycoeff0) = y 0N/A * @return the first valid root (in the range [0, 1]) 0N/A // From Numerical Recipes, 5.6, Quadratic and Cubic Equations 0N/A // The cubic degenerated to quadratic (or line or ...). 0N/A double Q = (a * a -
3.0 * b) /
9.0;
0N/A double R = (
2.0 * a * a * a -
9.0 * a * b +
27.0 * c) /
54.0;
0N/A double B = (A ==
0.0) ?
0.0 : (Q / A);
0N/A //throw new InternalError("bad t"); 0N/A public double refine(
double a,
double b,
double c,
0N/A if (t < -
0.1 || t >
1.1) {
0N/A if (
false && t >=
0 && t <=
1) {
0N/A return (t >
1) ? -
1 : t;
0N/A if (t >
0 && t <
1) {
0N/A double eqn[] =
new double[
14];
0N/A /* This happens in only rare cases where ystart is 0N/A * very near yend and solving for the yend root ends 0N/A * up stepping slightly lower in t than solving for 0N/A * Ideally we might want to skip this tiny little 0N/A * segment and just fudge the surrounding coordinates 0N/A * to bridge the gap left behind, but there is no way 0N/A * to do that from here. Higher levels could 0N/A * potentially eliminate these tiny "fixup" segments, 0N/A * but not without a lot of extra work on the code that 0N/A * coalesces chains of curves into subpaths. The 0N/A * simplest solution for now is to just reorder the t 0N/A * values and chop out a miniscule curve piece.