0N/A/*
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 *
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 *
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 *
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.
0N/A *
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
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.awt.geom;
0N/A
0N/Aimport java.awt.geom.Rectangle2D;
0N/Aimport java.awt.geom.PathIterator;
0N/Aimport java.util.Vector;
0N/A
0N/Afinal class Order1 extends Curve {
0N/A private double x0;
0N/A private double y0;
0N/A private double x1;
0N/A private double y1;
0N/A private double xmin;
0N/A private double xmax;
0N/A
0N/A public Order1(double x0, double y0,
0N/A double x1, double y1,
0N/A int direction)
0N/A {
0N/A super(direction);
0N/A this.x0 = x0;
0N/A this.y0 = y0;
0N/A this.x1 = x1;
0N/A this.y1 = y1;
0N/A if (x0 < x1) {
0N/A this.xmin = x0;
0N/A this.xmax = x1;
0N/A } else {
0N/A this.xmin = x1;
0N/A this.xmax = x0;
0N/A }
0N/A }
0N/A
0N/A public int getOrder() {
0N/A return 1;
0N/A }
0N/A
0N/A public double getXTop() {
0N/A return x0;
0N/A }
0N/A
0N/A public double getYTop() {
0N/A return y0;
0N/A }
0N/A
0N/A public double getXBot() {
0N/A return x1;
0N/A }
0N/A
0N/A public double getYBot() {
0N/A return y1;
0N/A }
0N/A
0N/A public double getXMin() {
0N/A return xmin;
0N/A }
0N/A
0N/A public double getXMax() {
0N/A return xmax;
0N/A }
0N/A
0N/A public double getX0() {
0N/A return (direction == INCREASING) ? x0 : x1;
0N/A }
0N/A
0N/A public double getY0() {
0N/A return (direction == INCREASING) ? y0 : y1;
0N/A }
0N/A
0N/A public double getX1() {
0N/A return (direction == DECREASING) ? x0 : x1;
0N/A }
0N/A
0N/A public double getY1() {
0N/A return (direction == DECREASING) ? y0 : y1;
0N/A }
0N/A
0N/A public double XforY(double y) {
0N/A if (x0 == x1 || y <= y0) {
0N/A return x0;
0N/A }
0N/A if (y >= y1) {
0N/A return x1;
0N/A }
0N/A // assert(y0 != y1); /* No horizontal lines... */
0N/A return (x0 + (y - y0) * (x1 - x0) / (y1 - y0));
0N/A }
0N/A
0N/A public double TforY(double y) {
0N/A if (y <= y0) {
0N/A return 0;
0N/A }
0N/A if (y >= y1) {
0N/A return 1;
0N/A }
0N/A return (y - y0) / (y1 - y0);
0N/A }
0N/A
0N/A public double XforT(double t) {
0N/A return x0 + t * (x1 - x0);
0N/A }
0N/A
0N/A public double YforT(double t) {
0N/A return y0 + t * (y1 - y0);
0N/A }
0N/A
0N/A public double dXforT(double t, int deriv) {
0N/A switch (deriv) {
0N/A case 0:
0N/A return x0 + t * (x1 - x0);
0N/A case 1:
0N/A return (x1 - x0);
0N/A default:
0N/A return 0;
0N/A }
0N/A }
0N/A
0N/A public double dYforT(double t, int deriv) {
0N/A switch (deriv) {
0N/A case 0:
0N/A return y0 + t * (y1 - y0);
0N/A case 1:
0N/A return (y1 - y0);
0N/A default:
0N/A return 0;
0N/A }
0N/A }
0N/A
0N/A public double nextVertical(double t0, double t1) {
0N/A return t1;
0N/A }
0N/A
0N/A public boolean accumulateCrossings(Crossings c) {
0N/A double xlo = c.getXLo();
0N/A double ylo = c.getYLo();
0N/A double xhi = c.getXHi();
0N/A double yhi = c.getYHi();
0N/A if (xmin >= xhi) {
0N/A return false;
0N/A }
0N/A double xstart, ystart, xend, yend;
0N/A if (y0 < ylo) {
0N/A if (y1 <= ylo) {
0N/A return false;
0N/A }
0N/A ystart = ylo;
0N/A xstart = XforY(ylo);
0N/A } else {
0N/A if (y0 >= yhi) {
0N/A return false;
0N/A }
0N/A ystart = y0;
0N/A xstart = x0;
0N/A }
0N/A if (y1 > yhi) {
0N/A yend = yhi;
0N/A xend = XforY(yhi);
0N/A } else {
0N/A yend = y1;
0N/A xend = x1;
0N/A }
0N/A if (xstart >= xhi && xend >= xhi) {
0N/A return false;
0N/A }
0N/A if (xstart > xlo || xend > xlo) {
0N/A return true;
0N/A }
0N/A c.record(ystart, yend, direction);
0N/A return false;
0N/A }
0N/A
0N/A public void enlarge(Rectangle2D r) {
0N/A r.add(x0, y0);
0N/A r.add(x1, y1);
0N/A }
0N/A
0N/A public Curve getSubCurve(double ystart, double yend, int dir) {
0N/A if (ystart == y0 && yend == y1) {
0N/A return getWithDirection(dir);
0N/A }
0N/A if (x0 == x1) {
0N/A return new Order1(x0, ystart, x1, yend, dir);
0N/A }
0N/A double num = x0 - x1;
0N/A double denom = y0 - y1;
0N/A double xstart = (x0 + (ystart - y0) * num / denom);
0N/A double xend = (x0 + (yend - y0) * num / denom);
0N/A return new Order1(xstart, ystart, xend, yend, dir);
0N/A }
0N/A
0N/A public Curve getReversedCurve() {
0N/A return new Order1(x0, y0, x1, y1, -direction);
0N/A }
0N/A
0N/A public int compareTo(Curve other, double yrange[]) {
0N/A if (!(other instanceof Order1)) {
0N/A return super.compareTo(other, yrange);
0N/A }
0N/A Order1 c1 = (Order1) other;
0N/A if (yrange[1] <= yrange[0]) {
0N/A throw new InternalError("yrange already screwed up...");
0N/A }
0N/A yrange[1] = Math.min(Math.min(yrange[1], y1), c1.y1);
0N/A if (yrange[1] <= yrange[0]) {
0N/A throw new InternalError("backstepping from "+yrange[0]+" to "+yrange[1]);
0N/A }
0N/A if (xmax <= c1.xmin) {
0N/A return (xmin == c1.xmax) ? 0 : -1;
0N/A }
0N/A if (xmin >= c1.xmax) {
0N/A return 1;
0N/A }
0N/A /*
0N/A * If "this" is curve A and "other" is curve B, then...
0N/A * xA(y) = x0A + (y - y0A) (x1A - x0A) / (y1A - y0A)
0N/A * xB(y) = x0B + (y - y0B) (x1B - x0B) / (y1B - y0B)
0N/A * xA(y) == xB(y)
0N/A * x0A + (y - y0A) (x1A - x0A) / (y1A - y0A)
0N/A * == x0B + (y - y0B) (x1B - x0B) / (y1B - y0B)
0N/A * 0 == x0A (y1A - y0A) (y1B - y0B) + (y - y0A) (x1A - x0A) (y1B - y0B)
0N/A * - x0B (y1A - y0A) (y1B - y0B) - (y - y0B) (x1B - x0B) (y1A - y0A)
0N/A * 0 == (x0A - x0B) (y1A - y0A) (y1B - y0B)
0N/A * + (y - y0A) (x1A - x0A) (y1B - y0B)
0N/A * - (y - y0B) (x1B - x0B) (y1A - y0A)
0N/A * If (dxA == x1A - x0A), etc...
0N/A * 0 == (x0A - x0B) * dyA * dyB
0N/A * + (y - y0A) * dxA * dyB
0N/A * - (y - y0B) * dxB * dyA
0N/A * 0 == (x0A - x0B) * dyA * dyB
0N/A * + y * dxA * dyB - y0A * dxA * dyB
0N/A * - y * dxB * dyA + y0B * dxB * dyA
0N/A * 0 == (x0A - x0B) * dyA * dyB
0N/A * + y * dxA * dyB - y * dxB * dyA
0N/A * - y0A * dxA * dyB + y0B * dxB * dyA
0N/A * 0 == (x0A - x0B) * dyA * dyB
0N/A * + y * (dxA * dyB - dxB * dyA)
0N/A * - y0A * dxA * dyB + y0B * dxB * dyA
0N/A * y == ((x0A - x0B) * dyA * dyB
0N/A * - y0A * dxA * dyB + y0B * dxB * dyA)
0N/A * / (-(dxA * dyB - dxB * dyA))
0N/A * y == ((x0A - x0B) * dyA * dyB
0N/A * - y0A * dxA * dyB + y0B * dxB * dyA)
0N/A * / (dxB * dyA - dxA * dyB)
0N/A */
0N/A double dxa = x1 - x0;
0N/A double dya = y1 - y0;
0N/A double dxb = c1.x1 - c1.x0;
0N/A double dyb = c1.y1 - c1.y0;
0N/A double denom = dxb * dya - dxa * dyb;
0N/A double y;
0N/A if (denom != 0) {
0N/A double num = ((x0 - c1.x0) * dya * dyb
0N/A - y0 * dxa * dyb
0N/A + c1.y0 * dxb * dya);
0N/A y = num / denom;
0N/A if (y <= yrange[0]) {
0N/A // intersection is above us
0N/A // Use bottom-most common y for comparison
0N/A y = Math.min(y1, c1.y1);
0N/A } else {
0N/A // intersection is below the top of our range
0N/A if (y < yrange[1]) {
0N/A // If intersection is in our range, adjust valid range
0N/A yrange[1] = y;
0N/A }
0N/A // Use top-most common y for comparison
0N/A y = Math.max(y0, c1.y0);
0N/A }
0N/A } else {
0N/A // lines are parallel, choose any common y for comparison
0N/A // Note - prefer an endpoint for speed of calculating the X
0N/A // (see shortcuts in Order1.XforY())
0N/A y = Math.max(y0, c1.y0);
0N/A }
0N/A return orderof(XforY(y), c1.XforY(y));
0N/A }
0N/A
0N/A public int getSegment(double coords[]) {
0N/A if (direction == INCREASING) {
0N/A coords[0] = x1;
0N/A coords[1] = y1;
0N/A } else {
0N/A coords[0] = x0;
0N/A coords[1] = y0;
0N/A }
0N/A return PathIterator.SEG_LINETO;
0N/A }
0N/A}