/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
private double x0;
private double y0;
private double cx0;
private double cy0;
private double cx1;
private double cy1;
private double x1;
private double y1;
private double xmin;
private double xmax;
private double xcoeff0;
private double xcoeff1;
private double xcoeff2;
private double xcoeff3;
private double ycoeff0;
private double ycoeff1;
private double ycoeff2;
private double ycoeff3;
int direction)
{
if (numparams == 0) {
// We are using addInstance here to avoid inserting horisontal
// segments
return;
}
// Store coordinates for splitting at tmp[3..10]
double t = tmp[0];
// Perform a "2 element sort"...
tmp[1] = t;
t = tmp[0];
}
if (numparams > 1) {
// Recalculate tmp[1] relative to the range [tmp[0]...1]
}
int index = 3;
if (direction == DECREASING) {
}
while (numparams >= 0) {
numparams--;
if (direction == INCREASING) {
index += 6;
} else {
index -= 6;
}
}
}
int direction) {
-direction));
direction));
}
}
/*
* Return the count of the number of horizontal sections of the
* specified cubic Bezier curve. Put the parameters for the
* horizontal sections into the specified <code>ret</code> array.
* <p>
* If we examine the parametric equation in t, we have:
* Py(t) = C0(1-t)^3 + 3CP0 t(1-t)^2 + 3CP1 t^2(1-t) + C1 t^3
* = C0 - 3C0t + 3C0t^2 - C0t^3 +
* 3CP0t - 6CP0t^2 + 3CP0t^3 +
* 3CP1t^2 - 3CP1t^3 +
* C1t^3
* Py(t) = (C1 - 3CP1 + 3CP0 - C0) t^3 +
* (3C0 - 6CP0 + 3CP1) t^2 +
* (3CP0 - 3C0) t +
* (C0)
* If we take the derivative, we get:
* Py(t) = Dt^3 + At^2 + Bt + C
* dPy(t) = 3Dt^2 + 2At + B = 0
* 0 = 3*(C1 - 3*CP1 + 3*CP0 - C0)t^2
* + 2*(3*CP1 - 6*CP0 + 3*C0)t
* + (3*CP0 - 3*C0)
* 0 = 3*(C1 - 3*CP1 + 3*CP0 - C0)t^2
* + 3*2*(CP1 - 2*CP0 + C0)t
* + 3*(CP0 - C0)
* 0 = (C1 - CP1 - CP1 - CP1 + CP0 + CP0 + CP0 - C0)t^2
* + 2*(CP1 - CP0 - CP0 + C0)t
* + (CP0 - C0)
* 0 = (C1 - CP1 + CP0 - CP1 + CP0 - CP1 + CP0 - C0)t^2
* + 2*(CP1 - CP0 - CP0 + C0)t
* + (CP0 - C0)
* 0 = ((C1 - CP1) - (CP1 - CP0) - (CP1 - CP0) + (CP0 - C0))t^2
* + 2*((CP1 - CP0) - (CP0 - C0))t
* + (CP0 - C0)
* Note that this method will return 0 if the equation is a line,
* which is either always horizontal or never horizontal.
* Completely horizontal curves need to be eliminated by other
* means outside of this method.
*/
double ret[]) {
return 0;
}
int j = 0;
for (int i = 0; i < numroots; i++) {
double t = ret[i];
// No splits at t==0 and t==1
if (t > 0 && t < 1) {
if (j < i) {
ret[j] = t;
}
j++;
}
}
return j;
}
/*
* Split the cubic Bezier stored at coords[pos...pos+7] representing
* the parametric range [0..1] into two subcurves representing the
* parametric subranges [0..t] and [t..1]. Store the results back
* into the array at coords[pos...pos+7] and coords[pos+6...pos+13].
*/
}
int direction)
{
super(direction);
// REMIND: Better accuracy in the root finding methods would
// ensure that cys are in range. As it stands, they are never
// more than "1 mantissa bit" out of range...
}
public int getOrder() {
return 3;
}
public double getXTop() {
return x0;
}
public double getYTop() {
return y0;
}
public double getXBot() {
return x1;
}
public double getYBot() {
return y1;
}
public double getXMin() {
return xmin;
}
public double getXMax() {
return xmax;
}
public double getX0() {
}
public double getY0() {
}
public double getCX0() {
}
public double getCY0() {
}
public double getCX1() {
}
public double getCY1() {
}
public double getX1() {
}
public double getY1() {
}
private double TforY1;
private double YforT1;
private double TforY2;
private double YforT2;
private double TforY3;
private double YforT3;
/*
* Solve the cubic whose coefficients are in the a,b,c,d fields and
* return the first root in the range [0, 1].
* The cubic solved is represented by the equation:
* x^3 + (ycoeff2)x^2 + (ycoeff1)x + (ycoeff0) = y
* @return the first valid root (in the range [0, 1])
*/
public double TforY(double y) {
if (y <= y0) return 0;
if (y >= y1) return 1;
// From Numerical Recipes, 5.6, Quadratic and Cubic Equations
if (ycoeff3 == 0.0) {
// The cubic degenerated to quadratic (or line or ...).
}
int roots = 0;
double Q = (a * a - 3.0 * b) / 9.0;
double R = (2.0 * a * a * a - 9.0 * a * b + 27.0 * c) / 54.0;
double R2 = R * R;
double Q3 = Q * Q * Q;
double a_3 = a / 3.0;
double t;
if (t < 0) {
t = refine(a, b, c, y,
}
if (t < 0) {
t = refine(a, b, c, y,
}
} else {
boolean neg = (R < 0.0);
if (neg) {
R = -R;
}
if (!neg) {
A = -A;
}
double B = (A == 0.0) ? 0.0 : (Q / A);
}
if (t < 0) {
//throw new InternalError("bad t");
double t0 = 0;
double t1 = 1;
while (true) {
break;
}
if (yt < y) {
t0 = t;
} else if (yt > y) {
t1 = t;
} else {
break;
}
}
}
if (t >= 0) {
TforY1 = t;
YforT1 = y;
}
return t;
}
public double refine(double a, double b, double c,
double target, double t)
{
if (t < -0.1 || t > 1.1) {
return -1;
}
double y = YforT(t);
if (y < target) {
t0 = t;
t1 = 1;
} else {
t0 = 0;
t1 = t;
}
double origt = t;
double origy = y;
boolean useslope = true;
while (y != target) {
if (!useslope) {
break;
}
t = t2;
} else {
if (slope == 0) {
useslope = false;
continue;
}
useslope = false;
continue;
}
t = t2;
}
y = YforT(t);
if (y < target) {
t0 = t;
} else if (y > target) {
t1 = t;
} else {
break;
}
}
boolean verbose = false;
if (false && t >= 0 && t <= 1) {
y = YforT(t);
{
}
}
}
return (t > 1) ? -1 : t;
}
public double XforY(double y) {
if (y <= y0) {
return x0;
}
if (y >= y1) {
return x1;
}
}
public double XforT(double t) {
}
public double YforT(double t) {
}
switch (deriv) {
case 0:
case 1:
case 2:
case 3:
return 6 * xcoeff3;
default:
return 0;
}
}
switch (deriv) {
case 0:
case 1:
case 2:
case 3:
return 6 * ycoeff3;
default:
return 0;
}
}
for (int i = 0; i < numroots; i++) {
}
}
return t1;
}
for (int i = 0; i < numroots; i++) {
double t = eqn[i];
if (t > 0 && t < 1) {
}
}
}
return getWithDirection(dir);
}
double eqn[] = new double[14];
/* This happens in only rare cases where ystart is
* very near yend and solving for the yend root ends
* up stepping slightly lower in t than solving for
* the ystart root.
* Ideally we might want to skip this tiny little
* segment and just fudge the surrounding coordinates
* to bridge the gap left behind, but there is no way
* to do that from here. Higher levels could
* potentially eliminate these tiny "fixup" segments,
* but not without a lot of extra work on the code that
* coalesces chains of curves into subpaths. The
* simplest solution for now is to just reorder the t
* values and chop out a miniscule curve piece.
*/
double t = t0;
t1 = t;
}
if (t1 < 1) {
}
int i;
if (t0 <= 0) {
i = 0;
} else {
i = 6;
}
dir);
}
}
if (direction == INCREASING) {
} else {
}
return PathIterator.SEG_CUBICTO;
}
}
}