/*
* 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.
*/
public abstract class Curve {
protected int direction;
}
{
INCREASING));
DECREASING));
} else {
// Do not add horizontal lines
}
}
double coords[])
{
// Do not add horizontal lines
return;
} else {
}
}
double coords[])
{
// Do not add horizontal lines
return;
} else {
}
}
/**
* Calculates the number of times the given path
* crosses the ray extending to the right from (px,py).
* If the point lies on a part of the path,
* then no crossings are counted for that intersection.
* +1 is added for each crossing where the Y coordinate is increasing
* -1 is added for each crossing where the Y coordinate is decreasing
* The return value is the sum of all crossings for every segment in
* the path.
* The path must start with a SEG_MOVETO, otherwise an exception is
* thrown.
* The caller must check p[xy] for NaN values.
* The caller may also reject infinite p[xy] values as well.
*/
{
return 0;
}
double coords[] = new double[6];
throw new IllegalPathStateException("missing initial moveto "+
"in path definition");
}
int crossings = 0;
case PathIterator.SEG_MOVETO:
}
break;
case PathIterator.SEG_LINETO:
break;
case PathIterator.SEG_QUADTO:
break;
case PathIterator.SEG_CUBICTO:
break;
case PathIterator.SEG_CLOSE:
}
break;
}
}
}
return crossings;
}
/**
* Calculates the number of times the line from (x0,y0) to (x1,y1)
* crosses the ray extending to the right from (px,py).
* If the point lies on the line, then no crossings are recorded.
* +1 is returned for a crossing where the Y coordinate is increasing
* -1 is returned for a crossing where the Y coordinate is decreasing
*/
{
// assert(y0 != y1);
}
/**
* Calculates the number of times the quad from (x0,y0) to (x1,y1)
* crosses the ray extending to the right from (px,py).
* If the point lies on a part of the curve,
* then no crossings are counted for that intersection.
* the level parameter should be 0 at the top-level call and will count
* up for each recursion level to prevent infinite recursion
* +1 is added for each crossing where the Y coordinate is increasing
* -1 is added for each crossing where the Y coordinate is decreasing
*/
{
// Note y0 could equal y1...
} else {
// py < y0
}
return 0;
}
// double precision only has 52 bits of mantissa
// [xy]c are NaN if any of [xy]0c or [xy]c1 are NaN
// [xy]0c or [xy]c1 are NaN if any of [xy][0c1] are NaN
// These values are also NaN if opposing infinities are added
return 0;
}
level+1) +
level+1));
}
/**
* Calculates the number of times the cubic from (x0,y0) to (x1,y1)
* crosses the ray extending to the right from (px,py).
* If the point lies on a part of the curve,
* then no crossings are counted for that intersection.
* the level parameter should be 0 at the top-level call and will count
* up for each recursion level to prevent infinite recursion
* +1 is added for each crossing where the Y coordinate is increasing
* -1 is added for each crossing where the Y coordinate is decreasing
*/
{
// Note y0 could equal yc0...
} else {
// py < y0
}
return 0;
}
// double precision only has 52 bits of mantissa
// [xy]mid are NaN if any of [xy]c0m or [xy]mc1 are NaN
// [xy]c0m or [xy]mc1 are NaN if any of [xy][c][01] are NaN
// These values are also NaN if opposing infinities are added
return 0;
}
}
/**
* The rectangle intersection test counts the number of times
* that the path crosses through the shadow that the rectangle
* projects to the right towards (x => +INFINITY).
*
* During processing of the path it actually counts every time
* the path crosses either or both of the top and bottom edges
* of that shadow. If the path enters from the top, the count
* is incremented. If it then exits back through the top, the
* same way it came in, the count is decremented and there is
* no impact on the winding count. If, instead, the path exits
* out the bottom, then the count is incremented again and a
* full pass through the shadow is indicated by the winding count
* having been incremented by 2.
*
* Thus, the winding count that it accumulates is actually double
* the real winding count. Since the path is continuous, the
* final answer should be a multiple of 2, otherwise there is a
* logic error somewhere.
*
* If the path ever has a direct hit on the rectangle, then a
* special value is returned. This special value terminates
* all ongoing accumulation on up through the call chain and
* ends up getting returned to the calling function which can
* then produce an answer directly. For intersection tests,
* the answer is always "true" if the path intersects the
* rectangle. For containment tests, the answer is always
* "false" if the path intersects the rectangle. Thus, no
* further processing is ever needed if an intersection occurs.
*/
/**
* Accumulate the number of times the path crosses the shadow
* extending to the right of the rectangle. See the comment
* for the RECT_INTERSECTS constant for more complete details.
* The return value is the sum of all crossings for both the
* top and bottom of the shadow for every segment in the path,
* or the special value RECT_INTERSECTS if the path ever enters
* the interior of the rectangle.
* The path must start with a SEG_MOVETO, otherwise an exception is
* thrown.
* The caller must check r[xy]{min,max} for NaN values.
*/
{
return 0;
}
return 0;
}
double coords[] = new double[6];
throw new IllegalPathStateException("missing initial moveto "+
"in path definition");
}
int crossings = 0;
case PathIterator.SEG_MOVETO:
}
// Count should always be a multiple of 2 here.
// assert((crossings & 1) != 0);
break;
case PathIterator.SEG_LINETO:
break;
case PathIterator.SEG_QUADTO:
break;
case PathIterator.SEG_CUBICTO:
break;
case PathIterator.SEG_CLOSE:
}
// Count should always be a multiple of 2 here.
// assert((crossings & 1) != 0);
break;
}
}
}
// Count should always be a multiple of 2 here.
// assert((crossings & 1) != 0);
return crossings;
}
/**
* Accumulate the number of times the line crosses the shadow
* extending to the right of the rectangle. See the comment
* for the RECT_INTERSECTS constant for more complete details.
*/
{
// Line is entirely to the right of the rect
// and the vertical ranges of the two overlap by a non-empty amount
// Thus, this line segment is partially in the "right-shadow"
// Path may have done a complete crossing
// Or path may have entered or exited the right-shadow
// y-increasing line segment...
// We know that y0 < rymax and y1 > rymin
// y-decreasing line segment...
// We know that y1 < rymax and y0 > rymin
}
return crossings;
}
// Remaining case:
// Both x and y ranges overlap by a non-empty amount
// First do trivial INTERSECTS rejection of the cases
// where one of the endpoints is inside the rectangle.
{
return RECT_INTERSECTS;
}
// Otherwise calculate the y intercepts and see where
// they fall with respect to the rectangle
}
}
// y-increasing line segment...
// We know that y0 < rymax and y1 > rymin
// y-decreasing line segment...
// We know that y1 < rymax and y0 > rymin
}
return crossings;
}
return RECT_INTERSECTS;
}
/**
* Accumulate the number of times the quad crosses the shadow
* extending to the right of the rectangle. See the comment
* for the RECT_INTERSECTS constant for more complete details.
*/
int level)
{
// Quad is entirely to the right of the rect
// and the vertical range of the 3 Y coordinates of the quad
// overlaps the vertical range of the rect by a non-empty amount
// We now judge the crossings solely based on the line segment
// connecting the endpoints of the quad.
// Note that we may have 0, 1, or 2 crossings as the control
// point may be causing the Y range intersection while the
// two endpoints are entirely above or below.
// y-increasing line segment...
// y-decreasing line segment...
}
return crossings;
}
// The intersection of ranges is more complicated
// First do trivial INTERSECTS rejection of the cases
// where one of the endpoints is inside the rectangle.
{
return RECT_INTERSECTS;
}
// Otherwise, subdivide and look for one of the cases above.
// double precision only has 52 bits of mantissa
if (level > 52) {
return rectCrossingsForLine(crossings,
}
// [xy]c are NaN if any of [xy]0c or [xy]c1 are NaN
// [xy]0c or [xy]c1 are NaN if any of [xy][0c1] are NaN
// These values are also NaN if opposing infinities are added
return 0;
}
level+1);
if (crossings != RECT_INTERSECTS) {
level+1);
}
return crossings;
}
/**
* Accumulate the number of times the cubic crosses the shadow
* extending to the right of the rectangle. See the comment
* for the RECT_INTERSECTS constant for more complete details.
*/
int level)
{
return crossings;
}
return crossings;
}
return crossings;
}
// Cubic is entirely to the right of the rect
// and the vertical range of the 4 Y coordinates of the cubic
// overlaps the vertical range of the rect by a non-empty amount
// We now judge the crossings solely based on the line segment
// connecting the endpoints of the cubic.
// Note that we may have 0, 1, or 2 crossings as the control
// points may be causing the Y range intersection while the
// two endpoints are entirely above or below.
// y-increasing line segment...
// y-decreasing line segment...
}
return crossings;
}
// The intersection of ranges is more complicated
// First do trivial INTERSECTS rejection of the cases
// where one of the endpoints is inside the rectangle.
{
return RECT_INTERSECTS;
}
// Otherwise, subdivide and look for one of the cases above.
// double precision only has 52 bits of mantissa
if (level > 52) {
return rectCrossingsForLine(crossings,
}
// [xy]mid are NaN if any of [xy]c0m or [xy]mc1 are NaN
// [xy]c0m or [xy]mc1 are NaN if any of [xy][c][01] are NaN
// These values are also NaN if opposing infinities are added
return 0;
}
if (crossings != RECT_INTERSECTS) {
}
return crossings;
}
}
public final int getDirection() {
return direction;
}
}
public static double round(double v) {
//return Math.rint(v*10)/10;
return v;
}
return -1;
}
return 1;
}
return 0;
}
}
}
public static double prev(double v) {
}
public static double next(double v) {
}
return ("Curve["+
getOrder()+", "+
"]");
}
return "";
}
public abstract int getOrder();
public abstract double getXTop();
public abstract double getYTop();
public abstract double getXBot();
public abstract double getYBot();
public abstract double getXMin();
public abstract double getXMax();
public abstract double getX0();
public abstract double getY0();
public abstract double getX1();
public abstract double getY1();
public abstract double XforY(double y);
public abstract double TforY(double y);
public abstract double XforT(double t);
public abstract double YforT(double t);
public int crossingsFor(double x, double y) {
return 1;
}
}
return 0;
}
return false;
}
return false;
}
} else {
return false;
}
tstart = 0;
}
} else {
tend = 1;
}
boolean hitLo = false;
boolean hitHi = false;
while (true) {
if (x < xhi) {
return true;
}
hitLo = true;
} else {
if (hitLo) {
return true;
}
hitHi = true;
}
break;
}
}
if (hitLo) {
}
return false;
}
}
/*
System.out.println(this+".compareTo("+that+")");
System.out.println("target range = "+yrange[0]+"=>"+yrange[1]);
*/
}
return 0;
}
return -1;
}
return 1;
}
// Parameter s for thi(s) curve and t for tha(t) curve
// [st]0 = parameters for top of current section of interest
// [st]1 = parameters for bottom of valid range
// [st]h = parameters for hypothesis point
// [d][xy]s = valuations of thi(s) curve at sh
// [d][xy]t = valuations of tha(t) curve at th
}
//System.out.println("s1 problem!");
}
}
//System.out.println("t1 problem!");
}
while (y <= y1) {
}
} else {
y -= bump;
while (true) {
bump /= 2;
if (newy <= y) {
break;
}
y = newy;
}
}
break;
}
y += bump;
}
if (y > y0) {
if (y < y1) {
yrange[1] = y;
}
return 0;
}
}
//double ymin = y1 * 1E-14;
if (ymin <= 0) {
}
/*
System.out.println("s range = "+s0+" to "+s1);
System.out.println("t range = "+t0+" to "+t1);
*/
/*
System.out.println("sh = "+sh);
System.out.println("th = "+th);
*/
try {
break;
}
} catch (Throwable t) {
return 0;
}
}
break;
}
} else {
}
break;
}
}
}
/*
System.out.println("final this["+s0+", "+sh+", "+s1+"]");
System.out.println("final y["+ys0+", "+ysh+"]");
System.out.println("final that["+t0+", "+th+", "+t1+"]");
System.out.println("final y["+yt0+", "+yth+"]");
System.out.println("final order = "+orderof(this.XforY(ymid),
that.XforY(ymid)));
System.out.println("final range = "+yrange[0]+"=>"+yrange[1]);
*/
/*
System.out.println("final sx = "+this.XforY(ymid));
System.out.println("final tx = "+that.XforY(ymid));
System.out.println("final order = "+orderof(this.XforY(ymid),
that.XforY(ymid)));
*/
}
{
/*
String pad = " ";
pad = pad+pad+pad+pad+pad;
pad = pad+pad;
System.out.println("----------------------------------------------");
System.out.println(pad.substring(0, slevel)+ys0);
System.out.println(pad.substring(0, slevel)+ys1);
System.out.println(pad.substring(0, slevel)+(s1-s0));
System.out.println("-------");
System.out.println(pad.substring(0, tlevel)+yt0);
System.out.println(pad.substring(0, tlevel)+yt1);
System.out.println(pad.substring(0, tlevel)+(t1-t0));
*/
return false;
}
{
return false;
}
// Bounding boxes intersect - back off the larger of
// the two subcurves by half until they stop intersecting
// (or until they get small enough to switch to a more
// intensive algorithm).
throw new InternalError("no s progress!");
}
throw new InternalError("no t progress!");
}
return true;
}
}
return true;
}
}
return true;
}
}
return true;
}
}
} else {
return true;
}
}
return true;
}
}
}
throw new InternalError("no t progress!");
}
return true;
}
}
return true;
}
}
} else {
// No more subdivisions
if (det != 0) {
if (s >= 0 && s <= 1 && t >= 0 && t <= 1) {
if (s < 0 || s > 1 || t < 0 || t > 1) {
}
yrange[1] = y;
return true;
}
}
}
//System.out.println("Testing lines!");
}
return false;
}
double t1 = 1;
while (true) {
return t1;
}
if (y < y0) {
yt0 = y;
} else if (y > y0) {
} else {
return t1;
}
}
}
}
}