|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.awt.geom; |
|
|
|
import java.awt.geom.Rectangle2D; |
|
import java.awt.geom.PathIterator; |
|
import java.util.Vector; |
|
|
|
final class Order1 extends Curve { |
|
private double x0; |
|
private double y0; |
|
private double x1; |
|
private double y1; |
|
private double xmin; |
|
private double xmax; |
|
|
|
public Order1(double x0, double y0, |
|
double x1, double y1, |
|
int direction) |
|
{ |
|
super(direction); |
|
this.x0 = x0; |
|
this.y0 = y0; |
|
this.x1 = x1; |
|
this.y1 = y1; |
|
if (x0 < x1) { |
|
this.xmin = x0; |
|
this.xmax = x1; |
|
} else { |
|
this.xmin = x1; |
|
this.xmax = x0; |
|
} |
|
} |
|
|
|
public int getOrder() { |
|
return 1; |
|
} |
|
|
|
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() { |
|
return (direction == INCREASING) ? x0 : x1; |
|
} |
|
|
|
public double getY0() { |
|
return (direction == INCREASING) ? y0 : y1; |
|
} |
|
|
|
public double getX1() { |
|
return (direction == DECREASING) ? x0 : x1; |
|
} |
|
|
|
public double getY1() { |
|
return (direction == DECREASING) ? y0 : y1; |
|
} |
|
|
|
public double XforY(double y) { |
|
if (x0 == x1 || y <= y0) { |
|
return x0; |
|
} |
|
if (y >= y1) { |
|
return x1; |
|
} |
|
|
|
return (x0 + (y - y0) * (x1 - x0) / (y1 - y0)); |
|
} |
|
|
|
public double TforY(double y) { |
|
if (y <= y0) { |
|
return 0; |
|
} |
|
if (y >= y1) { |
|
return 1; |
|
} |
|
return (y - y0) / (y1 - y0); |
|
} |
|
|
|
public double XforT(double t) { |
|
return x0 + t * (x1 - x0); |
|
} |
|
|
|
public double YforT(double t) { |
|
return y0 + t * (y1 - y0); |
|
} |
|
|
|
public double dXforT(double t, int deriv) { |
|
switch (deriv) { |
|
case 0: |
|
return x0 + t * (x1 - x0); |
|
case 1: |
|
return (x1 - x0); |
|
default: |
|
return 0; |
|
} |
|
} |
|
|
|
public double dYforT(double t, int deriv) { |
|
switch (deriv) { |
|
case 0: |
|
return y0 + t * (y1 - y0); |
|
case 1: |
|
return (y1 - y0); |
|
default: |
|
return 0; |
|
} |
|
} |
|
|
|
public double nextVertical(double t0, double t1) { |
|
return t1; |
|
} |
|
|
|
public boolean accumulateCrossings(Crossings c) { |
|
double xlo = c.getXLo(); |
|
double ylo = c.getYLo(); |
|
double xhi = c.getXHi(); |
|
double yhi = c.getYHi(); |
|
if (xmin >= xhi) { |
|
return false; |
|
} |
|
double xstart, ystart, xend, yend; |
|
if (y0 < ylo) { |
|
if (y1 <= ylo) { |
|
return false; |
|
} |
|
ystart = ylo; |
|
xstart = XforY(ylo); |
|
} else { |
|
if (y0 >= yhi) { |
|
return false; |
|
} |
|
ystart = y0; |
|
xstart = x0; |
|
} |
|
if (y1 > yhi) { |
|
yend = yhi; |
|
xend = XforY(yhi); |
|
} else { |
|
yend = y1; |
|
xend = x1; |
|
} |
|
if (xstart >= xhi && xend >= xhi) { |
|
return false; |
|
} |
|
if (xstart > xlo || xend > xlo) { |
|
return true; |
|
} |
|
c.record(ystart, yend, direction); |
|
return false; |
|
} |
|
|
|
public void enlarge(Rectangle2D r) { |
|
r.add(x0, y0); |
|
r.add(x1, y1); |
|
} |
|
|
|
public Curve getSubCurve(double ystart, double yend, int dir) { |
|
if (ystart == y0 && yend == y1) { |
|
return getWithDirection(dir); |
|
} |
|
if (x0 == x1) { |
|
return new Order1(x0, ystart, x1, yend, dir); |
|
} |
|
double num = x0 - x1; |
|
double denom = y0 - y1; |
|
double xstart = (x0 + (ystart - y0) * num / denom); |
|
double xend = (x0 + (yend - y0) * num / denom); |
|
return new Order1(xstart, ystart, xend, yend, dir); |
|
} |
|
|
|
public Curve getReversedCurve() { |
|
return new Order1(x0, y0, x1, y1, -direction); |
|
} |
|
|
|
public int compareTo(Curve other, double yrange[]) { |
|
if (!(other instanceof Order1)) { |
|
return super.compareTo(other, yrange); |
|
} |
|
Order1 c1 = (Order1) other; |
|
if (yrange[1] <= yrange[0]) { |
|
throw new InternalError("yrange already screwed up..."); |
|
} |
|
yrange[1] = Math.min(Math.min(yrange[1], y1), c1.y1); |
|
if (yrange[1] <= yrange[0]) { |
|
throw new InternalError("backstepping from "+yrange[0]+" to "+yrange[1]); |
|
} |
|
if (xmax <= c1.xmin) { |
|
return (xmin == c1.xmax) ? 0 : -1; |
|
} |
|
if (xmin >= c1.xmax) { |
|
return 1; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
double dxa = x1 - x0; |
|
double dya = y1 - y0; |
|
double dxb = c1.x1 - c1.x0; |
|
double dyb = c1.y1 - c1.y0; |
|
double denom = dxb * dya - dxa * dyb; |
|
double y; |
|
if (denom != 0) { |
|
double num = ((x0 - c1.x0) * dya * dyb |
|
- y0 * dxa * dyb |
|
+ c1.y0 * dxb * dya); |
|
y = num / denom; |
|
if (y <= yrange[0]) { |
|
// intersection is above us |
|
|
|
y = Math.min(y1, c1.y1); |
|
} else { |
|
|
|
if (y < yrange[1]) { |
|
|
|
yrange[1] = y; |
|
} |
|
|
|
y = Math.max(y0, c1.y0); |
|
} |
|
} else { |
|
// lines are parallel, choose any common y for comparison |
|
// Note - prefer an endpoint for speed of calculating the X |
|
|
|
y = Math.max(y0, c1.y0); |
|
} |
|
return orderof(XforY(y), c1.XforY(y)); |
|
} |
|
|
|
public int getSegment(double coords[]) { |
|
if (direction == INCREASING) { |
|
coords[0] = x1; |
|
coords[1] = y1; |
|
} else { |
|
coords[0] = x0; |
|
coords[1] = y0; |
|
} |
|
return PathIterator.SEG_LINETO; |
|
} |
|
} |